博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Data-Mediator专题之属性回调
阅读量:6437 次
发布时间:2019-06-23

本文共 10947 字,大约阅读时间需要 36 分钟。

目前框架支持的属性回调有3种

  • 1,默认的属性回调 含义: 其实就是某个属性变化了, 通知你的意思
  • 2, List属性回调 含义: 就是监听List属性的 增删改。
  • 3, SparseArray属性回调。 含义: 就是监听SparseArray属性的 增删改。

详解

  • 属性回调

  • 实际场景:

    • 在工作中,有的时候我们想监听某些数据/ui 的变化。以完成统计功能, 以前在项目中遇到过。
      比如新闻类的ui, 顶部有很多tab, 下面是数据流列表。 这时候有这样一个需求:
      要求用户点击了哪个item,属于哪个tab. 什么类型, 在列表中的索引, 这个时候我发现,搞统计还是挺麻烦的。
      即使最后我设计了一套通用的框架, 还是感觉不完美。
    • 所以后面我想到了数据中介者data-mediator这个框架. 后面会支持这些更加复杂的功能。
  • 属性回调,不一定非要绑定到view的属性上(比如setText, setTextColor, setBackground等等)。 它也可以是事件点击的属性, 后面也会支持。

    换句话说, 以后它可以做很多后台的一些操作。

  • 回归正题, 如何使用属性回调?

    在demo中有这样一个简单的例子。

