700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > Android 主题切换(theme) 语种切换 动态获取自定义属性(attr)值

Android 主题切换(theme) 语种切换 动态获取自定义属性(attr)值

时间:2018-08-04 03:59:56

相关推荐

Android 主题切换(theme) 语种切换 动态获取自定义属性(attr)值

Google提供的更换主题包方法参考:

https://source./devices/architecture/rros?hl=zh-cn

/p/398f1beb1a6e

/dayong198866/article/details/106281654

主题语言切换

1.开发环境:Android studio 3.4.0,kotlin实现

2.开发准备

①在values中添加资源文件【“new“ → "Values resouce file”】定义为”custom_theme_attrs“,内容如下:

<?xml version="1.0" encoding="utf-8"?><resources><!-- 控制app背景色 format:颜色值、资源引用 --><attr name="custom_attr_app_bg" format="color|reference" /><!-- 控制app标题栏背景色 format:颜色值、资源引用 --><attr name="custom_attr_app_title_layout_bg" format="color|reference" /><!-- 用户头像显示占位Drawable format:颜色值、资源引用 --><attr name="custom_attr_user_photo_place_holder" format="color|reference" /><!-- 用户昵称字体颜色 format:颜色值、资源引用 --><attr name="custom_attr_nickname_text_color" format="color|reference" /><!-- 用户备注字体颜色 format:颜色值、资源引用 --><attr name="custom_attr_remark_text_color" format="color|reference" /><!-- 用户头像显示的透明度 format:尺寸值、资源引用 --><attr name="custom_attr_user_photo_alpha" format="dimension|reference" /><attr name="titlebar_bg" format="color|reference"/><attr name="titlebar_text_color" format="color|reference"/><attr name="body_bg" format="color|reference"/><attr name="body_text_color" format="color|reference"/><attr name="title" format="string"/></resources>

②在资源文件”styles“中添加如下代码【添加主题】

<!-- 主题:白天 --><style name="theme_day" parent="Theme.AppCompat.Light.NoActionBar"><item name="titlebar_bg">#1EABF0</item><item name="titlebar_text_color">#FFFFFF</item><item name="body_bg">#F3F3F3</item><item name="body_text_color">#333333</item></style><!-- 主题:夜晚 --><style name="theme_night" parent="Theme.AppCompat.Light.NoActionBar"><item name="titlebar_bg">#000000</item><item name="titlebar_text_color">#FFFFFF</item><item name="body_bg">#888888</item><item name="body_text_color">#EAEAEA</item></style><!-- theme_day.chi_sim 表示继承theme_day --><style name="theme_day.chi_sim"><item name="title">主题配置</item></style><style name="theme_night.eng"><item name="title">TopicConfig</item></style>

3.添加观察者接口:

package com.zjhj.maxapp.themeinterface ThemeChangeObserver {/*** 加载当前主题*/fun loadingCurrentTheme()/*** 主题改变后通知*/fun notifyThemeChanged()}

4.在BaseActivity中实现接口

