我正在编写一个应用程序,它具有光明和黑暗模式,声明在这里:
styles.xml
<style name="Noon" parent="Theme.AppCompat.NoActionBar">
<item name="upper_bg">@drawable/day_sky_top</item>
<item name="lower_bg">@drawable/day_sky</item>
<item name="android:statusBarColor">@color/colorPrimaryDark</item>
</style>
<style name="Night" parent="Theme.AppCompat.NoActionBar">
<item name="upper_bg">@drawable/night_sky_top</item>
<item name="lower_bg">@drawable/night_sky</item>
<item name="android:statusBarColor">@color/colorNightDark</item>
</style>
根据这个答案,我创建了以下文件:
/res/价值/attrs.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="customAttrs">
<attr name="upper_bg" format="reference" />
<attr name="lower_bg" format="reference" />
</declare-styleable>
</resources>
并像这样自定义我的ImageViews:
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ImageView
android:id="@+id/top_bg"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="0.65"
android:src="?attr/upper_bg"/>
<ImageView
android:id="@+id/bottom_bg"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="0.35"
android:src="?attr/lower_bg"/>
</LinearLayout>
(注意这是代码的一部分,所有标记都正确关闭)
只要我有:
boolean night = true;
setTheme(night ? R.style.Night : R.style.Noon);
setContentView(R.layout.activity_main); // or whatever activity I'm in.
在我的应用程序的每一个活动。是否有一种方法来运行这个代码一次,使我的主题改变全局?
您仍然可以添加BaseActivity
来覆盖override fun onCreate()
,将setTheme()
的责任委托给从它继承的任何其他Activity
。
override fun onCreate(savedInstanceState: Bundle?) {
val night = true
setTheme(if (night) R.style.Night else R.style.Noon)
}
如果你不喜欢BaseActivity
,你可以在某个地方创建一个扩展函数,负责根据用户偏好设置主题:
fun Activity.setTheme() {
val night = true
// Or even have more than two theme styles
this.setTheme(if (night) R.style.Night else R.style.Noon)
}
然后被这样调用:
override fun onCreate(savedInstanceState: Bundle?) {
setTheme()
}
UPDATE: Java code
这个类将是每个所需Activity
的基类
public abstract class BaseActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
boolean night = true;
setTheme(night ? R.style.Night : R.style.Noon);
}
}
现在,假设你要实现"特性1"one_answers"特性2",因此,您可以直接从BaseActivity
继承它们。
"功能1":
public class Feature1Activity extends BaseActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); // <- BaseActivity's onCreate() will set theme for you
setContentView(R.layout.activity_feature_1);
}
}
2">"特点:
public class Feature2Activity extends BaseActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); // <- BaseActivity's onCreate() will set theme for you
setContentView(R.layout.activity_feature_2);
}
}
你可以!你必须使用类AppCompatDelegate的setDefaultNightMode()方法,它接受你想应用的主题的值,可用的值是MODE_NIGHT_NO &MODE_NIGHT_YES,MODE_NIGHT_FOLLOW_SYSTEM分别设置为灯光、夜晚和手机默认主题,你可以这样做:
AppCompatDelegate.setDefaultNightMode(THE_MODE_YOU_WANT);
重要的是要注意,从AppCompat v1.0.0开始,当这个方法被调用时,它会重新创建所有正在运行的活动来应用主题。
如果你正在运行Api 29或更高版本,你应该考虑使用Force Dark,你可以在官方文档中查看它以更好地理解它。
享受吧!