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