【android-architecture】TODO-DataBinding

xiaoxiao2021-02-28  40

todo-databinding 是基于todo-mvp ,但是使用了Data Binding 去展示数据并且绑定操作,这不是一个严格的Model-View-ViewModel,它同时使用了View Models 和 Presenter.

Data Binding 库可以节省很多样板代码,它允许UI元素和data model中的属性绑定起来

布局文件用于将数据元素(如姓名name,年龄age)绑定到UI元素(TextView,EditText等)事件也用action handler绑定起来数据可以被观察在需要的时候自动更新数据

Databinding 简介

Databinding是一个实现数据和UI绑定的库,可以省掉很多我们以前经常写的末班方法,比如findViewById,setText,setVisibility等方法,直接在layout文件中将具体的值与控件绑定比如 将任务名与显示的textView绑定 <TextView android:id="@+id/title" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:layout_marginLeft="@dimen/activity_horizontal_margin" android:textAppearance="@style/TextAppearance.AppCompat.Title" android:text="@{task.titleForList}" /> 如果还不了解databinding的参考Data Binding Library,这里不多说啦

Activity

以任务列表页为例,这个架构中Activity充当各个组件的创建容器,在TasksActivity的onCreate中创建TasksFragment,TasksPresenter和TasksViewModel

protected void onCreate(Bundle savedInstanceState) { ... ... TasksFragment tasksFragment = (TasksFragment) getSupportFragmentManager().findFragmentById(R.id.contentFrame); if (tasksFragment == null) { // 创建fragment,即MVP中的View角色 tasksFragment = TasksFragment.newInstance(); ActivityUtils.addFragmentToActivity(getSupportFragmentManager(), tasksFragment, R.id.contentFrame); } // 创建presenter,即mvp中的p层,同时创建数据仓库(model),presenter同时持有view和model mTasksPresenter = new TasksPresenter(Injection.provideTasksRepository( getApplicationContext()), tasksFragment); //创建ViewModel TasksViewModel tasksViewModel = new TasksViewModel(getApplicationContext(), mTasksPresenter); tasksFragment.setViewModel(tasksViewModel); }

Fragment

实现TasksContract.View接口,mvp中的view层,根据计算结果展示界面,将TasksViewModel通过Databinding设置给layout,Fragment同时也持有presenter,通过presenter去得到用户操作的结果

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { TasksFragBinding tasksFragBinding = TasksFragBinding.inflate(inflater, container, false); tasksFragBinding.setTasks(mTasksViewModel); 将mTasksViewModel绑定到布局 tasksFragBinding.setActionHandler(mPresenter); 将presenter绑定到布局,这样可以直接在布局中将presenter中的方法与点击事件绑定 ... ... }

布局中将presenter中的方法与点击事件绑定

<TextView android:id="@+id/noTasksAdd" android:layout_width="wrap_content" android:layout_height="48dp" android:layout_gravity="center" android:background="@drawable/touch_feedback" android:gravity="center" android:text="@string/no_tasks_add" android:onClick="@{() -> actionHandler.addNewTask()}" android:visibility="@{tasks.tasksAddViewVisible ? View.VISIBLE : View.GONE}" /> TasksPresenter.java @Override public void addNewTask() { mTasksView.showAddTask(); }

ViewModel

相当于布局要绑定的数据的一个映射类,即要展示的数据全部由ViewModel来提供,将ViewModel设置给layout

tasksFragBinding.setTasks(mTasksViewModel);

layout接收TasksViewModel并命名为tasks

tasks_frag.xml <layout xmlns:android="http://schemas.android.com/apk/res/android"> <data> <import type="android.view.View" /> <variable name="tasks" type="com.example.android.architecture.blueprints.todoapp.tasks.TasksViewModel" /> <variable name="actionHandler" type="com.example.android.architecture.blueprints.todoapp.tasks.TasksContract.Presenter" /> </data>

根据TasksViewModel中的数据设置界面

tasks_frag.xml <LinearLayout android:id="@+id/tasksLL" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:visibility="@{tasks.notEmpty ? View.VISIBLE : View.GONE}"> <TextView android:id="@+id/filteringLabel" android:layout_width="match_parent" android:layout_height="wrap_content" android:textAppearance="@style/TextAppearance.AppCompat.Title" android:gravity="center_vertical" android:layout_marginLeft="@dimen/list_item_padding" android:layout_marginRight="@dimen/list_item_padding" android:layout_marginTop="@dimen/activity_vertical_margin" android:layout_marginBottom="@dimen/activity_vertical_margin" android:text="@{tasks.currentFilteringLabel}" /> <ListView android:id="@+id/tasks_list" android:layout_width="match_parent" android:layout_height="wrap_content" /> </LinearLayout>

这部分意思是如果tasks不是空的就显示列表,notempty的值是从哪里来的呢

TasksViewModel.java @Bindable public boolean isNotEmpty() { return mTaskListSize > 0; }

@Bindable是DataBinding的注解,可以生成一个notEmpty的属性,这个demo中的属性都是这样生成的

Presenter

mvp中的p层,负责解析view的请求并计算,最后将计算结果返回给View,刚才绑定生命Tasks的地方同时也声明了actionHandler,他是一个presenter的对象

<variable name="actionHandler" type="com.example.android.architecture.blueprints.todoapp.tasks.TasksContract.Presenter" />

当view接收到请求的时候,actionHandler触发相应的计算方法,比如点击了添加按钮

TextView android:id="@+id/noTasksAdd" android:layout_width="wrap_content" android:layout_height="48dp" android:layout_gravity="center" android:background="@drawable/touch_feedback" android:gravity="center" android:text="@string/no_tasks_add" android:onClick="@{() -> actionHandler.addNewTask()}" android:visibility="@{tasks.tasksAddViewVisible ? View.VISIBLE : View.GONE}" />

因为onclick与actionHandler的addnewTask()方法绑定,点击的时候触发方法

TasksPresenter.java public void addNewTask() { mTasksView.showAddTask(); }

这里计算结果就是现实添加界面,所以通知View去打开添加界面

TasksFragment.java public void showAddTask() { Intent intent = new Intent(getContext(), AddEditTaskActivity.class); startActivityForResult(intent, AddEditTaskActivity.REQUEST_ADD_TASK); }

这个架构的大体执行流程就是这样啦

转载请注明原文地址: https://www.6miu.com/read-78492.html

最新回复(0)