package com.zjhj.maxapp.baseimport android.content.Contextimport android.os.Bundleimport android.view.WindowManagerimport androidx.appcompat.app.AppCompatActivityimport com.zjhj.maxapp.Appimport com.zjhj.maxapp.Rimport com.zjhj.maxapp.theme.ThemeChangeObserverimport com.zjhj.maxapp.utils.L //自定义日志类/*** CreateTime /4/2 09:10* Author LiuShiHua* Description:*/abstract class BaseActivity : AppCompatActivity(), ThemeChangeObserver {private val KEY_THEME_TAG = "myThemeTag"private var isChangeTheme: Boolean = falseoverride fun onCreate(savedInstanceState: Bundle?) {window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)window.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN)setThemeBeforeCreate()super.onCreate(savedInstanceState)setContentView()initView()initData()getData()}/***/private fun setThemeBeforeCreate() {App.registerObserver(this)//将当前Acitivity注册成观察者loadingCurrentTheme()}/*** 加载当前主题* 需要在super.onCreate(savedInstanceState)之前执行才会生效*/override fun loadingCurrentTheme() {when (getThemeTag()) {1 -> setTheme(R.style.theme_day_chi_sim)-1 -> setTheme(R.style.theme_night_eng)}L.d("loadingCurrentTheme:" + this::class.java)}abstract fun setContentView()abstract fun initView()abstract fun initData()abstract fun getData()/*** 获取当前主题类型*/protected open fun getThemeTag(): Int {val preferences = getSharedPreferences("MaxTheme", Context.MODE_PRIVATE)return preferences.getInt(KEY_THEME_TAG, 1)}/*** 设置主题类型* 保存在sharedprferences中*/protected open fun setThemeTag(tag: Int) {L.d("setThemeTag:" + tag)val preferences = getSharedPreferences("MaxTheme", Context.MODE_PRIVATE)val edit = preferences.edit()edit.putInt(KEY_THEME_TAG, tag)mit()App.notifyByThemeChanged()}/*** 注销这个观察者*/override fun onDestroy() {App.unregisterObserver(this)super.onDestroy()}}

5.在APP(继承 Application)中管理观察者

package com.zjhj.maxappimport android.app.Applicationimport android.content.Contextimport com.zjhj.maxapp.theme.ThemeChangeObserver/*** CreateTime /4/9 09:40* Author LiuShiHua* Description:*/class App : Application() {companion object {//静态属性或方法lateinit var context: Contextgetprivate var mThemeChangeObserverStack: MutableList<ThemeChangeObserver>? = null/*** 获得observer堆栈*/private fun obtainThemeChangeObserverStack(): MutableList<ThemeChangeObserver>? {if (mThemeChangeObserverStack == null) mThemeChangeObserverStack = ArrayList()return mThemeChangeObserverStack}/*** 向堆栈中添加observer*/fun registerObserver(observer: ThemeChangeObserver?) {if (observer == null || obtainThemeChangeObserverStack()!!.contains(observer)) returnobtainThemeChangeObserverStack()!!.add(observer)}/*** 从堆栈中移除observer*/fun unregisterObserver(observer: ThemeChangeObserver?) {if (observer == null || !obtainThemeChangeObserverStack()!!.contains(observer)) returnobtainThemeChangeObserverStack()!!.remove(observer)}/*** 向堆栈中所有对象发送更新UI的指令*/fun notifyByThemeChanged() {val observers: List<ThemeChangeObserver>? = obtainThemeChangeObserverStack()for (observer in observers!!) {observer.loadingCurrentTheme() //observer.notifyThemeChanged() //}}}override fun onCreate() {super.onCreate()context = this}}

5.在BaseActivity实例中去调用更换主题

package com.zjhj.maxappimport com.zjhj.maxapp.base.BaseActivityimport kotlinx.android.synthetic.main.activity_theme.*class ThemeActivity : BaseActivity() {override fun setContentView() {setContentView(R.layout.activity_theme)}override fun initView() {changeTheme.setOnClickListener {if (getThemeTag()==1) {//设置主题setThemeTag(-1)} else {setThemeTag(1)}recreate()//重新构建页面}}override fun initData() {}override fun getData() {}override fun notifyThemeChanged() {}}

6.说明:网上有些建议是使用recreate()来重新构建页面就行,实际中很多Activity都无法使用recreate()来重新构建页面,或者想保存之前的页面信息而不希望页面重新构建,我这里使用的是在Activity中notifyThemeChanged中重新设置对应主题的属性值【感觉比较low】

...override fun notifyThemeChanged() {val typedValue = TypedValue()//获取当前主题下的titlebar_bg属性值,并赋给typedValuetheme.resolveAttribute(R.attr.titlebar_bg, typedValue, true)//设置属性值【注意:属性是那种类型,设置的时候就用成那种类型】toolBar.setBackgroundColor(typedValue.data)}...

实现效果:在主题设置也改变主题后其他页面跟这变化

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。