[英]How to use view binding in Android
我一直在使用findViewById
,然后使用 ButterKnife 来绑定视图。 最近,我偶然发现了这篇文章,但不太确定如何使用它。
我尝试这样做,但它似乎在 Android Studio 3.4.2 中不起作用
val binding = MainActivityBinding.inflate(layoutInflater)
setContentView(binding.root)
然后使用这些值,例如:
binding.button....
binding.textView....
您应该做几件事,我尝试将其组织起来并列出:(基于此链接中的 Android 开发人员文档和我的个人经验)
您需要使用 Android Studio 3.6 canary11+(我目前正在使用 Android Studio 4,它对我来说做得很好)
你可以从这里找到它: https ://developer.android.com/studio/archive
您需要将 Gradle 包装器升级到 Gradle“5.6.4”,将 Gradle 构建工具升级到“3.6.0-rc01”,更高版本也可以使用,所以不要害怕更新
distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-all.zip
dependencies {
...
classpath 'com.android.tools.build:gradle:3.6.0-rc01'
}
android {
...
viewBinding {
enabled = true
}
}
tools:viewBindingIgnore="true"
属性添加到该布局文件的根视图: <LinearLayout
...
tools:viewBindingIgnore="true" >
...
</LinearLayout>
如果为模块启用了视图绑定,则会为模块包含的每个 XML 布局文件生成一个绑定类。 每个绑定类都包含对根视图和所有具有 ID 的视图的引用。 绑定类的名称是通过将 XML 文件的名称转换为驼峰式并在末尾添加单词“Binding”来生成的。
例如,给定一个名为result_profile.xml
的布局文件:
<LinearLayout ... >
<TextView android:id="@+id/name" />
<ImageView android:cropToPadding="true" />
<Button android:id="@+id/button"
android:background="@drawable/rounded_button" />
</LinearLayout>
生成的绑定类称为ResultProfileBinding
。 这个类有两个字段:一个名为name
的TextView
和一个名为button
的Button
。 布局中的ImageView
没有 ID,所以绑定类中也没有对其的引用。
每个绑定类还包含一个getRoot()
方法,为相应布局文件的根视图提供直接引用。 在此示例中, ResultProfileBinding
类中的getRoot()
方法返回LinearLayout
根视图。
private ResultProfileBinding binding;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = ResultProfileBinding.inflate(getLayoutInflater());
View view = binding.getRoot();
setContentView(view);
}
private FragmentHousesBinding binding;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
binding = FragmentHousesBinding.inflate(inflater, container, false);
init();
return binding.getRoot();
}
HouseCardPropertyFragmnetBinding binding;
@Override
public Holder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
binding = HouseCardPropertyFragmnetBinding.inflate(LayoutInflater
.from(parent.getContext()), parent, false);
return new Holder(binding);
}
@Override
public void onBindViewHolder(@NonNull HouseAdapter.Holder holder, int position) {
holder.bindData(getItem(position));
}
class Holder extends RecyclerView.ViewHolder {
HouseCardPropertyFragmnetBinding view;
Holder(@NonNull HouseCardPropertyFragmnetBinding v) {
super(v.getRoot());
view = v;
}
void bindData(Tag item) {
view.tagTxt.setText(item.Name);
}
}
就是这样,从现在开始你就可以摆脱findViewById
了;)
ViewBinding 仅适用于 Android Studio 3.6 及更高版本
1:- 您需要在 build.gradle (项目级别)中将您的 gradle build toolold 升级到 3.6.1
dependencies {
classpath 'com.android.tools.build:gradle:3.6.1'
}
2:- 你需要在 build.gradle(app) 中启用 viewBinding
android {
viewBinding {
enabled = true
}}
一旦启用视图绑定,就会为每个 XML 布局生成一个绑定类。 绑定类的名称是通过将 XML 文件的名称转换为驼峰式并在末尾添加单词“Binding”来生成的。
示例:- 如果布局文件命名为“ add_item_activity.xml ”,则绑定类的名称将为“ AddItemActivityBinding ”
3:-要设置绑定类的实例以与活动一起使用,创建绑定类的实例,这里我们将创建“ AddItemActivityBinding ”的实例并调用绑定类中生成的静态膨胀方法
通过调用 getRoot() 方法获取对根视图的引用,并在 setContentView() 方法中传递此根视图
public class AddItemActivity extends AppCompatActivity {
private AddItemActivityBinding binding;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = AddItemActivityBinding.inflate(getLayoutInflater());
View view = binding.getRoot();
setContentView(view);
//now we can access views by their IDs
binding.tvTitleMyOrder.setText("Title goes here");
}
}
现在我们可以使用绑定类的实例通过它们的 ID 访问视图
视图绑定仅在 Android Studio 3.6 Canary 11+ 中可用。 首先,您使用 android gradle 插件版本 3.6.0-alpha11+ 升级 Android Studio(您现在可以同时使用它们的测试版,尚未发布稳定版但您可以使用测试版)然后在build.gradle
中添加以下代码
android {
viewBinding.enabled = true
}
现在您可以像我们使用的数据绑定一样使用:
private lateinit var binding: ActivityMainBinding
@Override
fun onCreate(savedInstanceState: Bundle) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
binding.textView.text = "Hello World"
}
而已。
在 Google IO/19 的本次演讲中介绍了ViewBindings 。 它将在 Android Studio 3.6 中可用,正如您所提到的,您使用的是 Android Studio 3.4.2,因此它无法正常工作。 阅读本文中的 ViewBindings 部分以获取更多参考。 希望这可以帮助!
视图绑定ViewBinding 在 Android Studio 3.6 及更高版本中可用
它用于将视图绑定到代码,换句话说,我们可以简单地说它替换了 android 中的 findViewById,从而减少了样板代码。
每当您对 Fragment、Activity 或 RecyclerView Adapter 等布局进行膨胀时,我们都可以使用视图绑定。
启用视图绑定后,它将自动为 android 项目中的所有 XML 布局生成一个绑定类,无需手动对我们的 xml 布局进行任何更改。
我们可以在模块级 build.gradle 中启用视图绑定
安卓 {
...
构建功能 {
视图绑定真
}
}
activity_simple_view_binding_example.xml
<?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:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".SimpleViewBindingExample">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="18sp"
android:id="@+id/demoTv"/>
</LinearLayout>
SimpleViewBindingExample.java
public class SimpleViewBindingExample extends AppCompatActivity {
private ActivitySimpleViewBindingExampleBinding activitySimpleViewBindingExampleBinding;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
activitySimpleViewBindingExampleBinding = ActivitySimpleViewBindingExampleBinding.inflate(getLayoutInflater());
setContentView(activitySimpleViewBindingExampleBinding.getRoot());
activitySimpleViewBindingExampleBinding.demoTv.setText("View Binding is simple");
}
}
在大多数情况下,视图绑定取代了 findViewById。
Java:在 Gradle 文件中添加这个
android {
...
buildFeatures {
viewBinding true
}
}
科特林
android {
...
buildFeatures {
viewBinding = true
}
}
如果您希望在生成绑定类时忽略布局文件,请将 tools:viewBindingIgnore="true" 属性添加到该布局文件的根视图:
<LinearLayout
...
tools:viewBindingIgnore="true" >
...
</LinearLayout>
在活动中使用视图绑定
科特林
private lateinit var binding: ResultProfileBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ResultProfileBinding.inflate(layoutInflater)
val view = binding.root
setContentView(view)
}
爪哇
private ResultProfileBinding binding;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = ResultProfileBinding.inflate(getLayoutInflater());
View view = binding.getRoot();
setContentView(view);
}
您现在可以使用绑定类的实例来引用任何视图:
科特林
binding.name.text = viewModel.name
binding.button.setOnClickListener { viewModel.userClicked() }
爪哇
binding.getName().setText(viewModel.getName());
binding.button.setOnClickListener(new View.OnClickListener() {
viewModel.userClicked()
});
在片段中查看绑定
科特林
private var _binding: ResultProfileBinding? = null
// This property is only valid between onCreateView and
// onDestroyView.
private val binding get() = _binding!!
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
_binding = ResultProfileBinding.inflate(inflater, container, false)
val view = binding.root
return view
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
爪哇
private ResultProfileBinding binding;
@Override
public View onCreateView (LayoutInflater inflater,
ViewGroup container,
Bundle savedInstanceState) {
binding = ResultProfileBinding.inflate(inflater, container, false);
View view = binding.getRoot();
return view;
}
@Override
public void onDestroyView() {
super.onDestroyView();
binding = null;
}
您现在可以使用绑定类的实例来引用任何视图:
科特林
kotlinbinding.name.text = viewModel.name
binding.button.setOnClickListener { viewModel.userClicked() }
爪哇
binding.getName().setText(viewModel.getName());
binding.button.setOnClickListener(new View.OnClickListener() {
viewModel.userClicked()
});
作为初学者,如果您想学习在您的 Android 项目中实现数据绑定。
然后只需按照以下步骤操作:-
1:- 首先打开你的Gradel 脚本文件夹并找到build.gradel模块文件并将此代码粘贴到android项目中。
dataBinding {
enabled = true
}
plugins { id 'com.android.application' id 'kotlin-android' } android { compileSdkVersion 30 buildToolsVersion "30.0.3" defaultConfig { applicationId "com.example.implementing_data_binding" minSdkVersion 19 targetSdkVersion 30 versionCode 1 versionName "1.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } kotlinOptions { jvmTarget = '1.8' } dataBinding { enabled = true } } dependencies { implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" implementation 'androidx.core:core-ktx:1.3.2' implementation 'androidx.appcompat:appcompat:1.2.0' implementation 'com.google.android.material:material:1.3.0' implementation 'androidx.constraintlayout:constraintlayout:2.0.4' implementation 'androidx.navigation:navigation-fragment-ktx:2.3.5' implementation 'androidx.navigation:navigation-ui-ktx:2.3.5' testImplementation 'junit:junit:4.+' androidTestImplementation 'androidx.test.ext:junit:1.1.2' androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0' }
然后只需在您的 XML 文件中将您当前的布局封装在一个新的父布局标记中,并将名称空间声明从当前布局转移到新创建的父布局
<?xml version="1.0" encoding="utf-8"?> <layout 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"> <androidx.coordinatorlayout.widget.CoordinatorLayout android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity" > <TextView android:id="@+id/myId" android:layout_width="wrap_content" android:layout_height="34dp" android:layout_marginLeft="150sp" android:layout_marginTop="300sp" android:text="Hello world!" /> </androidx.coordinatorlayout.widget.CoordinatorLayout> </layout>
2:- 转到您的视图并为其分配一个 id:- android:id="@+id/textHere"
3:-然后只需进入相应的活动文件并在活动类初始化下方放置
lateinit var 绑定:ActivityMainBinding;
注意 - ActivityMainBinding 这个词只是视图存在的文件与 + 'Binding' 的组合
例如:- 文件名:acvity_main.kt -------> ActivityMainBinding
在 onCreate 函数内部,就在超级构造函数调用 put 的下方
binding = androidx.databinding.DataBindingUtil.setContentView(this,R.layout.activity_main);
这里 - R.layout.activity_main 是视图所在文件的名称
package com.example.implementing_data_binding import android.os.Bundle import com.google.android.material.floatingactionbutton.FloatingActionButton import com.google.android.material.snackbar.Snackbar import androidx.appcompat.app.AppCompatActivity import android.view.Menu import android.view.MenuItem import com.example.implementing_data_binding.databinding.ActivityMainBinding class MainActivity : AppCompatActivity() { lateinit var binding: ActivityMainBinding; override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = androidx.databinding.DataBindingUtil.setContentView(this,R.layout.activity_main); // setContentView(R.layout.activity_main) binding.myId.text = "Yup its done!"; } }
现在您可以访问该视图的属性。
尝试binding.myId.text = "是的,它完成了!";
注意:-myId 是我们在视图中定义的我的 id 的名称
从 Android studio 3.6 canary11+ 你可以使用 ViewBinding。 有关参考,请参阅此链接
我建议这样使用:
private val viewBinding: ADarkModeBinding by lazy { ADarkModeBinding.inflate(layoutInflater) }
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(viewBinding.root)
}
在科特林
重要的是视图绑定仅适用于 android studio 3.6+。 在项目中实现视图绑定,您可以按照以下步骤操作。
第 1 步:在 build.gradle(项目级别)文件中升级您的 Gradle 版本(3.6.1+)。
dependencies {
classpath 'com.android.tools.build:gradle:7.0.3'
}
第 2 步:将此行添加到您在android{}中的 build.gradle(应用级别)文件中
buildFeatures {
viewBinding = true
}
第 3 步:添加此代码(取决于您的活动名称)。
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
val view = binding.root //you can use directly setContentView(binding.root)
setContentView(view)
binding.textview.text="Hii"
}
或者您可以在此代码中实现上述功能。 我个人更喜欢去第二个。
class MainActivity : AppCompatActivity() {
private val binding by lazy {
ActivityMainBinding.inflate(layoutInflater)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(binding.root)
binding.textview.text="Hii"
}
}
:----------------------------------------------------这是给 Kotlin 的-------- -------------------------------------------:
我不能发布图片,因为我有 9 个声望并且需要 10 个声望。 请检查图片链接以获取说明
1)在项目的模块中添加viewBinding:
buildFeatures{
viewBinding true
}
2) 为您添加绑定活动 Class:
private lateinit var binding: ActivitySplashBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivitySplashBinding.inflate(layoutInflater)
setContentView(binding.root)
我不能发布图片,因为我有 9 个声望并且需要 10 个声望。 请检查图片链接以获取说明
如果您使用的是 Kotlin,您所要做的就是添加此插件:
plugins {
id 'com.android.application'
id 'org.jetbrains.kotlin.android'
id 'kotlin-android-extensions' <--
}
在您的课程文件中:
var binding = MainActivityBinding.inflate(layoutInflater) setContentView(MainActivity.this, R.layout.activity_Main)
binding.name = "Hello world"
在您的布局文件中:父布局将为<layout>
和<data>
<?xml version="1.0" encoding="utf-8"?>
<layout 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"
>
<!-- Inside the layout tag it is possible to set the data tag in order to set one or many variables. For this example we are having an User property-->
<data>
<variable
name="name"
type="String"/>
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<!-- your layout-->
<TextView
android:id="@+id/user_name_text_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="16dp"
android:text="@{name}" // here you can bind any data
tools:text="Name"
/>
</LinearLayout>
在Gradle中:
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-kapt'
android {
....
dataBinding {
enabled = true
}
}
dependencies {
...
// notice that the compiler version must be the same than our gradle version
kapt 'com.android.databinding:compiler:2.3.1'
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.