Android之视图绑定ViewBinding

文章介绍了如何在Android开发中启用和使用视图绑定,包括在Activity、Fragment、自定义Dialog和自定义View中的具体步骤,以及在RecyclerView.Adapter中的应用。通过视图绑定,可以简化代码并提高可维护性。

视图绑定  |  Android 开发者  |  Android Developers

1、启用视图绑定

android {
        ...
        viewBinding {
            enabled = true
        }
    }
    

如果您希望在生成绑定类时忽略某个布局文件,请将 tools:viewBindingIgnore="true" 属性添加到相应布局文件的根视图中:

<LinearLayout
            ...
            tools:viewBindingIgnore="true" >
        ...
    </LinearLayout>
    

2、在 Activity 中使用视图绑定

如需设置绑定类的实例以供 Activity 使用,请在 Activity 的 onCreate() 方法中执行以下步骤:

  1. 调用生成的绑定类中包含的静态 inflate() 方法。此操作会创建该绑定类的实例以供 Activity 使用。
  2. 通过调用 getRoot() 方法或使用 Kotlin 属性语法获取对根视图的引用。
  3. 将根视图传递到 setContentView(),使其成为屏幕上的活动视图。
 private lateinit var binding: ResultProfileBinding

    override fun onCreate(savedInstanceState: Bundle) {
        super.onCreate(savedInstanceState)
        binding = ResultProfileBinding.inflate(layoutInflater)
        val view = binding.root
        setContentView(view)
    }
    

3、在 Fragment 中使用视图绑定

如需设置绑定类的实例以供 Fragment 使用,请在 Fragment 的 onCreateView() 方法中执行以下步骤:

  1. 调用生成的绑定类中包含的静态 inflate() 方法。此操作会创建该绑定类的实例以供 Fragment 使用。
  2. 通过调用 getRoot() 方法或使用 Kotlin 属性语法获取对根视图的引用。
  3. 从 onCreateView() 方法返回根视图,使其成为屏幕上的活动视图。
    private var _binding: ResultProfileBinding? = null
    private val binding get() = _binding!!

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        _binding = ResultProfileBinding.inflate(inflater, container, false)
        return binding.root
    }

    override fun onDestroyView() {
        super.onDestroyView()
        _binding = null
    }
    

4、自定义Dialog中使用

public class MyDialog extends Dialog {
 
    protected View mView;
    protected DialogBottomBinding mBinding;
    
    public MyDialog(@NonNull Context context, @StyleRes int themeResId) {
        super(context, themeResId);
 
        //原来的写法
        // mView = View.inflate(getContext(), getLayoutId(), null);
 
        //使用ViewBinding的写法
        mBinding = DialogBottomBinding.inflate(getLayoutInflater());
        mView = mBinding.getRoot();
        
        setContentView(mView);
    }
}

5、在自定义View中使用

// 自定义view
public class MyLinearLayout extends LinearLayout {
    public MyLinearLayout(Context context) {
        this(context, null);
    }
 
    public MyLinearLayout(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }
 
    public MyLinearLayout(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
 
        // 正常添加布局(亲测有效)
        ViewMyLayoutBinding binding = LibPlateformLayoutBinding.inflate(LayoutInflater.from(getContext()), this, true);

        // 方法二:
        // val root = View.inflate(context, R.layout.widget_core, this)
        // binding = WidgetCoreBinding.bind(root)
 
        // 针对根标签为merge
        ViewMyLayoutMergeBinding binding = ViewMyLayoutMergeBinding.inflate(LayoutInflater.from(getContext()), this);
    }
 
}

6、在RecyclerView.Adapter中使用

class StudentAdapter(private val context: Context,
                     private val list: List<AddressInfo>) : RecyclerView.Adapter<ItemViewHolder>() {
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemViewHolder {
        val studentBinding = ItemAddressBinding.inflate(LayoutInflater.from(
            context), parent, false)
        return ItemViewHolder(studentBinding)
    }

    @SuppressLint("SetTextI18n")
    override fun onBindViewHolder(holder: ItemViewHolder, position: Int) {
        holder.itemBinding.tvName.text = "姓名:" + list[position].name
    }

    override fun getItemCount(): Int {
        return list.size
    }

    inner class ItemViewHolder(var itemBinding: ItemAddressBinding) : RecyclerView.ViewHolder(
        itemBinding.root)
}

Android 开发中,`ViewBinding` 是一种用于更轻松地访问视图组件的机制。它通过为每个 XML 布局文件生成绑定类,从而替代传统的 `findViewById()` 方法。使用 ViewBinding 可以显著减少样板代码,并提高类型安全性。 ### 使用步骤 #### 1. 启用 ViewBinding 在 `build.gradle` 文件中启用 ViewBinding: ```gradle android { ... viewBinding { enabled = true } } ``` #### 2. 创建布局文件(例如:`activity_main.xml`) ```xml <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <TextView android:id="@+id/textView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello, ViewBinding!" /> <Button android:id="@+id/button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Click Me" /> </LinearLayout> ``` #### 3. 在 Activity 中使用 ViewBinding 以下是使用 ViewBinding 的完整示例代码: ```java import android.os.Bundle; import androidx.appcompat.app.AppCompatActivity; public class MainActivity extends AppCompatActivity { private ActivityMainBinding binding; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 绑定布局 binding = ActivityMainBinding.inflate(getLayoutInflater()); setContentView(binding.getRoot()); // 使用绑定对象访问视图 binding.textView.setText("ViewBinding is working!"); binding.button.setOnClickListener(v -> binding.textView.setText("Button clicked!")); } @Override protected void onDestroy() { super.onDestroy(); // 避免内存泄漏 binding = null; } } ``` ### 解释 - **ActivityMainBinding**: - 这是根据 `activity_main.xml` 自动生成的绑定类。 - 它包含对所有视图的引用,并提供类型安全的访问方式。 - **binding.textView 和 binding.button**: - 这些是对布局中定义的 `TextView` 和 `Button` 的直接引用。 - 不需要手动调用 `findViewById()`。 - **binding.getRoot()**: - 返回根视图,通常作为 `setContentView()` 的参数传入。 - **避免内存泄漏**: - 在 `onDestroy()` 生命周期方法中将 `binding` 设置为 `null`,可以防止内存泄漏。 --- ### 优点 | 特性 | 描述 | |------|------| | 类型安全 | Binding 对象会自动生成正确的类型,避免强制类型转换 | | 空安全 | 如果某个视图不存在,编译器会在编译时报错而不是运行时报错 | | 提高开发效率 | 减少 `findViewById()` 的重复代码 | --- ### 注意事项 - **命名规则**: 绑定类的名称基于 XML 文件名并采用驼峰命名法,例如 `activity_main.xml` 会生成 `ActivityMainBinding` 类。 - **性能**: ViewBinding 的性能与传统 `findViewById()` 差不多,但它更加简洁和易读。 - **适用范围**: ViewBinding 支持 `Activity`、`Fragment`、`RecyclerView.ViewHolder` 等多种场景。 --- ### 示例:在 Fragment 中使用 ViewBinding ```java import android.os.Bundle; import androidx.fragment.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; public class MyFragment extends Fragment { private FragmentMyBinding binding; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { binding = FragmentMyBinding.inflate(inflater, container, false); return binding.getRoot(); } @Override public void onViewCreated(View view, Bundle savedInstanceState) { binding.textView.setText("Fragment with ViewBinding"); } @Override public void onDestroyView() { super.onDestroyView(); binding = null; } } ``` --- ### 相关问题
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

唐诺

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值