Android setTheme设置透明主题无效

【问题现象】

1、首先,你在AndroidManifest.xml中声明一个activity,不给application或者activity设置android:theme, 例如这样:

html 复制代码
  <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true">
        <activity android:name=".MainActivity" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

或者是给application或者activity设置一个非透明的主题,例如这样:

html 复制代码
<application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@android:style/Theme.Light.NoTitleBar.Fullscreen">
        <activity android:name=".MainActivity" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

2、接着,你企图在代码中动态设置该activity的主题为透明主题,例如这样:

cpp 复制代码
  @Override
    protected void onCreate(Bundle savedInstanceState) {
        setTheme(android.R.style.Theme_Translucent_NoTitleBar_Fullscreen);
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        TextView tv = findViewById(R.id.sample_text);
        tv.setText(stringFromJNI());
    }

那么,我们来看看运行效果:

很明显,背景并没有变透明,依然是黑色背景,所以在super.onCreate(savedInstanceState)前设置透明背景也是无效的

3、然后,有人说,你设置的位置不对吖,setTheme这句代码应该放在super.onCreate(savedInstanceState)之后,setContentView之前设置才有效果,那么,我们来试试:

cpp 复制代码
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setTheme(android.R.style.Theme_Translucent_NoTitleBar_Fullscreen);
        setContentView(R.layout.activity_main);
        TextView tv = findViewById(R.id.sample_text);
        tv.setText(stringFromJNI());
    }

看看出来的效果:

很明显,依然还是没有变成透明主题效果

4、那么,我们再试试重写getTheme来返回透明的主题样式,看看是否有效果

cpp 复制代码
 @Override
    public Resources.Theme getTheme() {
        Resources.Theme theme = super.getTheme();
        theme.applyStyle(android.R.style.Theme_Translucent_NoTitleBar_Fullscreen, true);
        return theme;
    }

结果还是跟上面一样,背景依然不是透明

【问题分析】

在上面,我们尝试各种操作(其实这些操作都是百度搜索到网上说的做法),都没法在代码里面动态将activity的主题样式设置为透明,那么问题点出在哪里了呢?后来决定Google搜索一下,发现有个英文博客提到一个关键点:

这个英文博客提到要是设置的是非透明主题样式的话,直接用setTheme设置是可以动态设置的,但是假如你想要通过setTheme设置透明主题样式的话,android系统似乎自动忽略了你透明主题中的windowIsTranslucent=true这个标志,依然还是显示非透明的主题样式

【问题解决】

我们看看那个英文博客说怎么解决这个问题呢?

1、首先,在AndroidManifest.xml中给activity随便设置一个透明的主题样式,比如: @android:style/Theme.Translucent,这样设置之后,你在代码里随便设置哪个透明主题都可以生效

2、然后博客提到不可以直接调用setTheme(R.style.MyOwnTranslucentTheme)来设置主题样式,因为这样会使得透明失效,而是通过调用getTheme().applyStyle(R.style.MyOwnTranslucentTheme, true)来设置自己想要的透明样式

其实,我测试直接调用setTheme就可以设置,你们可以试试

【尾声】

可能有人有疑问说,既然直接在AndroidManifest.xml设置透明主题样式是可以直接生效的,为何还要多此一举在代码通过setTheme来动态设置呢?其实,应用场景还是挺多的,比如:

1、本来你的activity是个非透明主题样式或者是个透明有标题的主题样式,然后在某个时间,你希望动态设置为透明无标题全屏主题样式,那么你就需要通过setTheme来动态设置

2、插件化加载插件的activity时候,占位activity就需要根据插件真实的主题样式设置,所以也是会需要用到setTheme去动态设置透明主题样式的需求

原文链接:https://blog.csdn.net/qq_43278826/article/details/107557784

相关推荐
zhangphil37 分钟前
Android ValueAnimator ImageView animate() rotation,Kotlin
android·kotlin
徊忆羽菲1 小时前
CentOS7使用源码安装PHP8教程整理
android
编程、小哥哥2 小时前
python操作mysql
android·python
Couvrir洪荒猛兽3 小时前
Android实训十 数据存储和访问
android
五味香5 小时前
Java学习,List 元素替换
android·java·开发语言·python·学习·golang·kotlin
十二测试录5 小时前
【自动化测试】—— Appium使用保姆教程
android·经验分享·测试工具·程序人生·adb·appium·自动化
Couvrir洪荒猛兽7 小时前
Android实训九 数据存储和访问
android
aloneboyooo7 小时前
Android Studio安装配置
android·ide·android studio
Jacob程序员8 小时前
leaflet绘制室内平面图
android·开发语言·javascript
2401_897907868 小时前
10天学会flutter DAY2 玩转dart 类
android·flutter