預(yù)期效果
類(lèi)似魅族便簽下拉顯示標(biāo)題的效果妓湘,加入了顯示隱藏的動(dòng)畫(huà)。
實(shí)現(xiàn)
1乌询、OnLayout中獲取第一個(gè)子view的高度
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
mChildLayout = (ViewGroup) getChildAt(0);
mTopChildView = mChildLayout.getChildAt(0);
topChildHeight = mTopChildView.getMeasuredHeight();
screenHeight = getMeasuredHeight();
offsetDistance = topChildHeight - screenHeight;
if (!mInited) {
mInited = true;
if (currentPage == PAGE_BOTTOM) {
scrollTo(0, topChildHeight);
}
}
}
2榜贴、dispatchTouchEvent中在ACTION_UP時(shí),通過(guò)getscrollY()即當(dāng)前滑動(dòng)的距離與header View高度的比較妹田,并設(shè)定一個(gè)閾值唬党,當(dāng)getscrollY()大于或小于該閾值時(shí)鹃共,顯示或隱藏header view。
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
if (isInIgnoredView(ev)) {
//往下傳遞
Log.e(TAG, "dispatchTouchEvent>>傳遞事件");
return super.dispatchTouchEvent(ev);
} else {
Log.e(TAG, "dispatchTouchEvent>>不傳遞事件");
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
isTouch = true;
downY = (int) ev.getY();
downTime = System.currentTimeMillis();
if (mScroller != null) {
mScroller.forceFinished(true);
mScroller = null;
}
break;
case MotionEvent.ACTION_MOVE:
break;
case MotionEvent.ACTION_UP:
isTouch = false;
upY = (int) ev.getY();
upTime = System.currentTimeMillis();
boolean isUpMove = upY - downY <= 0;//是否上劃
//用戶(hù)手指在屏幕上的時(shí)間
long duration = upTime - downTime;
//這里要確保點(diǎn)擊事件不失效
//we force stop scroll when touch down
//in some case we need to finish scroll up or down
if (currentPage == PAGE_TOP) {
//下面的判斷已經(jīng)能確定用戶(hù)是否往上滑
if (getScrollY() > offsetDistance) {
mScroller = new Scroller(mContext);
if (getScrollY() < (screenHeight * PERCENT + offsetDistance) && duration > TOUCH_DURATION) {
//基本可以無(wú)視
isPageChange = false;
scrollToTarget(PAGE_TOP);
} else if (getScrollY() > topChildHeight / 5) {
//切換到下界面 手勢(shì)是上劃且滑動(dòng)的距離大于一定值
isPageChange = true;
scrollToTarget(PAGE_BOTTOM);
} else if (getScrollY() <= topChildHeight / 5) {
isPageChange = false;
scrollToTarget(PAGE_TOP);
} else if (getScrollY() > topChildHeight) {
isPageChange = true;
currentPage = PAGE_BOTTOM;
}
return false;
}
} else {
if (getScrollY() < topChildHeight) {
mScroller = new Scroller(mContext);
if (getScrollY() < topChildHeight / 2) {
//切換到上界面
isPageChange = true;
scrollToTarget(PAGE_TOP);
} else {
isPageChange = false;
scrollToTarget(PAGE_BOTTOM);
}
return false;
}
}
break;
}
}
return super.dispatchTouchEvent(ev);
}
3驶拱、header view設(shè)置粘性滑動(dòng)(有沒(méi)有更貼切的名字霜浴?) 即scrollview的滑動(dòng)不跟隨手指的滑動(dòng),假如設(shè)置的比值為0.4蓝纲,那么手指滑動(dòng)10個(gè)像素阴孟,實(shí)際scrollview只滑動(dòng)了4個(gè)像素,類(lèi)似下拉刷新的那種下拉吃力的感覺(jué)驻龟。實(shí)現(xiàn)方法很簡(jiǎn)單温眉,在TouchEvent中,通過(guò)scrollBy()方法實(shí)現(xiàn)scrollview的滑動(dòng)翁狐,并返回true类溢,表示scrollview消費(fèi)了該次事件。
@Override
public boolean onTouchEvent(MotionEvent ev) {
if (isInIgnoredView(ev)) {
Log.e(TAG, "onTouchEvent>>不消費(fèi)事件");
return false;
} else {
Log.e(TAG, "onTouchEvent>>消費(fèi)事件");
currentY = (int) ev.getY();
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
lastY = (int) ev.getY();
break;
case MotionEvent.ACTION_MOVE:
int moveY = currentY - lastY;
lastY = currentY;
if (currentPage == PAGE_BOTTOM) {
if (getScrollY() <= topChildHeight) {
//下拉
scrollBy(0, (int) (-moveY * mFraction));
return true;
} else {
return super.onTouchEvent(ev);
}
} else {
return super.onTouchEvent(ev);
}
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
break;
}
return super.onTouchEvent(ev);
}
}
4露懒、動(dòng)畫(huà)闯冷。動(dòng)畫(huà)使用了屬性動(dòng)畫(huà),這里就不多介紹了懈词。
效果圖
gif太大..簡(jiǎn)書(shū)上傳不了.
偷偷懶蛇耀,移步github看效果
GitHub
歡迎star...歡迎吐槽...