Android四种方式刷新View

Android四种方式刷新View

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.主界面布局:

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">

android:id="@+id/textview"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:layout_marginStart="40dp"

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" />

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}")

}

}

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 android.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刷新

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

相关内容

钢琴1级到10级各是什么水平?
下载旧版365彩票网软件

钢琴1级到10级各是什么水平?

📅 07-04 👁️ 701
淘宝云客服怎么做?淘宝云客服申请流程
365网站客服电话

淘宝云客服怎么做?淘宝云客服申请流程

📅 07-24 👁️ 9128
未来最赚钱的17大行业
365网站客服电话

未来最赚钱的17大行业

📅 08-17 👁️ 3658
C#/.NET/.NET Core学习路线集合,学习不迷路!
365bet足球比

C#/.NET/.NET Core学习路线集合,学习不迷路!

📅 08-16 👁️ 2120