viewDragHelper仿qq側(cè)滑的效果
學(xué)習(xí)資料 《android群英傳》
老規(guī)矩先上圖

滑動(dòng)的本質(zhì)就是移動(dòng)一個(gè)view,改變其當(dāng)前所在的位置,它的原理與動(dòng)畫效果實(shí)現(xiàn)非常相似。都是通過不斷的改變view的坐標(biāo)來(lái)實(shí)現(xiàn)這一效果。
所以就必須監(jiān)聽用戶觸摸的事件,并傳入坐標(biāo),動(dòng)態(tài)的不斷的改變坐標(biāo),從而實(shí)現(xiàn)view跟隨用戶的觸摸滑動(dòng)而滑動(dòng)。
先學(xué)習(xí)viewDragHelper的基本用法
一,初始化ViewDragHelper
public DragView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initView();
}
private void initView() {
viewDragHelper=ViewDragHelper.create(this,callback);
}
二,重寫攔截事件方法
觸摸事件的方法
//攔截事件
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
return viewDragHelper.shouldInterceptTouchEvent(ev);
}
//觸摸事件
@Override
public boolean onTouchEvent(MotionEvent event) {
viewDragHelper.processTouchEvent(event);
return true;
}
只要這三步,實(shí)現(xiàn)的是觸摸滑動(dòng),如圖:
三,處理computeScollege()
四,處理回調(diào)Callback();關(guān)鍵部分
public ViewDragHelper.Callback callback=
new ViewDragHelper.Callback() {
//tryCaptureView如何返回ture則表示可以捕獲該view,你可以根據(jù)傳入的第一個(gè)view參數(shù)決定哪些可以捕獲
@Override
public boolean tryCaptureView(View child, int pointerId) {
return true;
}
//處理水平滑動(dòng),返回左邊的坐標(biāo),可以進(jìn)行計(jì)算,layout方法進(jìn)行設(shè)置顯示的位置
@Override
public int clampViewPositionHorizontal(View child, int left, int dx) {
return left;
}
//處理垂直滑動(dòng)和處理水平的思想一樣
@Override
public int clampViewPositionVertical(View child, int top, int dy) {
return top;
}
五,onViewRelease方法,拖動(dòng)結(jié)束后進(jìn)行調(diào)用
六,通過以上學(xué)習(xí),實(shí)現(xiàn)一個(gè)qq側(cè)滑功能如圖

側(cè)滑其實(shí)和view滑動(dòng)原理是一樣的
我把自己理解的需要注意和重點(diǎn)分為以下幾點(diǎn);
一,側(cè)滑其實(shí)就是兩個(gè)view,他們的圖層不同,在xml布局中需要把菜單和主界面區(qū)分好,如圖:activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<com.example.a11059.myview.DragView xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:text="dsdsd"
android:gravity="center"
android:background="@color/colorPrimary"
android:layout_width="300dp"
android:layout_height="match_parent" />
<TextView
android:text="dsdsd"
android:layout_gravity="center"
android:background="@color/colorAccent"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</com.example.a11059.myview.DragView>
就這幾行代碼非常簡(jiǎn)單,兩個(gè)TextView,一個(gè)作為主界面,一個(gè)作為菜單。
菜單在主界面的前面,所以這兩個(gè)圖層在手機(jī)上會(huì),顯示第二個(gè)TextView。
當(dāng)它進(jìn)行滑動(dòng)時(shí),(這里只允許進(jìn)行水平滑動(dòng))底層的Textview就會(huì)顯示出來(lái)。
//拖動(dòng)結(jié)束后調(diào)用
// @Override
// public void onViewReleased(View releasedChild, float xvel, float yvel) {
// super.onViewReleased(releasedChild, xvel, yvel);
// if (mMainView.getLeft()<500){
// //關(guān)閉菜單
// //相當(dāng)
// viewDragHelper.smoothSlideViewTo(mMainView,0,0);
// //這句相當(dāng)于重繪
// ViewCompat.postInvalidateOnAnimation(DragView.this);
// }else {
// //把mMainView設(shè)置到固定的位置
// viewDragHelper.smoothSlideViewTo(mMainView,300,0);
// ViewCompat.postInvalidateOnAnimation(DragView.this);
// }
// }
二
拖動(dòng)后的回調(diào),這里需要把上層的TextView進(jìn)行限制,不然Textview的位置就會(huì)隨著手指拖動(dòng)亂跑。這里限制當(dāng)主界面的左側(cè)小于500,關(guān)閉菜單,其實(shí)就是把主界面覆蓋上去。
三
mMainView 和mMenuView通過onFinishInflate方法創(chuàng)建實(shí)例
//加載布局文件后調(diào)用
@Override
protected void onFinishInflate() {
super.onFinishInflate();
mMenuView=getChildAt(0);
mMainView=getChildAt(1);
}
如有錯(cuò)誤或異議,歡迎指正留言。