Android四種方式刷新View的操作方法
Android四種方式刷新View
1.前言:
最近在切換主題時有個TextView是Gone的狀態(tài),切換主題后內(nèi)容沒有顯示,于是排查代碼,剛開始以為是textView沒有設(shè)置內(nèi)容,但是打印日志和排查發(fā)現(xiàn)有setText.
2.View.VISIBLE與View.GONE的基本概念:
在Android中,視圖的可見性狀態(tài)主要有三種:
View.VISIBLE:視圖可見,默認狀態(tài)。
View.INVISIBLE:視圖不可見,但仍占據(jù)布局空間。
View.GONE:視圖不可見,并且不再占據(jù)任何空間。
3.使用GONE導(dǎo)致的問題:
- 布局性能下降:在復(fù)雜的布局中,頻繁地更改視圖狀態(tài)為GONE可能會導(dǎo)致性能問題。這是因為Android在處理布局時需要重新計算可見視圖的排列。
- UI體驗不佳:頻繁切換視圖的可見性可能會導(dǎo)致用戶體驗下降。例如,用戶在點擊按鈕時,如果需要等待布局重新排列,用戶可能會感覺卡頓。
- 數(shù)據(jù)綁定問題:對數(shù)據(jù)綁定的視圖進行GONE操作可能會使得數(shù)據(jù)變更不再更新。例如,通過LiveData綁定的視圖,如果處于GONE狀態(tài),它的更新可能不會體現(xiàn)在界面上。
- 事件監(jiān)聽問題:將一個視圖設(shè)置為GONE會使得它的事件監(jiān)聽器失效,這在某些情況下可能會導(dǎo)致功能缺失
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="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" />
</LinearLayout>5.解決方式1:
4.1 使用協(xié)程刷新view
private fun initView() {
//使用協(xié)程方式刷新
uiScope.launch {
binding.textview.text = "這是view使用協(xié)程刷新"
}
}
4.2 使用view.post刷新
private fun initView() {
//使用view.post刷新
binding.textview.post {
binding.textview.text = "這是view使用post刷新"
Log.d(TAG,"view的內(nèi)容${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 {
// 當(dāng)布局確定后執(zhí)行的代碼
binding.textview.text = "這是view使用doOnLayout刷新"
}
6.遇到問題:
- 由于項目中是切換主題,view是Gone的狀態(tài),所以第5種方式是不生效的,這里不推薦使用,
- 方式2和3這里因為view是隱藏狀態(tài),所以在post刷新時會閃爍一下,為了解決此需要重新繪制布局,調(diào)用view.requestLayout()或view.invalidate()都可以
- 方式4因為項目中的設(shè)備是34的,所以不需要主動移除監(jiān)聽,在低版本是需要做移除操作
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() {
//使用協(xié)程方式刷新
uiScope.launch {
binding.textview.text = "這是view使用協(xié)程刷新"
}
binding.textview.visibility = View.GONE
//使用view.post刷新
binding.textview.post {
binding.textview.text = "這是view使用post刷新"
Log.d(TAG,"view的內(nèi)容${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 {
// 當(dāng)布局確定后執(zhí)行的代碼
binding.textview.text = "這是view使用doOnLayout刷新"
}
}
}9.總結(jié):
今天的使用場景很特殊,一般不會遇到,不過既然遇到了,就要找到問題原因解決掉問題,當(dāng)然解決方式有很多,這里看個人,沒有說一定要使用哪種方式,由于是demo所以沒有做主題切換的操作,view也是直接顯示的,感興趣的同學(xué)可以自己嘗試一下再view隱藏時切換主題會不會有此問題,打卡收工,祝大家新年快樂.
10.項目源碼:
https://gitee.com/jackning_admin/view-post-demo
到此這篇關(guān)于Android四種方式刷新View的文章就介紹到這了,更多相關(guān)Android 刷新View內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Android自定義ListView實現(xiàn)下拉刷新上拉加載更多
- android RecycleView實現(xiàn)下拉刷新和上拉加載
- 解決android viewmodel 數(shù)據(jù)刷新異常的問題
- Android巧用XListView實現(xiàn)萬能下拉刷新控件
- Android自定義view仿微信刷新旋轉(zhuǎn)小風(fēng)車
- Android自定義控件ListView下拉刷新的代碼
- Android ExpandableListView實現(xiàn)下拉刷新和加載更多效果
- Android RecyclerView的刷新分頁的實現(xiàn)
- android使用SwipeRefreshLayout實現(xiàn)ListView下拉刷新上拉加載
- android使用PullToRefresh框架實現(xiàn)ListView下拉刷新上拉加載更多
- Android 中RecyclerView頂部刷新實現(xiàn)詳解
相關(guān)文章
Android中的sqlite查詢數(shù)據(jù)時去掉重復(fù)值的方法實例
今天小編就為大家分享一篇關(guān)于Android中的sqlite查詢數(shù)據(jù)時去掉重復(fù)值的方法實例,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧2019-01-01
Android基于Sensor感應(yīng)器獲取重力感應(yīng)加速度的方法
這篇文章主要介紹了Android基于Sensor感應(yīng)器獲取重力感應(yīng)加速度的方法,涉及Android使用Sensor類實現(xiàn)感應(yīng)重力變化的功能,需要的朋友可以參考下2015-12-12
Android編程實現(xiàn)AlertDialog自定義彈出對話框的方法示例
這篇文章主要介紹了Android編程實現(xiàn)AlertDialog自定義彈出對話框的方法,結(jié)合實例形式分析了Android AlertDialog自定義彈出對話框的基本功能與事件監(jiān)聽實現(xiàn)技巧,需要的朋友可以參考下2017-07-07

