测试的MainActivity.java:
package zhangphil.test; import android.databinding.DataBindingUtil; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.Log; import android.view.GestureDetector; import android.view.MotionEvent; import android.view.View; import zhangphil.test.databinding.ActivityMainBinding; public class MainActivity extends AppCompatActivity { private final String TAG = "MainActivity调试"; private ViewModel mViewModel; private ActivityMainBinding binding; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); final GestureDetector mGestureDetector = createGestureDetector(); binding = DataBindingUtil.setContentView(this, R.layout.activity_main); mViewModel = new ViewModel(); binding.setModel(mViewModel); binding.philview.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View view, MotionEvent motionEvent) { mGestureDetector.onTouchEvent(motionEvent); return false; } }); } private GestureDetector createGestureDetector() { // mGestureDetector用于监测用户在手机屏幕上的上滑和下滑事件。 GestureDetector mGestureDetector = new GestureDetector(this, new GestureDetector.SimpleOnGestureListener() { @Override public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { //处于顶部且用户再下拉 if ((distanceY < 0) && (binding.philview.getScrollY() == 0)) { if (mViewModel.isRefreshing.get()) { Log.d(TAG, "加载中,请勿重复加载"); } else { Log.d(TAG, "开始下拉刷新..."); //执行下拉刷新/加载更多事务 loadMore(); } } return super.onScroll(e1, e2, distanceX, distanceY); } }); return mGestureDetector; } private void loadMore() { new Thread(new Runnable() { @Override public void run() { //通过设置布尔值改变View mViewModel.isRefreshing.set(true); try { //假设这里做了一个长时间的耗时操作 Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } //通过设置布尔值改变View mViewModel.isRefreshing.set(false); } }).start(); } } 关键的PhilView.java: package zhangphil.test; import android.content.Context; import android.databinding.InverseBindingListener; import android.databinding.InverseBindingMethod; import android.databinding.InverseBindingMethods; import android.support.v4.widget.NestedScrollView; import android.util.AttributeSet; import android.util.Log; /** * Created by Phil on 2017/9/1. */ @InverseBindingMethods({@InverseBindingMethod(type = PhilView.class, attribute = "refreshing", event = "refreshingAttrChanged")}) public class PhilView extends NestedScrollView { private String TAG = "调试"; private boolean isRefreshing = false; public PhilView(Context context, AttributeSet attrs) { super(context, attrs); } public void setRefreshing(boolean refreshing) { if (isRefreshing == refreshing) { //防止死循环 Log.d(TAG, "重复设置"); return; } else { Log.d(TAG, "setRefreshing " + refreshing); isRefreshing = refreshing; } } public boolean getRefreshing() { return isRefreshing; } public void setRefreshingAttrChanged(InverseBindingListener inverseBindingListener) { if (inverseBindingListener == null) { Log.e(TAG, "InverseBindingListener为空!"); } else { Log.d(TAG, "setRefreshingAttrChanged"); inverseBindingListener.onChange(); } } } 对比本篇文章的PhilView.java代码和附录十、十一的异同,最关键的地方是用InverseBindingMethod重新实现。InverseBindingMethod在注解定义的地方,有几点需要特别注意: (1)InverseBindingMethod里面的event事件不是必须的,如果在InverseBindingMethod里面没有定义,那么Android系统自己会自动匹配查找。Android系统自动匹配查找的原则:根据定义的attribute值后面追加”AttrChanged”形成默认方法名进行匹配查找。比如,如果自己定义了attribute=”xxx”,那么Android系统自动会匹配查找xxxAttrChanged方法,该方法是set开头,那么就最终变成:setXxxAttrChanged (2)如果开发者在event里面自己随意定义了一个方法名,那么必须严格一致确保类里面有这个方法,比如,如果用户在InverseBindingMethod的event里面任意定义了一个方法“abcdefg”,那么必须在该注解类有一个同名方法如setAbcdefg(),然后在这里面调用InverseBindingListener的onChange()。 (3)InverseBindingMethod中定义的attribute值,即为开发者想要和xml布局里面的app:xxx绑定的值。 (4)如果基于InverseBindingMethod,在绑定注解类里面get和set方法,后面的方法名即为attribute的值,举例,如果,attribute=”xxx”,那么set和get方法即为setXxx()和getXxx()。 附录: 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 10,《Android官方DataBinding(十):双向绑定之基于InverseBindingAdapter的反向绑定》链接:http://blog.csdn.net/zhangphil/article/details/77767513 11,《Android官方DataBinding(十一):对于双向绑定之反向绑定的改进和简化》链接:http://blog.csdn.net/zhangphil/article/details/77772671