Android官方DataBinding(十):双向绑定之基于InverseBindingAdapter的反向绑定

我给出一个简单例子,说明如何基于InverseBindingAdapter进行双向绑定中的反向绑定。
以一个经典的开发需求任务:下拉刷新。一般的下拉刷新,头部出现一个滚动的进度显示(ProgressBar)和一些文字提示,当下拉加载完毕后自动消失。
我写一个自定义view,继承自NestedScrollView,继承自NestedScrollView主要是为了利用NestedScrollView的下拉滚动事件。在这里面触发下拉刷新事件。
老规矩,先写一个model:
package zhangphil.test;import android.databinding.BaseObservable;import android.databinding.ObservableBoolean;/** * Created by Phil on 2017/8/25. */public class ViewModel extends BaseObservable {    public final ObservableBoolean isRefreshing = new ObservableBoolean();}




写布局,activity_main.xml:

<?xml version="1.0" encoding="utf-8"?>                                                                                                                                                                        




自定义的PhilView.java:

package zhangphil.test;import android.content.Context;import android.databinding.BindingAdapter;import android.databinding.InverseBindingAdapter;import android.databinding.InverseBindingListener;import android.support.v4.widget.NestedScrollView;import android.util.AttributeSet;import android.util.Log;/** * Created by Phil on 2017/8/25. */public class PhilView extends NestedScrollView {    private static final String TAG = "调试";    private static boolean isRefreshing = false;    private static InverseBindingListener mInverseBindingListener;    public PhilView(Context context, AttributeSet attrs) {        super(context, attrs);    }    @BindingAdapter(value = "refreshing", requireAll = false)    public static void setRefreshing(PhilView view, boolean refreshing) {        if (isRefreshing == refreshing) {            //防止死循环            Log.d(TAG, "重复设置");            return;        } else {            Log.d(TAG, "setRefreshing " + refreshing);            isRefreshing = refreshing;        }    }    @InverseBindingAdapter(attribute = "refreshing", event = "refreshingAttrChanged")    public static boolean getRefreshing(PhilView view) {        return isRefreshing;    }    @BindingAdapter(value = {"refreshingAttrChanged"}, requireAll = false)    public static void setRefreshingAttrChanged(PhilView view, final InverseBindingListener inverseBindingListener) {        Log.d(TAG, "setRefreshingAttrChanged");        if (inverseBindingListener == null) {            view.setRefreshingListener(null);        } else {            mInverseBindingListener = inverseBindingListener;            view.setRefreshingListener(mOnRefreshingListener);        }    }    @Override    protected void onScrollChanged(int x, int y, int oldx, int oldy) {        super.onScrollChanged(x, y, oldx, oldy);        if ((y < oldy) && y == 0) {            if (isRefreshing) {                Log.d(TAG, "正在刷新,请勿重复加载");                return;            } else {                longTimeTask();            }        }    }    public void setRefreshingListener(OnRefreshingListener listener) {        this.mOnRefreshingListener = listener;    }    public static abstract class OnRefreshingListener {        public void startRefreshing() {            isRefreshing = true;            mInverseBindingListener.onChange();        }        public void stopRefreshing() {            isRefreshing = false;            mInverseBindingListener.onChange();        }    }    private static OnRefreshingListener mOnRefreshingListener = new OnRefreshingListener() {        @Override        public void startRefreshing() {            super.startRefreshing();        }        @Override        public void stopRefreshing() {            super.stopRefreshing();        }    };    private void longTimeTask() {        new Thread(new Runnable() {            @Override            public void run() {                mOnRefreshingListener.startRefreshing();                try {                    //假设这里做了一个长时间的耗时操作                    Thread.sleep(5000);                } catch (InterruptedException e) {                    e.printStackTrace();                }                mOnRefreshingListener.stopRefreshing();            }        }).start();    }}




测试的MainActivity.java:

package zhangphil.test;import android.databinding.DataBindingUtil;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import zhangphil.test.databinding.ActivityMainBinding;public class MainActivity extends AppCompatActivity {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main);        ViewModel vm = new ViewModel();        binding.setModel(vm);    }}






代码运行结果初始化状态:

Android官方DataBinding(十):双向绑定之基于InverseBindingAdapter的反向绑定_第1张图片






当下拉时候:

Android官方DataBinding(十):双向绑定之基于InverseBindingAdapter的反向绑定_第2张图片

注意,代码有些小问题:只有先向上翻滚,再往下拉时候才会触发头部的刷新滚动提醒。然而这不是本文要解决的重点,随后的文章将改进。



附录:
1,《Android官方DataBinding简例(一)》链接:http://blog.csdn.net/zhangphil/article/details/77322530    
2,《Android官方DataBinding(二):动态数据更新notifyPropertyChanged》链接:http://blog.csdn.net/zhangphil/article/details/77328688   
3,《Android官方DataBinding(三):RecyclerView 使用ViewDataBinding更新数据》链接:http://blog.csdn.net/zhangphil/article/details/77367432  
4,《Android官方DataBinding(四):BindingAdapter》链接:http://blog.csdn.net/zhangphil/article/details/77374211 
5,《Android官方DataBinding(五):ObservableMap,ObservableArrayMap》链接:http://blog.csdn.net/zhangphil/article/details/77448933
6,《Android官方DataBinding(六): @= 操作符进行双向绑定》链接:http://blog.csdn.net/zhangphil/article/details/77454045 
7,《Android官方DataBinding(七):BindingMethods与BindingMethod》链接:http://blog.csdn.net/zhangphil/article/details/77479843 
8,《Android官方DataBinding(八):Lambda长表达式事件处理》链接:http://blog.csdn.net/zhangphil/article/details/77503013 
9,《Android官方DataBinding(九):反向绑定,View变化结果回写进数据模型中》链接:http://blog.csdn.net/zhangphil/article/details/77649256 

更多相关文章

  1. Android官方架构组件Navigation:大巧不工的Fragment管理框架
  2. Android 利用广播实现黑名单【指定号码】的短信的拦截 附源码下
  3. 看Google官方的Android开发文档的一些收获
  4. Android的TextView/EditText使用CharacterStyle&SpannableString
  5. Android 最全面试题汇总(问题+答案+详解链接)
  6. Android SDK官方下载地址及在线SDK网址
  7. Android官方教程翻译(2)——运行第一个程序
  8. 关于android的webview打开淘宝天猫链接问题
  9. android WebView 应用内点击超链接不调用系统浏览器

随机推荐

  1. 使用PHP反射机制获取函数文档
  2. PHP快速搭建一个简单的QQ机器人
  3. PHP实现驼峰命名和下划线命名互转
  4. PHP之你不得不知道的COOKIE含义及使用方
  5. PHP百钱百鸡问题(三种解题思路及答案)
  6. 如何用PHP代码生成金字塔
  7. PHP路由库FastRoute的使用教程
  8. PHP日期时间快速入门(图文详解)
  9. PHP简单实现路由Route功能
  10. PHP中你必须了解的4种Array函数