package com.lc.mywidget;
import android.content.Context;
import android.support.v4.view.ViewCompat;
import android.support.v4.widget.ViewDragHelper;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.Log;
import android.util.TypedValue;
import android.view.MotionEvent;
import android.view.View;
import android.widget.RelativeLayout;
public class MyViewGroup extends RelativeLayout {
private View mView1;//left
private View mView2;//right
private View mView3;//top
private View mView4;//bottom
private ViewDragHelper mViewDragHelper;
private float mLeftMenuOnScreen = 0f;//显示百分比
private float mRightMenuOnScreen=0f;
private int symbol = 0; // 0 都不显示 -1 显示左菜单 1 右边菜单 -2 顶部菜单 2 底部菜单
private float widthPercent =0.5f;
private float parentWidth =0;
private float parentHeight = 0;
private int actionBarHeight = 96;
private ViewDragHelper.Callback mCallback = new ViewDragHelper.Callback() {
@Override
public boolean tryCaptureView(View child, int pointerId) {
//设置拦截的view
/* boolean capture = false;
if(mView1 == child || mView2 == child || mView4 == child || mView3 == child){
capture = true;
if(mView2 == child){
symbol = 1;
}else if(mView1 == child){
symbol =-1;
}else if(mView3 == child){
symbol = -2;
}else{
symbol = 2;
}
}
Log.d("lcc","capture view"+capture+ " symbol = " + symbol);*/
return true;
}
@Override
public int clampViewPositionHorizontal(View child, int left, int dx) {
//通过判断水平方向该view的left取值范围,设置值
Log.d("lcc","clamp horizontal "+left);
int newLeft = 0;
if(symbol == -1) {
newLeft = Math.max(-child.getWidth(), Math.min(left, 0));
}else if(symbol ==1){
newLeft = Math.min((int)parentWidth,Math.max(left,(int)parentWidth-child.getWidth()));
}
Log.d("lcc","symbol = "+ symbol+" newLeft="+newLeft);
return newLeft;
}
@Override
public int clampViewPositionVertical(View child, int top, int dy) {
//通过判断垂直方向该view的top取值范围,设置值
int newTop = 0;
if(symbol == -2){
newTop = Math.max(-child.getHeight(),Math.min(top,0));
}else if(symbol == 2){
newTop = Math.min((int)parentHeight,Math.max(top,(int)parentHeight-child.getHeight()));
}
Log.d("lcc","clamp vertical " + newTop);
return newTop;
}
@Override
public void onViewReleased(View releasedChild, float xvel, float yvel) {
//当手指离开屏幕时,根据当前运行速度和已显示所占的百分比设置最终状态(显示或隐藏)
Log.d("lcc","onViewReleased "+releasedChild.getLeft()+ " symbol = "+ symbol);
super.onViewReleased(releasedChild, xvel, yvel);
final int childWidth = releasedChild.getWidth();
final int childHeight = releasedChild.getHeight();
float offset = 0;
if(symbol == -1) {
offset = (childWidth + releasedChild.getLeft()) * 1.0f / childWidth;
mViewDragHelper.settleCapturedViewAt(xvel > 0 || xvel == 0 && offset > 0.5f ? 0 : -childWidth, releasedChild.getTop());
}else if(symbol == 1){
offset = (parentWidth-releasedChild.getLeft()) * 1.0f / childWidth;
mViewDragHelper.settleCapturedViewAt(xvel < 0 || xvel == 0 && offset > 0.5f ? (int)(parentWidth-childWidth) : (int)parentWidth, releasedChild.getTop());
}else if(symbol == -2){
offset = (childHeight + releasedChild.getTop()) * 1.0f / childHeight;
mViewDragHelper.settleCapturedViewAt(releasedChild.getLeft(),yvel > 0 || yvel == 0 && offset > 0.5f ? 0 : -childHeight);
}else{
offset = (parentHeight-actionBarHeight- releasedChild.getTop()) * 1.0f / childHeight;
mViewDragHelper.settleCapturedViewAt(releasedChild.getLeft(),yvel < 0 || yvel == 0 && offset > 0.5f ? (int)(parentHeight-childHeight-actionBarHeight) : (int)parentHeight);
}
invalidate();
}
@Override
public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy) {
Log.d("lcc"," onViewPositionChanged symbol = " + symbol);
final int childWidth = changedView.getWidth();
final int childHeight = changedView.getHeight();
float offset = 0;
if(symbol == -1){
offset = (float) (childWidth + left) / childWidth;
mLeftMenuOnScreen = offset;
}else if(symbol == 1){
offset = (parentWidth-left) / childWidth;
mRightMenuOnScreen = offset;
}else if(symbol == -2){
offset = (childHeight+top)/childHeight;
}else{
offset = (parentHeight-top)/childHeight;
}
//offset can callback here
changedView.setVisibility(offset == 0 ? View.INVISIBLE : View.VISIBLE);
invalidate();
}
@Override
public int getViewHorizontalDragRange(View child) {
return child.getWidth();
}
@Override
public int getViewVerticalDragRange(View child) {
return 0;
}
@Override
public void onEdgeDragStarted(int edgeFlags, int pointerId) {
if(edgeFlags == ViewDragHelper.EDGE_LEFT) {
Log.d("lcc","edge left");
mViewDragHelper.captureChildView(mView1, pointerId);
symbol = -1;
}else if(edgeFlags == ViewDragHelper.EDGE_RIGHT){
Log.d("lcc","edge right");
mViewDragHelper.captureChildView(mView2,pointerId);
symbol = 1;
}else if(edgeFlags == ViewDragHelper.EDGE_TOP){
Log.d("lcc","edge top");
mViewDragHelper.captureChildView(mView3,pointerId);
symbol = -2;
}else{
Log.d("lcc","edge bottom");
mViewDragHelper.captureChildView(mView4,pointerId);
symbol = 2;
}
}
};
public MyViewGroup(Context context, AttributeSet attrs) {
super(context, attrs);
parentWidth = context.getResources().getDisplayMetrics().widthPixels;
mViewDragHelper = ViewDragHelper.create(this,mCallback);
mViewDragHelper.setEdgeTrackingEnabled(ViewDragHelper.EDGE_ALL );
//设置minVelocity
mViewDragHelper.setMinVelocity(400*getResources().getDisplayMetrics().density);
DisplayMetrics metircs= getResources().getDisplayMetrics();
parentWidth = metircs.widthPixels;
parentHeight = metircs.heightPixels;
actionBarHeight = getActionBarHeight();
Log.d("lcc"," parentWidth = "+ parentWidth);
}
public MyViewGroup(Context context) {
super(context);
mViewDragHelper = ViewDragHelper.create(this,mCallback);
mViewDragHelper.setEdgeTrackingEnabled(ViewDragHelper.EDGE_ALL);
//设置minVelocity
mViewDragHelper.setMinVelocity(400*getResources().getDisplayMetrics().density);
DisplayMetrics metircs= getResources().getDisplayMetrics();
parentWidth = metircs.widthPixels;
parentHeight = metircs.heightPixels;
actionBarHeight = getActionBarHeight();
Log.d("lcc"," parentWidth = "+ parentWidth);
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
mView1 = getChildAt(0);
mView2 = getChildAt(1);
mView3 = getChildAt(2);
mView4 = getChildAt(3);
}
@Override
public void computeScroll() {
if(mViewDragHelper.continueSettling(true)){
ViewCompat.postInvalidateOnAnimation(this);
}
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
boolean intercepte = mViewDragHelper.shouldInterceptTouchEvent(ev);
Log.d("lcc","intercept="+intercepte);
return intercepte;
}
@Override
public boolean onTouchEvent(MotionEvent event) {
mViewDragHelper.processTouchEvent(event);
return true;
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
mView1 = getChildAt(0);
mView2 = getChildAt(1);
mView3 = getChildAt(2);
mView4 = getChildAt(3);
MarginLayoutParams mp = (MarginLayoutParams) mView1.getLayoutParams();
int view1Width = (int) (mView1.getMeasuredWidth()*widthPercent);
int left = (int) (-view1Width+view1Width * mLeftMenuOnScreen);
mView1.layout(left,mp.topMargin,left+view1Width,mp.topMargin+mView1.getMeasuredHeight());
Log.d("lcc","myView1 left=" + left + " right = " + (left+view1Width));
mp = (MarginLayoutParams) mView2.getLayoutParams();
int view2Width = (int) (mView2.getMeasuredWidth()*widthPercent);
int left2 = (int) parentWidth;
mView2.layout(left2,mp.topMargin,left2+view2Width,mView2.getMeasuredHeight()+mp.topMargin);
Log.d("lcc","myView2 left=" + left2 + " right = " + (left2+view2Width));
mp = (MarginLayoutParams) mView3.getLayoutParams();
int viewHeight = (int) (mView3.getMeasuredHeight()*widthPercent);
mView3.layout(mp.leftMargin,mp.topMargin-viewHeight,mp.leftMargin+mView3.getMeasuredWidth(),mp.topMargin);
Log.d("lcc","myView3 top=" + (mp.topMargin-viewHeight) + " bottom = " + mp.topMargin);
mp = (MarginLayoutParams) mView4.getLayoutParams();
int viewHeight2 = (int) (mView4.getMeasuredHeight()*widthPercent);
mView4.layout(mp.leftMargin,(int)(parentHeight+mp.topMargin-actionBarHeight),mp.leftMargin+mView4.getMeasuredWidth(),(int) (parentHeight+viewHeight2+mp.topMargin-actionBarHeight));
Log.d("lcc","myView4 top=" + (mp.topMargin+parentHeight) + " bottom = " + mp.topMargin);
}
public int getActionBarHeight(){
TypedValue tv = new TypedValue();
if (getContext().getTheme().resolveAttribute(android.R.attr.actionBarSize, tv, true)) {
int actionBarHeight = TypedValue.complexToDimensionPixelSize(tv.data, getContext().getResources().getDisplayMetrics());
Log.d("lcc","actionBarHeight = " + actionBarHeight);
return actionBarHeight;
}
else{
Log.d("lcc","actionBarHeight = " + 0);
return 0;
}
}
}
上述demo是对其他博主demo的一个扩展,原文链接:http://blog.youkuaiyun.com/lmj623565791/article/details/47396187
练习时发现ViewDragHelper在多次调用captureChildView()方法后只会对最后一个view的行为进行处理。