尋找Layout某個View時
之前是使用findViewById找到指定的View
View Binding則是利用Layout名稱來做綁定或者初始化,便可取得指定的View
大多數的情況,可以替代View Binding
但也是有例外
視圖綁定的優點及缺點,可以參考Android官方網站
使用View Binding前的設置
至App build.gradle設置以下內容
android { ... buildFeatures { viewBinding = true } ... } //出現警告Access to 'viewBinding' exceeds its access rights //改成以下即可,把=拿掉 buildFeatures { viewBinding true }
在Activity中使用
//原先的內容如下 override fun onCreate(savedInstanceState: Bundle?) { setContentView(R.layout.activity_home) } //變更為以下方式 //此處的ActivityHomeBinding是activity_home的layout名稱直接轉換 //_後面的英文會自動變大寫,然後刪掉_ private lateinit var binding: ActivityHomeBinding override fun onCreate(savedInstanceState: Bundle?) { binding = ActivityHomeBinding.inflate(layoutInflater) setContentView(binding.root) //這樣就可以取得直接取到layout裡面的view binding.imageview.setBackgroundColor( ContextCompat.getColor( context,Color.white ) }
在Fragment中使用
class TestFragment1: Fragment() { private var _binding: FragmentTest1Binding? = null private val binding get() = _binding!! override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View { _binding = FragmentTest1Binding.inflate(layoutInflater, container, false) return binding.root } override fun onDestroyView() { super.onDestroyView() _binding = null } }
這裡介紹使用的小細節
1. 在一個Layout裡面include layout,調用方式會不一樣
//需要將此Layout設定id <include layout="@layout/bottom_check_layout" android:id="@+id/bottomCheckLayout2" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent"/> //使用的時候,一樣先找到此層的binding //假設@layout/bottom_check_layout裡面有個ImageView id是imageView2 //如下 //binding.bottomCheckLayout2.imageView2就可以這樣使用了
2. ViewStub的使用方法
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" xmlns:app="http://schemas.android.com/apk/res-auto"> <ViewStub android:id="@+id/viewstub" android:layout_width="match_parent" android:layout_height="match_parent" android:layout="@layout/sub_layout"/> </androidx.constraintlayout.widget.ConstraintLayout>
使用方式會有些不一樣
狀況如下:
binding.viewstub.inflate()
這樣Android Studio會顯示錯誤inflate找不到
可以正常編譯、在手機運行
錯誤是因為viewstub轉變成ViewStubProxy
所以找不到inflate()方法
如果把viewstub當作ViewStubProxy用
編譯會錯誤
Unresolved reference: isInflated
Unresolved reference: viewStub
為了解決這個問題,使用方法如下:
private lateinit var binding: MainLayoutBinding private lateinit var bindingSub: SubLayoutBinding override fun onCreate(savedInstanceState: Bundle?) { binding = MainLayoutBinding.inflate(layoutInflater) setContentView(binding.root) binding.viewstub.setOnInflateListener { _, inflated -> //將設定第二個binding,之後sub_layout裡面的view //都將使用bindingSub來呼叫 bindingSub = SubLayoutBinding.bind(inflated) } //此處可以透過findViewById來處理,也可以去掉錯誤紅字 //利用binding.root找到指定的id val viewStub = binding.root.findViewById(R.id.viewstub) //執行這個後inflate(),上方Listener會觸發 //就可以找到內部的binding viewStub.inflate() }
訂閱Codeilin的旅程,若有最新消息會通知。
廣告
發表迴響