【android-architecture】TODO-DataBinding

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

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值