android学习笔记(2)—view的事件体系

     view是Android中所有控件的基类,是一种界面层的抽象,除了view还有viewGroup,viewGroup内部包含了多个view,viewGroup也继承了view,这就意味view本身就可以是一个控件也可以是多个控件组成的一组控件,这种关系形成了view树的结构。

    view的位置由它的4个顶点来决定,分别对应view的4个属性:top、left、right、bottom,top是相对于view的父view的左上角纵坐标,left是相对于父view左上角横坐标,同理right和bottom分别对应右下角横坐标和右下角纵坐标,这4个属性属于相对坐标。很容易得到view的宽width和高height分别为:

    width = right-left;

    height = bottom-top;

    可以通过这4个属get方法得到这4个属性值,left = getLeft();以此类推。从Android3.0开始,view额外增加,x,y,translationX,translationY,其中x y 是view左上角的坐标,而translationX translationY是view左上角相对于父容器的偏移量,这几个参数也是相对于父容器的坐标,translationX 和translationY的默认值是0,和其他的位置参数一样,view也为他们提供了get 和set 方法,换算关系

   x = left+translationX   y = right+translationY

   MotionEvent ,手指接触屏幕的时候所产生的一些列事件,典型的有ACTION_DOWN手指刚接触屏幕,ACTION_MOVE手指移动,ACTION_UP手指放开,ACTION_CANNCEL惭怍取消等。通过MotionEvent对象可以得到点击事件发生的x和y坐标,系统提供了两组方法 getX/getY 和 getRawX/getRawY,区别在于,前者返回的是相对当前View的左上角x y坐标,后者返回的是相对手机屏幕左上角的x y坐标。

   TouchSlop是系统所能识别的被认为滑动的最小距离,通过这个方式获取ViewConfiguration.get(getContext()).getScaledTouchSlop(),方法获取。

  VelocityTracker,用于追踪手指在滑动过程中的速度,计算公式:速度 = (终点位置-起点位置)/ 时间段,分X轴和Y轴,使用方式,在onTouchEvent中

  VelocityTracker tracker = VelocityTracker.obain();

  tracker.addMoveEvent(event);

  获取滑动的速度

  tracker.computeCurrentVelocity(1000);//计算当前速度,其中1000是时间间隔

  int xTracker = tracker.getXVelocity();//水平速度

  int yTracker = tracker.getYVelocity();//垂直速度

  不使用的时候,调用 tracker.clear();tracker.recycle();方法重置回收内存。

  GestureDetector 手势检测类,用于辅助检测用户的点击,滑动,长按,双击等行为。

  关于View的滑动

  view的滑动可以有3种方式,第一种是通过view本身的scrollTo和scrollBy方法,第二种是通过动画,第三种是通过LayoutParams重新布局,第一种方式的时候有两个参数需要注意,scrollX和scrollY,可以通过getScrollX和getScrollY方法获取,分别是view左边缘到view内容左边缘的距离(当view内容左边缘在view左边缘的左边时为正)和view上边缘到view内容上边缘的距离(当view内容上边缘在view上边缘的上边时为正)。值得注意的是第一种方式只能改变view内容的位置,而不能改变View在布局中的位置。

 用动画的方式可以使用view动画也能使用属性动画:ObjectAnimator.ofFloat(view,"translationX",0,100).setDuration(1000).start();值得注意的是动画的方式是对view的影像做操作,不会真正改变view的位置参数,如果希望动画完成后的状态保留,需要设置fiilAfter为true。动画过后控件的位置信息不会发生改变,也就是动画完成后看似控件移动到了目标位置,实际上位置信息还是原来,例如点击事件,点击目标位置没有作用,所以动画不能用于有交互的地方。

  弹性滑动

  实现弹性滑动方式很多,例如,Scroller,Handler#postDelay,Thread#sleep。

   使用Scroller,

//滑动到指定的位置
public void smooth(int dealX,int dealyY){
int scrollX = getScrollX();
int deltaX = dealX-scrollX;
scroller.startScroll(scrollX, 0, deltaX, 0, 1000);
  invalidate();
}

@Override
public void computeScroll() {
if(scroller.computeScrollOffset()){
scrollTo(scroller.getCurrX(), scroller.getCurrY());
postInvalidate();
}
}

   有趣的是,Scroller本身并不能实现View的滑动,需要配合View的computeScroll方法才能完成弹性滑动的效果,它不断让view重绘,而每一次重绘滑动的起始时间有一个时间间隔,通过这个时间间隔Scroller就可以得到View当前的滑动位置。 知道了滑动位置就通过scrollTo来进行滑动。view每一次重绘都会导致view进行小幅度的滑动,达到弹性滑动效果。

    通过动画

     ObjectAnimator.ofFloat(view,"translationX",0,100).setDuration(1000).start();我们可以通过动画的特性来实现一些动画不能实现的效果。

   private void scollerAnimation(){
final int startX = 0;
final int detlaX = 100;

ValueAnimator animator = ValueAnimator.ofInt(0,1).setDuration(1000);
animator.addUpdateListener(new AnimatorUpdateListener() {

@Override
public void onAnimationUpdate(ValueAnimator animation) {
float fraction = animation.getAnimatedFraction();
View view = new View(getContext());
view.scrollTo(startX+(int)(detlaX+fraction),0 );//滑动计算的距离
}
});
}

我们可以在onAnimationUpdate中做我们想要做的操作。

   使用延时策略

   顾名思义,就是用延时策略来发送一系列的消息,可以用handler或者view的postDelay方法。

   int mCount = 0;
final int MESSAGE_SCROLL_TO = 1;
final int FRAME_COUNT = 30;
final int DELAYED_TIME = 33;
final Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case MESSAGE_SCROLL_TO:
mCount++;
if (mCount <= FRAME_COUNT) {
float fraction = mCount / (float) FRAME_COUNT;
int scrollX = (int) (fraction + 100);
View view = new View(getContext());
view.scrollTo(scrollX, 0);
handler.sendEmptyMessageDelayed(MESSAGE_SCROLL_TO,
DELAYED_TIME);
}
break;
default:
break;
}
}
};


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值