最近研究Android list(譬如RecyclerView)下拉动效(譬如下拉刷新)的实现方式。看到一个不错的开源项目,实现类似iPhone上的Chrome下拉更多操作。详细研究了实现方式,记录如下。
1.开源代码地址
2.如何使用
以RecyclerView作为list为例,其他情况类似
(1)Layout:
在RecyclerView外层套一层Layout-ChromeLikeSwipeLayout:
<com.asha.ChromeLikeSwipeLayout
app:layout_behavior="@string/appbar_scrolling_view_behavior"
android:id="@+id/chrome_like_swipe_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:background="#fff5d0"
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
</android.support.v7.widget.RecyclerView>
</com.asha.ChromeLikeSwipeLayout>
(2)Java:
配置ChromeLikeSwipeLayout:
ChromeLikeSwipeLayout chromeLikeSwipeLayout = (ChromeLikeSwipeLayout) findViewById(R.id.chrome_like_swipe_layout);
ChromeLikeSwipeLayout.makeConfig()
.addIcon(R.drawable.selector_icon_add)
.addIcon(R.drawable.selector_icon_refresh)
.addIcon(R.drawable.selector_icon_refresh)
.addIcon(R.drawable.selector_icon_close)
.radius(dp2px(35))
.gap(dp2px(5))
.circleColor(0xFF11CCFF)
.listenItemSelected(new ChromeLikeSwipeLayout.IOnItemSelectedListener() {
@Override
public void onItemSelected(int index) {
Toast.makeText(RecyclerViewActivity.this, "onItemSelected:" + index, Toast.LENGTH_SHORT).show();
}
})
.setTo(chromeLikeSwipeLayout);
3.缺陷
(1)无法实现list中一拉到底
(2)安卓的list弹性效果使得下拉灵敏度下降
4.实现原理
(1)MotionEvent的分发和消费
ChromeLikeSwipeLayout拦截逻辑:
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
//Log.d(TAG,"onInterceptTouchEvent:" + event);
if (!mEnabled) return false;
if ( mAnimationStarted ) return false;
if ( canChildDragDown(mTouchManager.event2Point(event)) ) return false;
return mTouchManager.onFeedInterceptEvent(event);
}
private boolean canChildDragDown(PointF pointF){
ensureTarget();
if ( mTarget instanceof TouchAlwaysTrueLayout )
return ((TouchAlwaysTrueLayout) mTarget).canChildDragDown(pointF);
else return ViewCompat.canScrollVertically(mTarget,-1);
}
mTarget即child view的RecyclerView,通过API ViewCompat.
canScrollVertically
()判断当前RecyclerView是否还能够向上滑动,如果还能,则不拦截MotionEvent,交给child处理;如果不能,由自己处理。另一个成员变量mChromeLikeLayout是下拉出来的动效区。
TouchManager.onFeedInterceptEvent():
public boolean o