美文网首页android
Android Jetpack架构组件(五)—ViewBindi

Android Jetpack架构组件(五)—ViewBindi

作者: 独自闯天涯的码农 | 来源:发表于2022-07-16 22:57 被阅读0次

    一、ViewBinding的使用

    1、ViewBinding简介

    视图绑定是一项功能,可让您更轻松地编写与视图交互的代码。在模块中启用视图绑定后,它会为该模块中存在的每个 XML 布局文件生成一个 绑定类。绑定类的实例包含对在相应布局中具有 ID 的所有视图的直接引用。在大多数情况下,视图绑定会替换findViewById。

    也就是说view binding能够给每一个布局绑定一个布局类,这样我们就不需要使用findViewById来获取对应的视图了,可以防止一些视图为空的情况导致的错误。

    2、ViewBinding使用

    1.首先在build.gradle中添加以下代码,Kotlin语言
    buildFeatures {
            viewBinding = true
    }
    
    2.布局代码

    布局文件activity_main.xml

    <?xml version="1.0" encoding="utf-8"?>
    <androidx.constraintlayout.widget.ConstraintLayout 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"
        tools:context="com.alan.module.main.activity.MainActivity">
    
        <TextView
            android:id="@+id/tv_hello"
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:gravity="center"
            android:text="Hello World"
            android:textColor="@android:color/black"
            android:textSize="20sp"
            android:textStyle="bold"
            app:layout_constraintBottom_toTopOf="@+id/bt_request"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            tools:ignore="HardcodedText" />
    
        <Button
            android:id="@+id/bt_request"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginBottom="30dp"
            android:text="获取数据"
            android:textAllCaps="false"
            android:textSize="20sp"
            android:textStyle="bold"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            tools:ignore="HardcodedText" />
    
    </androidx.constraintlayout.widget.ConstraintLayout>
    

    启用ViewBinding功能后,Android Studio 会为每一个布局文件生成一个对应的Binding类,这个类以驼峰式命名。activity_main.xml 对应的就是ActivityMainBinding。

    3.Activity中使用
    class MainActivity : BaseActivity {
        private lateinit var binding: ActivityMainBinding
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            binding = ActivityMainBinding.inflate(layoutInflater)
            val view = binding.root
            setContentView(view)
        }
    }
    
    4.部分页面不启用ViewBinding

    在布局页面的根元素下加入声明

    tools:viewBindingIgnore="true"
    

    即如下所示

    <?xml version="1.0" encoding="utf-8"?>
    <androidx.constraintlayout.widget.ConstraintLayout 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"
        tools:viewBindingIgnore="true"
        tools:context="com.alan.module.main.activity.MainActivity">
    
    
    </androidx.constraintlayout.widget.ConstraintLayout>
    

    二、DataBinding的使用

    1、Data Binding简介

    Data Binding即数据绑定,使数据对象和xml布局绑定,支持双向绑定;
    是一个实现数据和UI绑定的框架,是构建MVVM模式的一个工具。

    2、Data Binding使用

    1.在app模块下的build.gradle文件添加内容
    android {
    ...
        dataBinding {
           enabled true
        }
    }
    
    2.创建ViewModel
    class LoginModel() : ViewModel() {
        var ld_phone: MutableLiveData<String> = MutableLiveData<String>()
        var ld_code: MutableLiveData<String> = MutableLiveData<String>()
        var ld_content: MutableLiveData<String> = MutableLiveData<String>()
    }
    
    3.布局转换

    在layout布局中选中根布局进行转换

    Convert to data binding layout
    
    几个标签含义
    • layout
      用作布局的根节点,只能包裹一个View标签,且不能包裹merge标签。
    • data
      Data Binding的数据,只能存在一个data标签。
    • variable
      data中使用,数据的变量标签,type属性指明变量的类,如com.alan.mvvm.viewmodel.LoginModel。name属性指明变量的名字,方便布局中使用。
    • import
      data中使用,需要使用静态方法和静态常量,如需要使用View.Visble属性的时候,则需导入<import type="android.view.View"/>。type属性指明类的路径,如果两个import标签导入的类名相同,则可以使用alias属性声明别名,使用的时候直接使用别名即可。
    • include
      View标签中使用,作用同普通布局中的include一样,需要使用bind:<参数名>传递参数
    <?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">
    
        <data>
            <!--需要的viewModel,通过mBinding.vm=mViewMode注入-->
            <variable
                name="model"
                type="com.alan.mvvm.viewmodel.LoginModel"/>
    
            <variable
                name="activity"
                type="androidx.fragment.app.FragmentActivity"/>
        </data>
    
        <androidx.constraintlayout.widget.ConstraintLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent">
    
            <TextView
                android:id="@+id/txt_cancel"
                android:onClick="@{()-> activity.onBackPressed()}"
                />
    
            <TextView
                android:id="@+id/txt_title"
                app:layout_constraintTop_toTopOf="parent"
                .../>
    
            <EditText
                android:id="@+id/et_account"
                android:text="@{model.ld_phone.get()}"
                android:onTextChanged="@{(text, start, before, count)->model.onNameChanged(text)}"
                ...
                />
    
            <EditText
                android:id="@+id/et_pwd"
                android:text="@{model.code.get()}"
                android:onTextChanged="@{model::onPwdChanged}"
                ...
                />
    
            <Button
                android:id="@+id/btn_login"
                android:text="Sign in"
                android:onClick="@{() -> model.login()}"
                android:enabled="@{(model.code.get().isEmpty()||model.phone.get().isEmpty()) ? false : true}"
                .../>
    
    
        </androidx.constraintlayout.widget.ConstraintLayout>
    </layout>
    
    1. 属性的引用
      如果想使用ViewModel中成员变量,如直接使用model.ld_phone

    2. 事件绑定
      事件绑定包括方法引用和监听绑定:

    • 方法引用:参数类型和返回类型要一致,参考et_pwdEditTextandroid:onTextChanged引用。
    • 监听绑定:相比较于方法引用,监听绑定的要求就没那么高了,我们可以使用自行定义的函数,参考et_accountEditText的android:onTextChanged引用。
    1. 表达式
      btn_loginButton在密码没有内容的时候是灰色的就是使用的表达式。
    • 运算符 + - / * %
    • 字符串连接 +
    • 逻辑与或 && ||
    • 二进制 & | ^
    • 一元 + - ! ~
    • 移位 >> >>> <<
    • 比较 == > < >= <= (Note that < needs to be escaped as <)
    • instanceof
    • Grouping ()
    • Literals - character, String, numeric, null
    • Cast
    • 方法调用
    • 域访问
    • 数组访问
    • 三元操作符
    4.生成绑定类并使用

    布局文件创建完毕之后,点击Build下面的Make Project,让系统帮我生成绑定类ActivityLoginBinding

    然后只需在LoginActivity 中完成绑定即可,绑定操作既可以使用上述生成的ActivityLoginBinding也可以使用自带的DataBindingUtil完成:

    1.使用DataBindingUtil
    函数名 作用
    setContentView 用来进行Activity下面的绑定
    inflate 用来进行Fragment下面的绑定
    bind 用来进行View的绑定
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val binding: ActivityLoginBinding =DataBindingUtil.setContentView(this, R.layout.activity_login)
    }
    
    //DataBinding也支持在Fragment和RecyclerView中使用
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        binding = DataBindingUtil.inflate(inflater, getContentViewId(), container, false);
        return binding.getRoot();
    }
    
    2.使用生成的ActivitytLoginBinding
        binding = ActivitytLoginBinding.inflate(inflater, getContentViewId(), container, false);
    

    相关文章

      网友评论

        本文标题:Android Jetpack架构组件(五)—ViewBindi

        本文链接:https://www.haomeiwen.com/subject/xxxkirtx.html