目录
- android四种方式刷新View
- 1.前言:
- 2.View.VISIBLE与View.GONE的基本概念:
- 3.使用GONE导致的问题:
- 4.主界面布局:
- 5.解决方式1:
- 4.1 使用协程刷新view
- 4.2 使用view.post刷新
- 4.3 使用handler.post刷新
- 4.4 使用view.viewTreeObserver刷新
- 4.5 使用view.doOnLayout刷新
- 6.遇到问题:
- 7.编程客栈效果截图:
- 8.完整测试代码:
- 9.总结:
- 10.项目源码:
Android四种方式刷新View
1.前言:
最近在切换主题时有个TextView是Gone的状态,切换主题后内容没有显示,于是排查代码,刚开始以为是textView没有设置内容,但是打印日志和排查发现有setText.
2.View.VISIBLE与View.GONE的基本概念:
在Android中,视图的可见性状态主要有三种:
View.VISIBLE:视图可见,默认状态。
View.INVISIBLE:视图不可见,但仍占据布局空间。View.GONE:视图不可见,并且不再占据任何空间。3.使用GONE导致的问题:
- 布局性能下降:在复杂的布局中,频繁地更改视图状态为GONE可能会导致性能问题。这是因为Android在处理布局时需要重新计算可见视图的排列。
- UI体验不佳:频繁切换视图的可见性可能会导致用户体验下降。例如,用户在点击按钮时,如果需要等待布局重新排列,用户可能会感觉卡顿。
- 数据绑定问题:对数据绑定的视图进行GONE操作可能会使得数据变更不再更新。例如,通过LiveData绑定的视图,如果处于GONE状态,它的更新可能不会体现在界面上。
- 事件监听问题:将一个视图设置为GONE会使得它的事件监听器失效,这在某些情况下可能会导致功能缺失
4.主界面布局:
<?XML version="1.0" encoding="utf-8"?> <LinearLayout 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:id="@+id/main" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_gravity="center" android:gravity="center" tools:context=".MainActivity"> <TextView android:id="@+id/textview" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginStart="4piqPKYINH0dp" android:layout_marginEnd="40dp" android:background="@color/design_default_color_primary_dark" android:gravity="center" android:text="这是一个textview" android:textColor="@color/white" android:textSize="18sp" android:visibility="visible" tools:text="这是一个textview" /> </LinearLayout>
5.解决方式1:
4.1 使用协程刷新view
private fun initView() { //使用协程方式刷新 uiScope.launch { binding.textview.text = "这是view使用协程刷新" } }
4.2 使用view.post刷新
private fun initView() { //使用view.post刷新 binding.textview.post { binding.textview.text = "这是view使用post刷新" Log.d(TAG,"view的内容${binding.textview.text} ${binding.textview.visibility}javascript") } }
4.3 使用handler.post刷新
4.4 使用view.viewTreeObserver刷新
private fun initView() { //使用view.viewTreeObserver刷新 binding.textview.viewTreeObserver.addOnGlobalLayoutListener { binding.textview.text = "这是view使用viewTreeObserver刷新" } }
4.5 使用view.doOnLayout刷新
binding.textview.doOnLayout { // 当布局确定后执行的代码 binding.textview.text = "这是view使用doOnLayout刷新" }
6.遇到问题:
- 由于项目中是切换主题,view是Gone的状态,所以第5种方式是不生效的,这里不推荐使用,
- 方式2和3这里因为view是隐藏状态,所以在post刷新时会闪烁一下,为了解决此需要重新绘制布局,调用view.requestLayout()或view.invalidate()都可以
- 方式4因为项目中的设备是34的,所以不需要主动移除监听,在低版本是需要做移除操作
7.效果截图:
8.完整测试代码:
package com.cloud.viewpostdemo import android.animation.ObjectAnimator import and编程客栈roid.os.Bundle import android.os.Handler import android.os.Looper import android.util.Log import android.view.View import android.widget.LinearLayout import androidx.appcompat.app.AppCompatActivity import androidx.core.view.doOnLayout import com.cloud.viewpostdemo.databinding.ActivityMainBinding import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.launch class MainActivity : AppCompatActivity() { private val mainJob = SupervisorJob() private val uiScope = CoroutineScope(Dispatchers.Main + mainJob) private lateinit var binding: ActivityMainBinding private val TAG by lazy { "${JavaClass.simpleName}@${System.identityHashCode(this)}" } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = ActivityMainBinding.inflate(layoutInflater) setContentView(binding.root) initView() } private fun initView() { //使用协程方式刷新 uiScope.launch { binding.textview.text = "这是view使用协程刷新" } binding.textview.visibility = View.GONE //使用view.post刷新 binding.textview.post { binding.textview.text = "这是view使用post刷新" Log.d(TAG,"view的内容${binding.textview.text} ${binding.textview.visibility}") } //使用handler.post刷新 val handler = Handler(Looper.getMainLooper()) handler.post { binding.textview.text = "这是view使用handler刷新" } //使用view.viewTreeObserver刷新 www.devze.com binding.textview.viewTreeObserver.addOnGlobalLayoutListener { binding.textview.text = "这是view使用viewTreeObserver刷新" } binding.textview.doOnLayout { // 当布局确定后执行的代码 binding.textview.text = "这是view使用doOnLayout刷新" } } }
9.总结:
今天的使用场景很特殊,一般不会遇到,不过既然遇到了,就要找到问题原因解决掉问题,当然解决方式有很多,这里看个人,没有说一定要使用哪种方式,由于是demo所以没有做主题切换的操作,view也是直接显示的,感兴趣的同学可以自己尝试一下再view隐藏时切换主题会不会有此问题,打卡收工,祝大家新年快乐.
10.项目源码:
https://gitee.com/jackning_admin/view-post-demo
到此这篇关于Android四种方式刷新View的文章就介绍到这了,更多相关Android 刷新View内容请搜索编程客栈(www.devze.com)以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程客栈(www.devze.com)!
精彩评论