当前位置:网站首页>Databinding+livedata can easily realize skin changing without restart
Databinding+livedata can easily realize skin changing without restart
2022-07-28 13:03:00 【Serbian uncle】
author :ezy
Recent projects need to use the dynamic skin changing function without restart , I was going to use github On star The most Android-skin-support
But a closer look shows that it's too complicated and 2 No maintenance in + A lot of issues It's not solved , Finally give up
After exploration , Find out Databinding+LiveData It can realize skin change without restart at low cost
- Dynamic skin changing without restart ( Unwanted recreate())
- No need to make a skin bag
- No extra dependence (Databinding+LiveData It is almost necessary to develop itself )
- Low invasive
- AppCompat and Material Default component support ( A small number of attributes require additional support or adaptation )
- Customize View/ The third party View The adaptation process is simple ( Just write a binding adapter )
- No need to use LayoutInflater.Factory
Define skin
The following code defines three skins Default,Day,Night, By calling AppTheme.update(theme) You can complete the dynamic skin change
The skin here only supports ColorStateList, Because most scenes just ColorStateList That's enough
If you want to ,Drawable/String And other resources can support
data class Theme(
val content: Int,
val background: Int,
)
object Themes {
val Default = Theme(Color.RED, Color.GRAY)
val Day = Theme(Color.BLACK, Color.WHITE)
val Night = Theme(Color.MAGENTA, Color.BLACK)
}
object AppTheme {
val background = MutableLiveData<ColorStateList>()
val content = MutableLiveData<ColorStateList>()
init {
update(Themes.Default)
}
fun update(theme: Theme) {
background.value = ColorStateList.valueOf(theme.background)
content.value = ColorStateList.valueOf(theme.content)
}
}
Use skins in layout files
Directly introducing AppTheme Single case ,livedata Will be associated with the lifecycle , Don't worry about resource release
<?xml version="1.0" encoding="utf-8"?>
<layout 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">
<data>
<import type="ezy.demo.theme.AppTheme" />
</data>
<FrameLayout android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity" android:background="#EEEEEE">
<LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" app:background="@{AppTheme.INSTANCE.background}" android:gravity="center" android:orientation="vertical">
<SeekBar android:layout_width="300dp" android:layout_height="wrap_content" android:max="100" android:progress="50" android:progressBackgroundTint="@{AppTheme.INSTANCE.background}" android:progressTint="@{AppTheme.INSTANCE.content}" android:thumb="@android:drawable/ic_btn_speak_now" android:thumbTint="@{AppTheme.INSTANCE.content}" />
<TextView android:layout_width="100dp" android:layout_height="100dp" android:layout_margin="10dp" android:gravity="center" android:text="Hello World!" android:textColor="@{AppTheme.INSTANCE.content}" app:drawableTint="@{AppTheme.INSTANCE.content}" app:drawableTopCompat="@android:drawable/ic_media_pause" />
<LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal">
<TextView android:id="@+id/btn_default" android:layout_width="100dp" android:layout_height="40dp" android:gravity="center" android:text="Default" android:textColor="@{AppTheme.INSTANCE.content}" />
<TextView android:id="@+id/btn_day" android:layout_width="100dp" android:layout_height="40dp" android:gravity="center" android:text="Day" android:textColor="@{AppTheme.INSTANCE.content}" />
<TextView android:id="@+id/btn_night" android:layout_width="100dp" android:layout_height="40dp" android:gravity="center" android:text="Night" android:textColor="@{AppTheme.INSTANCE.content}" />
</LinearLayout>
</LinearLayout>
</FrameLayout>
</layout>
Associated lifecycle
actually Databinding+ObserverableField It can also realize skin change without restart , but ObserverableField Cannot associate lifecycle , Resource release is more troublesome
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding = DataBindingUtil.setContentView<ActivityMainBinding>(this, R.layout.activity_main)
// Associated lifecycle
binding.lifecycleOwner = this
binding.btnDefault.setOnClickListener {
AppTheme.update(Themes.Default) }
binding.btnDay.setOnClickListener {
AppTheme.update(Themes.Day) }
binding.btnNight.setOnClickListener {
AppTheme.update(Themes.Night) }
}
}
Extend supported skin properties
DataBinding It already supports a large number of properties , Some are not supported , You have to implement it yourself
Actually, it's just writing Binder Adapter , It's almost the same to support third-party controls or custom controls , It's simple
Here are some examples
@SuppressLint("RestrictedApi")
@BindingMethods(
BindingMethod(type = ImageView::class, attribute = "tint", method = "setImageTintList")
)
object ThemeAdapter {
@BindingAdapter("background")
@JvmStatic
fun adaptBackground(view: View, value: ColorStateList?) {
view.setBackgroundColor(Color.WHITE)
view.backgroundTintList = value
}
@BindingAdapter("drawableTint")
@JvmStatic
fun adaptDrawableTint(view: TextView, value: ColorStateList?) {
if (view is AppCompatTextView) {
view.supportCompoundDrawablesTintList = value
}
}
@BindingAdapter("android:progressBackgroundTint")
@JvmStatic
fun adaptProgressBackgroundTint(view: SeekBar, value: ColorStateList?) {
view.progressBackgroundTintList = value
}
}
Demo
边栏推荐
- Jetpack Compose 完全脱离 View 系统了吗?
- Monotonic stack
- 【嵌入式C基础】第8篇:C语言数组讲解
- What if the win11 folder cannot be opened
- [basic teaching of Bi design] detailed explanation of OLED screen use - single chip microcomputer Internet of things
- Qt 信号和槽机制( 详解 )
- SQL most commonly used basic operation syntax
- 机器学习实战-逻辑回归-19
- Zurich Federal Institute of technology | reference based image super resolution with deformable attention transformer (eccv2022))
- How many times can the WordPress user name be changed? Attach the method of changing user name
猜你喜欢

