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-01Android基于Sensor感應(yīng)器獲取重力感應(yīng)加速度的方法
這篇文章主要介紹了Android基于Sensor感應(yīng)器獲取重力感應(yīng)加速度的方法,涉及Android使用Sensor類實現(xiàn)感應(yīng)重力變化的功能,需要的朋友可以參考下2015-12-12Android編程實現(xiàn)AlertDialog自定義彈出對話框的方法示例
這篇文章主要介紹了Android編程實現(xiàn)AlertDialog自定義彈出對話框的方法,結(jié)合實例形式分析了Android AlertDialog自定義彈出對話框的基本功能與事件監(jiān)聽實現(xiàn)技巧,需要的朋友可以參考下2017-07-07