public class TestPropertyChangeActivity extends BaseActivity {          @BindView(R.id.tv_desc)       TextView mTv_desc;          @BindView(R.id.bt_set_text_on_TextView)       Button mBt_changeProperty;       @BindView(R.id.bt_set_text_on_mediator)       Button mBt_temp;          DataMediator
mMediator; @Override protected int getLayoutId() { return R.layout.ac_test_double_bind; } @Override protected void onInit(Context context, Bundle savedInstanceState) { mBt_changeProperty.setText("click this to change property"); mBt_temp.setVisibility(View.GONE); //为数据模型创建 中介者。 mMediator = DataMediatorFactory.createDataMediator(StudentModule.class); //添加属性callback mMediator.addDataMediatorCallback(new DataMediatorCallback
() { @Override public void onPropertyValueChanged(StudentModule data, Property prop, Object oldValue, Object newValue) { Logger.w("TestPropertyChangeActivity","onPropertyValueChanged","prop = " + prop.getName() + " ,oldValue = " + oldValue + " ,newValue = " + newValue); //改变文本 mTv_desc.setText(String.valueOf(newValue)); } }); mMediator.getDataProxy().setName("heaven7"); } @OnClick(R.id.bt_set_text_on_TextView) public void onClickSetTextOnTextView(View v){ mMediator.getDataProxy().setName("time: " + System.currentTimeMillis()); } }复制代码

仅仅,属性改变的时候改变一下文本。很简单吧。

  • List属性编辑器

  • 当一个属性是List类型时,会自动 生成beginXXXEditor的方法返回该编辑器, 它可以方便的操作list数据。 数据模型和代理均有。其中XXX是属性的名称
  • 一般用于绑定列表控件,比如android RecyclerView. 下面是一个demo:
public class TestRecyclerListBindActivity extends BaseActivity {            private static final Random sRan = new Random();                @BindView(R.id.rv)        RecyclerView mRv;                private Binder
mBinder; private TestRecyclerListAdapter
mAdapter; @Override protected int getLayoutId() { return R.layout.ac_test_recycler_list_bind; } @Override protected void onInit(Context context, Bundle savedInstanceState) { //初始化adapter     initAdapter(); //创建binder     mBinder = DataMediatorFactory.createBinder(RecyclerListBindModule.class); //绑定列表     onBindListItems(mBinder); } //添加一个item @OnClick(R.id.bt_add) public void onClickAddItem(View v){ mBinder.getDataProxy().beginStudentsEditor() .add(0, createItem()); } //添加一组items @OnClick(R.id.bt_add_all) public void onClickAddItems(View v){ List
list = createItems(); mBinder.getDataProxy().beginStudentsEditor() .addAll(list); } //删除一个 item @OnClick(R.id.bt_remove) public void onClickRemoveItem(View v){ mBinder.getDataProxy().beginStudentsEditor() .remove(0); } //替换所有items @OnClick(R.id.bt_replace) public void onClickReplaceItem(View v){ mBinder.getDataProxy().setStudents(createItems()); } protected void onBindListItems(Binder
mBinder) { //通用的绑定方法. 这里用于绑定列表     mBinder.bindList(RecyclerListBindModule.PROP_students, mAdapter); } protected void initAdapter() { mRv.setLayoutManager(new LinearLayoutManager(this)); mRv.setAdapter(mAdapter = new TestRecyclerListAdapter
( R.layout.item_test_recycler_list, null) { @Override protected void onBindData(Context context, int position, StudentModule item, int itemLayoutId, ViewHelper helper) { helper.setText(R.id.tv_name, item.getName()) .setText(R.id.tv_age, ""+item.getAge()); } }); } private static StudentModule createItem(){ StudentModule data = DataMediatorFactory.createData(StudentModule.class); data.setAge(sRan.nextInt(10001)); data.setName("google__" + sRan.nextInt(100)); return data; } @NonNull private static List
createItems() { List
list = new ArrayList<>(); //just mock data final int count = sRan.nextInt(10) + 1; for (int i =0 ; i< count ; i++){ list.add(createItem()); } return list; } private static abstract class TestRecyclerListAdapter
extends QuickRecycleViewAdapter
implements BaseListPropertyCallback.IItemManager
{ public TestRecyclerListAdapter(int layoutId, List
mDatas) { super(layoutId, mDatas); } @Override public void addItems(List
items) { //增加 getAdapterManager().addItems(items); } @Override public void addItems(int index, List
items) { //增加 getAdapterManager().addItems(index, items); } @Override public void removeItems(List
items) { //删除 getAdapterManager().removeItems(items); } @Override public void replaceItems(List
items) { //替换所有 getAdapterManager().replaceAllItems(items); } @Override public void onItemChanged(int index, T oldItem, T newItem) { //改变元素 getAdapterManager().setItem(index, newItem); } } }复制代码

复杂么? 不复杂,第一步绑定了列表。然后改变数据的时候回调到了BaseListPropertyCallback.IItemManager

SparseArray属性编辑器

  • 当属性类型是SparseArray时,会自动生成SparseArray属性编辑器: beginXXXEdiator, XXX是属性名称.
  • 下面是一个示例程序:
public class TestSparseArrayActivity extends BaseActivity {  private static final String TAG = "TestSparseArray";  @BindView(R.id.tv_sa)  TextView mTv_sa;  private DataMediator
mDm; private Set
mIndexes = new HashSet<>(); @Override protected int getLayoutId() { return R.layout.ac_test_sparse_array; } @Override protected void onInit(Context context, Bundle savedInstanceState) { mDm = DataMediatorFactory.createDataMediator(TestBindModule.class); // 这里直接用属性回调。也可以用binder.bind(String property, SparseArrayPropertyCallback
callback)方法 mDm.addDataMediatorCallback(DataMediatorCallback.createForSparse( TestBindModule.PROP_cityData2.getName(), new CallbackImpl())); } // put 操作 @OnClick(R.id.bt_put) public void onClickPut(View v){ final StudentModule stu = createStu(-1); mDm.getDataProxy().beginCityData2Editor() .put((int)stu.getId(), stu) .end(); } // 移除操作(通过key) @OnClick(R.id.bt_remove_key) public void onClickRemoveByKey(View v){ if(!mIndexes.isEmpty()){ final Integer index = mIndexes.iterator().next(); mDm.getDataProxy().beginCityData2Editor() .remove(index); mIndexes.remove(index); }else{ mTv_sa.setText(""); Logger.w(TAG , "onClickRemoveByKey", "already empty"); } } // 移除操作(通过value) @OnClick(R.id.bt_remove_value) public void onClickRemoveByValue(View v){ if(!mIndexes.isEmpty()){ final Integer index = mIndexes.iterator().next(); mDm.getDataProxy().beginCityData2Editor() .removeByValue(createStu(index)); mIndexes.remove(index); }else{ mTv_sa.setText(""); Logger.w(TAG , "onClickRemoveByValue", "already empty"); } } //清空操作 @OnClick(R.id.bt_clear) public void onClickClear(View v){ if(!mIndexes.isEmpty()){ mDm.getDataProxy().beginCityData2Editor().clear(); mIndexes.clear(); }else{ mTv_sa.setText(""); Logger.w(TAG , "onClickClear", "already empty"); } } private StudentModule createStu(int index) { if(index < 0){ index = new Random().nextInt(5); } mIndexes.add(index); return DataMediatorFactory.createData(StudentModule.class) .setId(index).setName("google_" + index).setAge(index); } private void setLogText(String method, String msg){ mTv_sa.setText(method + ": \n " + msg + "\n\n now is: \n" + mDm.getData().getCityData2().toString()); } private class CallbackImpl implements SparseArrayPropertyCallback
{ @Override public void onEntryValueChanged(TestBindModule data, Property prop, Integer key, Object oldValue, Object newValue) { final String msg = "oldValue = " + oldValue + " ,newValue = " + newValue; Logger.i(TAG , "onEntryValueChanged", msg); setLogText("onEntryValueChanged", msg); } @Override //添加key-value public void onAddEntry(TestBindModule data, Property prop, Integer key, Object value) { final String msg = "key = " + key + " ,value = " + value; Logger.i(TAG , "onAddEntry", msg); setLogText("onAddEntry", msg); } @Override //移除key-value public void onRemoveEntry(TestBindModule data, Property prop, Integer key, Object value) { final String msg = "key = " + key + " ,value = " + value; Logger.i(TAG , "onRemoveEntry", msg); setLogText("onRemoveEntry", msg); } @Override //清空 public void onClearEntries(TestBindModule data, Property prop, Object entries) { final String msg = entries.toString(); //here entries is SparseArray Logger.i(TAG , "onClearEntries", msg); setLogText("onClearEntries", msg); } @Override //一般的属性改变 public void onPropertyValueChanged(TestBindModule data, Property prop, Object oldValue, Object newValue) { final String msg = "oldValue = " + oldValue + " ,newValue = " + newValue; Logger.i(TAG , "onPropertyValueChanged", msg); setLogText("onPropertyValueChanged", msg); } @Override public void onPropertyApplied(TestBindModule data, Property prop, Object value) { final String msg = "value = " + value; Logger.i(TAG , "onPropertyApplied", msg); setLogText("onPropertyApplied", msg); } }}复制代码

想要体验最新的特性 ?

请到体验。 如果觉得不错,请star支持下项目哈。

欢迎大家star, fork,contribute ,提issue. 它会越来越棒。

Thanks for reading !

技术源于分享!

转载地址:http://enkwo.baihongyu.com/

你可能感兴趣的文章
ARKit从入门到精通(1)-ARKit初体验
查看>>
debug
查看>>
配置文件git config介绍
查看>>
IIS7的应用程序池详细解析
查看>>
java类路径classpath和包
查看>>
Information Retrieval 倒排索引 学习笔记
查看>>
【Git】Git-add之后-忽略部分文件的方法
查看>>
JQuery使用trigger模拟触发selete的选择change事件
查看>>
连表更新数据
查看>>
tensorflow笔记1:基础函数、embedding_lookup
查看>>
如何用phpmyadmin导入大容量.sql文件,直接使用cmd命令进行导入
查看>>
BZOJ4133 : Answer的排队
查看>>
基于Centos搭建 Mono 开发环境
查看>>
算法题:福尔摩斯的约会
查看>>
Oralce sql (+) 补充
查看>>
hdu 2665 划分树
查看>>
laravel中的plicy授权方法:
查看>>
基于R进行相关性分析--转载
查看>>
常用 cdn
查看>>
tomcat8 管理页面403 Access Denied的解决方法
查看>>