How can non-standard automation equipment enterprises do well in product quality management with the help of ERP system?
![[embedded explanation] key scanning based on finite state machine and stm32](/img/ce/cc3f959a4e4f5b22e2c711ea887ad7.png)
[embedded explanation] key scanning based on finite state machine and stm32
![[graduation design] heart rate detection system based on single chip microcomputer - STM32 embedded Internet of things](/img/b4/06c822c52f5bb0045698b7107efb26.png)
[graduation design] heart rate detection system based on single chip microcomputer - STM32 embedded Internet of things
![[embedded C foundation] Part 1: basic data types](/img/45/b0bc9e90b0582f0f2624ce27b5a76c.png)
[embedded C foundation] Part 1: basic data types

大模型哪家强?OpenBMB发布BMList给你答案!

Sliding Window

Leetcode94. Middle order traversal of binary trees

LeetCode 42.接雨水

How to add PDF virtual printer in win11

What if the right button of win11 start menu doesn't respond
随机推荐
机器学习基础-决策树-12
Code layered management of interface testing based on RF framework
SQL most commonly used basic operation syntax
Machine learning practice - neural network-21
leetcode 376. Wiggle Subsequence
Jetpack Compose 完全脱离 View 系统了吗?
机器学习实战-神经网络-21
How can non-standard automation equipment enterprises do well in product quality management with the help of ERP system?
【C语言易错点】第4篇:结构体在内存中存储规则详讲
黑猫带你学eMMC协议第24篇:eMMC的总线测试程序详解(CMD19 & CMD14)
AI制药的数据之困,分子建模能解吗?
01 introduction to pyechars features, version and installation
Change the document type in endnode and import it in word
Low code: reduce technical capability requirements and improve software development efficiency
Leetcode 42. rainwater connection
Which big model is better? Openbmb releases bmlist to give you the answer!
Flexpro software: measurement data analysis in production, research and development
Leetcode daily question (2196. create binary tree from descriptions)
C# static的用法详解
Jetpack 全家桶之 LiveData 使用及源码篇