這里接著上一篇文章 通過(guò)NestedScrolling實(shí)現(xiàn)RecyclerView拖拽回彈效果,做了一些優(yōu)化并增加滑動(dòng)動(dòng)畫(huà)效果秸谢。
首先看下我們要實(shí)現(xiàn)的效果:
功能很簡(jiǎn)單纱新,需要給RecyclerView做兩個(gè)擴(kuò)展:
一由捎、增加拖拽功能
拖拽功能在上一章已經(jīng)做了介紹商叹,但有幾點(diǎn)需要注意:
1燕刻、拖拽范圍限制
@Override
public void scrollTo(int x, int y) {
if (x < 0) {
x = 0;
} else if (x > maxWidth * 2) {
x = maxWidth * 2;
}
super.scrollTo(x, y);
}
2、慣性問(wèn)題:當(dāng)RecyclerView在界面之內(nèi)交給它自己慣性滑動(dòng)
@Override
public boolean onNestedPreFling(View target, float velocityX, float velocityY) {
// 當(dāng)RecyclerView在界面之內(nèi)交給它自己慣性滑動(dòng)
return getScrollX() != maxWidth;
}
3剖笙、快速左右連續(xù)滑動(dòng)會(huì)出現(xiàn)錯(cuò)位問(wèn)題卵洗,需要要限制處理
@Override
public void onNestedPreScroll(View target, int dx, int dy, int[] consumed) {
...
// 限制錯(cuò)位問(wèn)題
if (dx > 0 && getScrollX() > maxWidth && !ViewCompat.canScrollHorizontally(target, -1)) {
scrollTo(maxWidth, 0);
}
if (dx < 0 && getScrollX() < maxWidth && !ViewCompat.canScrollHorizontally(target, 1)) {
scrollTo(maxWidth, 0);
}
}
4、動(dòng)畫(huà)問(wèn)題:和慣性同樣判斷什么時(shí)候開(kāi)啟動(dòng)畫(huà)
@Override
public void onStopNestedScroll(View target) {
mParentHelper.onStopNestedScroll(target);
// 如果不在RecyclerView滑動(dòng)范圍內(nèi)
if(maxWidth != getScrollX()){
startAnimation(new ProgressAnimation());
}
}
5弥咪、多點(diǎn)觸控問(wèn)題:在動(dòng)畫(huà)執(zhí)行時(shí)期不處理事件
@Override
public boolean onStartNestedScroll(View child, View target, int nestedScrollAxes) {
return target instanceof RecyclerView && !isRunAnim;
}
mChildView.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
// 保證動(dòng)畫(huà)狀態(tài)中 子view不能滑動(dòng)
return isRunAnim;
}
});
二过蹂、根據(jù)拖拽距離繪制橢圓
1、首先要保證查看更多按鈕一直在最右邊顯示
有兩個(gè)思路:
(1)自定義擴(kuò)展得View寬度固定聚至,查看更多按鈕位置隨著滑動(dòng)距離變化酷勺。
(2)自定義擴(kuò)展的View寬度隨著滑動(dòng)距離變化,查看更多按鈕右居中顯示扳躬。
2脆诉、滑動(dòng)顯示出更多按鈕后,開(kāi)始繪制橢圓贷币。
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
mPath.reset();
float marginTop = (mHeight - mLayoutHeight) / 2;
// 右上角x坐標(biāo)击胜、右上角y坐標(biāo)
mPath.moveTo(mMove - mLayoutWidth, marginTop);
// 左邊弧形x坐標(biāo)、左邊弧形y坐標(biāo)役纹、右下角x坐標(biāo)偶摔、右下角y坐標(biāo)
mPath.quadTo(0, mHeight / 2, mMove - mLayoutWidth, mLayoutHeight + marginTop);
canvas.drawPath(mPath, mBackPaint);
}
demo地址:https://github.com/eatdefecat/DZStickyNavLayout
最后還有個(gè)問(wèn)題很困擾我,如果沒(méi)有給RecyclerView中itemView設(shè)置可以點(diǎn)擊字管,onStartNestedScroll會(huì)執(zhí)行2次啰挪,并且onNestedPreScroll方法里返回的dx或者dy會(huì)變得很大,實(shí)現(xiàn)不了阻力效果嘲叔。如果有知道這是什么原因引起的歡迎在文章下面留言亡呵。