Android 테마 전환 (theme), 언어 전환, 사용자 정의 속성 (attr) 값 동적 가져오기
37445 단어 안드로이드 베이스
<?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.theme
interface ThemeChangeObserver {
/**
*
*/
fun loadingCurrentTheme()
/**
*
*/
fun notifyThemeChanged()
}
4.BaseActivity에서 인터페이스 구현
package com.zjhj.maxapp.base
import android.content.Context
import android.os.Bundle
import android.view.WindowManager
import androidx.appcompat.app.AppCompatActivity
import com.zjhj.maxapp.App
import com.zjhj.maxapp.R
import com.zjhj.maxapp.theme.ThemeChangeObserver
import com.zjhj.maxapp.utils.L //
/**
* CreateTime 2020/4/2 09:10
* Author LiuShiHua
* Description:
*/
abstract class BaseActivity : AppCompatActivity(), ThemeChangeObserver {
private val KEY_THEME_TAG = "myThemeTag"
private var isChangeTheme: Boolean = false
override 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)
edit.commit()
App.notifyByThemeChanged()
}
/**
*
*/
override fun onDestroy() {
App.unregisterObserver(this)
super.onDestroy()
}
}
5. APP에서 관찰자 관리
package com.zjhj.maxapp
import android.app.Application
import android.content.Context
import com.zjhj.maxapp.theme.ThemeChangeObserver
/**
* CreateTime 2020/4/9 09:40
* Author LiuShiHua
* Description:
*/
class App : Application() {
companion object {//
lateinit var context: Context
get
private 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)) return
obtainThemeChangeObserverStack()!!.add(observer)
}
/**
* observer
*/
fun unregisterObserver(observer: ThemeChangeObserver?) {
if (observer == null || !obtainThemeChangeObserverStack()!!.contains(observer)) return
obtainThemeChangeObserverStack()!!.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.maxapp
import com.zjhj.maxapp.base.BaseActivity
import 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에서 notify ThemeChanged에서 해당 주제의 속성 값을 다시 설정합니다[느낌 비교 low]
...
override fun notifyThemeChanged() {
val typedValue = TypedValue()
// titlebar_bg , typedValue
theme.resolveAttribute(R.attr.titlebar_bg, typedValue, true)
// 【 : , 】
toolBar.setBackgroundColor(typedValue.data)
}
...
실현 효과: 테마 설정도 테마를 바꾼 후 다른 페이지와 이 변화
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Dialog 팝업 상자(보통 가운데에서 팝업 및 아래쪽 애니메이션에서 팝업)텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.