目前框架支持的屬性回調有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<StudentModule> mMediator;
@Overrideprotected int getLayoutId() {
return R.layout.ac_test_double_bind;}
@Overrideprotected void onInit(Context context, Bundle savedInstanceState) {mBt_changeProperty.setText(
"click this to change property");mBt_temp.setVisibility(View.GONE);mMediator = DataMediatorFactory.createDataMediator(StudentModule.class);mMediator.addDataMediatorCallback(
new DataMediatorCallback<StudentModule>() {
@Overridepublic 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<RecyclerListBindModule> mBinder;
private TestRecyclerListAdapter<StudentModule> mAdapter;
@Overrideprotected int getLayoutId() {
return R.layout.ac_test_recycler_list_bind;}
@Overrideprotected void onInit(Context context, Bundle savedInstanceState) {initAdapter();mBinder = DataMediatorFactory.createBinder(RecyclerListBindModule.class);onBindListItems(mBinder);}
@OnClick(R.id.bt_add)
public void onClickAddItem(View v){mBinder.getDataProxy().beginStudentsEditor().add(
0, createItem());}
@OnClick(R.id.bt_add_all)
public void onClickAddItems(View v){List<StudentModule> list = createItems();mBinder.getDataProxy().beginStudentsEditor().addAll(list);}
@OnClick(R.id.bt_remove)
public void onClickRemoveItem(View v){mBinder.getDataProxy().beginStudentsEditor().remove(
0);}
@OnClick(R.id.bt_replace)
public void onClickReplaceItem(View v){mBinder.getDataProxy().setStudents(createItems());}
protected void onBindListItems(Binder<RecyclerListBindModule> mBinder) {mBinder.bindList(RecyclerListBindModule.PROP_students,mAdapter);}
protected void initAdapter() {mRv.setLayoutManager(
new LinearLayoutManager(
this));mRv.setAdapter(mAdapter =
new TestRecyclerListAdapter<StudentModule>(R.layout.item_test_recycler_list,
null) {
@Overrideprotected 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;}
@NonNullprivate static List<StudentModule> createItems() {List<StudentModule> list =
new ArrayList<>();
final int count = sRan.nextInt(
10) +
1;
for (
int i =
0 ; i< count ; i++){list.add(createItem());}
return list;}
private static abstract class TestRecyclerListAdapter<T extends ISelectable>extends QuickRecycleViewAdapter<T> implementsBaseListPropertyCallback.IItemManager<T> {
public TestRecyclerListAdapter(int layoutId, List<T> mDatas) {
super(layoutId, mDatas);}
@Overridepublic void addItems(List<T> items) {getAdapterManager().addItems(items);}
@Overridepublic void addItems(int index, List<T> items) {getAdapterManager().addItems(index, items);}
@Overridepublic void removeItems(List<T> items) {getAdapterManager().removeItems(items);}
@Overridepublic void replaceItems(List<T> items) {getAdapterManager().replaceAllItems(items);}
@Overridepublic 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<TestBindModule> mDm;
private Set<Integer> mIndexes =
new HashSet<>();
@Overrideprotected int getLayoutId() {
return R.layout.ac_test_sparse_array;}
@Overrideprotected void onInit(Context context, Bundle savedInstanceState) {mDm = DataMediatorFactory.createDataMediator(TestBindModule.class);mDm.addDataMediatorCallback(DataMediatorCallback.createForSparse(TestBindModule.PROP_cityData2.getName(),
new CallbackImpl()));}
@OnClick(R.id.bt_put)
public void onClickPut(View v){
final StudentModule stu = createStu(-
1);mDm.getDataProxy().beginCityData2Editor().put((
int)stu.getId(), stu).end();}
@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");}}
@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<TestBindModule>{
@Overridepublic 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 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 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(); 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);}
@Overridepublic void onPropertyApplied(TestBindModule data, Property prop, Object value) {
final String msg =
"value = " + value;Logger.i(TAG ,
"onPropertyApplied", msg);setLogText(
"onPropertyApplied", msg);}}
}
復制代碼想要體驗最新的特性 ?
請到github/data-mediator體驗。 如果覺得不錯,請star支持下項目哈。
歡迎大家star, fork,contribute ,提issue. 它會越來越棒。
Thanks for reading !
技術源于分享!
總結
以上是生活随笔為你收集整理的Data-Mediator专题之属性回调的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。