ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Jetpack_dataBinding

2021-07-04 23:03:52  阅读:237  来源: 互联网

标签:布局 layout Jetpack 绑定 class dataBinding MyViewModel public


开始使用

1. 在moudle的build.gradle中开启对databinding的支持

    defaultConfig {
        applicationId "com.example.databinding_viewmodel_livedata"
        minSdkVersion 15
        targetSdkVersion 30
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"

		//开启对databinding的支持
        dataBinding{
            enabled = true
        }
    }

2. 在布局文件中添加layout布局

<?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>
        <variable
            name="viewModel"
            type="com.example.databinding_viewmodel_livedata.MyViewModel" />
    </data>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">
    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

3. 获取dataBinding的引用

  1. 在activity中
	//绑定类名 = 布局名称(转换为驼峰) + Binding
	ActivityMainBinding activityMainBinding = DataBindingUtil.setContentView(this,R.layout.activity_main);
  1. 在fragment中
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        final FragmentFirstBinding fragmentFirstBinding = DataBindingUtil.inflate(inflater,R.layout.fragment_first,container,false);
        return fragmentFirstBinding.getRoot();
    }

两个常用的标签

1.声明标签

    <data>
        <variable
            name="viewModel"
            type="com.example.databinding_viewmodel_livedata.MyViewModel" />
    </data>

表示在layout布局文件中,声明一个变量
变量的类型: com.example.databinding_viewmodel_livedata.MyViewModel
变量的名称: viewModel
变量由 DataBinding对象 赋值 :

 ActivityMainBinding activityMainBinding = DataBindingUtil.setContentView(this,R.layout.activity_main);
 MyViewModel myViewModel = new ViewModelProvider(this).get(MyViewModel.class);
 activityMainBinding.setViewModel(myViewModel);

2.导入标签

    <data>
        <import type="com.example.databinding_viewmodel_livedata.AppUtils"
            alias="appUtils"/>
    </data>

表示在layout布局文件中,导入一个类
alias=“appUtils” : 给类起别名 (可不设置)
类中存在静态方法: madeNewScore(int score) ,可直接调用:

   <TextView
            android:id="@+id/tvScore"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{appUtils.madeNewScore(viewModel.score)}"
            android:textSize="30sp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

在include中使用

1.创建文件名称为 include_layout 的 include布局

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
    <data>
        <variable
            name="includeViewModel"
            type="com.example.databinding_viewmodel_livedata.MyViewModel" />
    </data>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="@{String.valueOf(includeViewModel.num)}"
            android:textSize="22sp" />

    </LinearLayout>
</layout>

2.使用include布局

	<include
		app:includeViewModel="@{viewModel}"
		layout="@layout/include_layout"
	/>

includeViewModel : 在include布局文件定义的 变量名称
app:includeViewModel="@{viewModel}": 将该布局数的viewModel变量 赋值给 include布局中的includeViewModel变量


事件处理

方法绑定

相似于给view添加onClick()方法

    public class MyHandlers {
        public void onClickFriend(View view) { ... }
    }
<?xml version="1.0" encoding="utf-8"?>
    <layout xmlns:android="http://schemas.android.com/apk/res/android">
       <data>
           <variable name="handlers" type="com.example.MyHandlers"/>
           <variable name="user" type="com.example.User"/>
       </data>
       <LinearLayout
           android:orientation="vertical"
           android:layout_width="match_parent"
           android:layout_height="match_parent">
           <TextView android:layout_width="wrap_content"
               android:layout_height="wrap_content"
               android:text="@{user.firstName}"
               android:onClick="@{handlers::onClickFriend}"/>
       </LinearLayout>
    </layout>
监听器绑定 (常用,且可在监听回调中传入任意个数的参数)
    public class Presenter {
        public void onSaveClick(Task task){}
    }
<?xml version="1.0" encoding="utf-8"?>
    <layout xmlns:android="http://schemas.android.com/apk/res/android">
        <data>
            <variable name="task" type="com.android.example.Task" />
            <variable name="presenter" type="com.android.example.Presenter" />
        </data>
        <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent">
            <Button android:layout_width="wrap_content" android:layout_height="wrap_content"
            android:onClick="@{() -> presenter.onSaveClick(task)}" />
        </LinearLayout>
    </layout>
    

绑定适配器

此处示例实现了 LiveData + ViewModel + DataBinding 的结合
意义: 实现了单向绑定, 当ViewModel中的值(LiveData包裹)发生变化时,界面会自动发生变化

创建绑定适配器

public class BindingAdapterManager {

    @BindingAdapter(value = {"imageUrl","imageLocal"},requireAll = false)
    public static void setImage(ImageView imageView,String imageUrl,int resId){
        if (!TextUtils.isEmpty(imageUrl)){
            Glide.with(imageView.getContext()).load(imageUrl).into(imageView);
        }else {
            Glide.with(imageView.getContext()).load(resId).into(imageView);
        }
    }
    
}
解读
  1. 上图相当于给Binding布局中的 ImageView标签 添加 imageUrl属性imageLocal属性

  2. 其中 ImageView标签源于方法的第一个参数

  3. imageUrl属性 和 imageLocal属性 源于 BindingAdapter注解中的两个value值

  4. BindingAdapter注解中value值 接收的是一个数组,意味着可以给 ImageView标签 添加任意个数的属性

  5. requireAll : true: 默认, 如果声明的value没有被全部设置,则无法编译 false: 允许只有部分值被设置

  6. 通过绑定适配器,可以将View的一些属性的设置实现复用 ,并与业务逻辑实现解耦

在布局中的使用

<?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>
        <variable
            name="viewModel"
            type="com.example.databinding_viewmodel_livedata.MyViewModel" />
    </data>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center_horizontal"
        android:orientation="vertical"
        android:padding="40dp"
        tools:context=".MainActivity">

        <ImageView
            app:imageUrl="@{viewModel.imgUrl}"
            app:imageLocal="@{viewModel.imgLocalResId}"
            android:layout_width="match_parent"
            android:layout_height="200dp"/>

    </LinearLayout>
</layout>

对应的ViewModel

public class MyViewModel extends ViewModel {

    private MutableLiveData<Integer> imgLocalResId;
    private MutableLiveData<String> imgUrl;

    public MutableLiveData<Integer> getImgLocalResId() {
        if (imgLocalResId==null){
            imgLocalResId = new MutableLiveData<>();
            imgLocalResId.setValue(R.mipmap.idol);
        }
        return imgLocalResId;
    }

    public MutableLiveData<String> getImgUrl() {
        if (imgUrl==null){
            imgUrl = new MutableLiveData<>();
            imgUrl.setValue(
                    "http://wx1.sinaimg.cn/mw2000/007fS0GEgy1gs59xp5cwfj60tw1a810v02.jpg"
            );
        }
        return imgUrl;
    }
}

在Activity中的使用

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //创建databinding对象
        ActivityMainBinding activityMainBinding = DataBindingUtil.setContentView(this,R.layout.activity_main);
        //获取ViewModel对象
        MyViewModel myViewModel = new ViewModelProvider(this).get(MyViewModel.class);
		//设置dataBinding的变量的值
        activityMainBinding.setViewModel(myViewModel);
        //不设置无法实现单向绑定
        activityMainBinding.setLifecycleOwner(this);
    }
}

标签:布局,layout,Jetpack,绑定,class,dataBinding,MyViewModel,public
来源: https://blog.csdn.net/weixin_38397436/article/details/118466070

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有