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

来源:互联网 发布:手机宠物软件 编辑:程序博客网 时间:2024/05/17 23:58

前言

在做自定义控件的时候,我们首先要选择的是要继承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;}
@Overridepublic 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和rightoffsetTopAndBottom(offset);//同时更改view的top和bottomlayout(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方法:

@Overridepublic void computeScroll() {    super.computeScroll();    if(viewDragHelper.continueSettling(true)){        ViewCompat.postInvalidateOnAnimation(this);    }}