您的位置:首页 > 其它

自定义View---继承ViewGroup动效

2017-08-21 16:59 267 查看

前言

在做自定义控件的时候,我们首先要选择的是要继承View还是ViewGroup。本文介绍的是自定义控件继承ViewGroup时进行子View的动效。

1.继承选择

我们通常不是直接继承ViewGroup,因为这样的话我们要自己实现onMeasure(要根据MeasureSpec的模式不同测量自己,获取padding值,测量子View以及利用LayoutParams获取margin值),我们还有自己实现onLayout,需要摆放自己和子View。一般情况下,我们会选取继承轻量级的FrameLayout,利用它的默认实现onMeasure,可选择的是否实现onLayout。选择了要要继承的FrameLayout了,接下来就是实现构造,Android Studio的自定义模板:vc,可以帮我们快速实现自定义控件的构造。

常用方法介绍

CustomView(Context context)

在代码中new出自定义控件时被调用

CustomTitleView(Context context, AttributeSet attrs)

读取xml文件后被调用,最终会调用三个参数的构造

onFinishInflate

此方法执行在当前view在布局文件中的xml结束标签读取完后执行。此时已经添加了子View,但是还没有测量。

onSizeChanged

此方法是onMeasure执行之后执行,因此可获取宽高

ViewDragHelper

触摸事件的解析类(如GestureDecetor),需要我们传递给它触摸事件,该类专门用于在ViewGroup中对子View进行拖拽处理。

ViewDragHelper viewDragHelper = ViewDragHelper.create(this, callback);


public boolean onInterceptTouchEvent(MotionEvent ev) {
//让ViewDragHelper帮助我们判断是否应该拦截
boolean result = viewDragHelper.shouldInterceptTouchEvent(ev);
return result;
}


@Override
public boolean onTouchEvent(MotionEvent event) {
//将触摸事件传递给ViewDragHelper来解析
viewDragHelper.processTouchEvent(event);
return true;
}


ViewDragHelper.Callback的回调方法

tryCaptureView

判断要对哪个View进行触摸事件的捕获

getViewHorizontalDragRange

用来判断你是否想强制水平滑动的,如果想强制水平滑动,则返回大于0的任意值

clampViewPositionHorizontal

控制子View在水平方向上的移动

clampViewPositionVertical

控制子View在竖直方向上的移动

onViewPositionChanged

当View位置改变的时候执行,可以获取view移动的距离。

ViewDragHelper只是触摸事件的解析类,在这个方法里需要进行真正的动画效果。

移动View的方法:

通过改变View的scroll的坐标来移动:

scrollTo(x,y);//滚动到指定位置
scrollBy(xOffset,yOffset);//滚动多少距离


通过改变View在父View中的布局的位置:

offsetLeftAndRight(offset);//同时更改view的left和right
offsetTopAndBottom(offset);//同时更改view的top和bottom
layout(l,t,r,b);
ViewCompat.offsetLeftAndRight(view,dx);//让view进行伴随移动


在得到子View拖动的百分比fraction,后我们通常要一些算法计算出中间的动画效果,这里我们通常可以利用FloatEvaluator(数值变化),ArgbEvaluator(颜色变化)

float scale = floatEval.evaluate(fraction,1f,0.8f);
view.setScaleY(scale);
view.setScaleX(scale);


int color = (int) argbEval.evaluate(fraction,Color.BLACK,Color.TRANSPARENT);
getBackground().setColorFilter(color,PorterDuff.Mode.SRC_OVER);


onViewReleased

手指抬起的时候执行,通常在这里可以做一些手指抬起时的缓慢移动的动效.这里可以利用ViewCompat进行动画效果(不用传入时长,会计算出一个最优的动画时间)

dragHelper.smoothSlideViewTo(view,left,top);
ViewCompat.postInvalidateOnAnimation(ViewGroup.this);


同时重写computeScroll方法:

@Override
public void computeScroll() {
super.computeScroll();
if(viewDragHelper.continueSettling(true)){
ViewCompat.postInvalidateOnAnimation(this);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息