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

相关推荐
paid槮2 小时前
MySql基础:数据类型
android·mysql·adb
用户2018792831673 小时前
AMS和app通信的小秘密
android
用户2018792831673 小时前
ThreadPoolExecutor之市场雇工的故事
android
诺诺Okami3 小时前
Android Framework-Launcher-InvariantDeviceProfile
android
Antonio9154 小时前
【音视频】Android NDK 与.so库适配
android·音视频
sun00770013 小时前
android ndk编译valgrind
android
AI视觉网奇14 小时前
android studio 断点无效
android·ide·android studio
jiaxi的天空14 小时前
android studio gradle 访问不了
android·ide·android studio
No Silver Bullet15 小时前
android组包时会把从maven私服获取的包下载到本地吗
android
catchadmin15 小时前
PHP serialize 序列化完全指南
android·开发语言·php