【android-architecture】TODO-DataBinding

来源:互联网 发布:淘宝企业开店费用 编辑:程序博客网 时间:2024/05/18 15:23

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

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

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

image

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充当各个组件的创建容器,在TasksActivityonCreate中创建TasksFragmentTasksPresenterTasksViewModel

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);    }

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

原创粉丝点击