您的位置:首页 > 其它

ViewDragHelper的使用

2016-04-08 11:30 218 查看
首先继承:

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;
}
}


最终的效果

这里写链接内容
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: