ViewDragHelper的使用

首先繼承:

java.lang.Object
↳ android.support.v4.widget.ViewDragHelper
直接父類是Object。
類概述

ViewDragHelper is a utility class for writing custom ViewGroups. It offers a number of useful operations and state tracking for allowing a user to drag and reposition views within their parent ViewGroup.
他是一個編寫自定義ViewGroup的工具類,本省提供了許多有用的方法和狀態允許用戶去拖拽和繪製他們在父ViewGroup中的軌跡和位置。
Nested Classes(嵌套類)

ViewDragHelper.Callback
A Callback is used as a communication channel with the ViewDragHelper back to the parent view using it.
一個回調是用作ViewDragHelper和他的父view的通信的接口。
ViewDragHelper不能通過new來創建對象,它只能通過一個靜態方法ViewDragHelper.create()來構造一個對象。
這裏寫圖片描述
讓我們在來看下需要用到的裏面的幾個方法:

public boolean tryCaptureView(View child, int pointerId) {}
public int getViewHorizontalDragRange(View child) {}
public int clampViewPositionHorizontal(View child, int left, int dx) {}
public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy) {}
public void onViewReleased(View releasedChild, float xvel, float yvel) {}
上面的幾個方法,會在代碼中有詳細的註釋,在這裏只是看下我們需要重寫的方法
首先先看主要的佈局

<?xml version="1.0" encoding="utf-8"?>
<com.example.administrator.viewdragerhelper.DrayLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal"
    tools:context="com.example.administrator.viewdragerhelper.MainActivity">

    <LinearLayout
        android:id="@+id/left_linear"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="horizontal"
        android:background="#33ffee" />

    <LinearLayout
        android:id="@+id/main_linear"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="horizontal"
        android:background="#00ff00" />
</com.example.administrator.viewdragerhelper.DrayLayout>

下面來看自定義DragLayout

package com.example.administrator.viewdragerhelper;

import android.content.Context;
import android.support.v4.widget.ViewDragHelper;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.LinearLayout;

/**
 * Created by Administrator on 2016/4/8.
 */
public class DrayLayout extends FrameLayout {

    private ViewDragHelper mDragHelper;
    private MyCallback mCallback;
    private LinearLayout mMainLinear;   //主佈局
    private LinearLayout mLeftLinear;   //左側佈局
    private int mHeight;
    private int mWidth;
    private int mRange; //左邊佈局拖拽的位置

    public DrayLayout(Context context) {
        super(context);
        init();
    }

    public DrayLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public DrayLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void init(){
        mCallback = new MyCallback();
        mDragHelper = ViewDragHelper.create(this,1.0f,mCallback);
    }

    class MyCallback extends ViewDragHelper.Callback{


        @Override
        public boolean tryCaptureView(View child, int pointerId) {
            //返回true代表的是ViewGroup中的子控件可以隨意拖動
            return true;
        }

        @Override
        public int clampViewPositionHorizontal(View child, int left, int dx) {
            //如果當前佈局是主佈局
            if(child == mMainLinear){
                if(left<0){
                    return 0;  //主佈局不能向左邊拖拽
                }else if(left > mRange){
                    return mRange;
                }
            }
            //返回子控件拖動後左側的位置
            return left;
        }

        @Override
        public int clampViewPositionVertical(View child, int top, int dy) {
            //返回子控件拖動後頂部的位置
            return 0;
        }

        @Override
        public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy) {
            super.onViewPositionChanged(changedView, left, top, dx, dy);
            int newLeft = left;

            if (changedView == mLeftLinear) {
            newLeft = mMainLinear.getLeft() + dx;
            }

            newLeft = fixLeft(newLeft);
            //當左邊佈局位置發生變化之後,拖拽左邊佈局也可以讓主佈局往回移動
            if(changedView == mLeftLinear){
                mLeftLinear.layout(0,0,mWidth,mHeight);
                mMainLinear.layout(newLeft, 0, newLeft + mWidth, 0 + mHeight);
            }

        }

        @Override
        public void onViewReleased(View releasedChild, float xvel, float yvel) {
            super.onViewReleased(releasedChild, xvel, yvel);
        }
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        //自己控件判斷是否攔截事件
        return mDragHelper.shouldInterceptTouchEvent(ev);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        //自己去處理觸摸事件
        mDragHelper.processTouchEvent(event);
        return true;
    }

    //當xml填充完畢的時候纔是調用
    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        //得到左邊佈局
        mLeftLinear = (LinearLayout) getChildAt(0);
        //得到主佈局
        mMainLinear = (LinearLayout) getChildAt(1);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        mWidth = getMeasuredWidth();
        mHeight = getMeasuredHeight();

        //控制昨天佈局拖拽的位置
        mRange = (int) (mWidth * 0.7);
    }

    private int fixLeft(int left) {
        if (left < 0) {
            return 0;
        } else if (left > mRange) {
            return mRange;
        }
        return left;
    }
}

最終的效果
這裏寫鏈接內容

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章