Android实现简单的下拉阻尼效应

来源:互联网 发布:arm linux gcc 官方 编辑:程序博客网 时间:2024/05/05 17:44

IOS的下拉上拉都会出现一个很玄的动态效果。在Android中,虽然可以实现类似的效果,但有点不同的是,如果调用overScrollBy来实现类似的阻尼效应的话,最顶部会出现一片亮的区域,让人感觉不是很爽。所以决定不采用该方法来实现而是改用自定义的方式来实现。下面是自定义控件的代码部分:



public class MyView extends ScrollView {//记录下最开始点击的位置int initY;//移动的位置int deltaY;int touchY;//记录第一个item的位置的矩形Rect topRect;//用来存放第一个可见的itemView inner;//记录下ImageView最原始的顶部位置和底部位置int initTop,initButtom;int left = 0,top = 0,right = 0,bottom = 0;ImageView imageView;State state; boolean recordFlag; enum State{UP,NORMAL,DOWN} boolean isMoving;boolean shutScroll;private int current_Bottom;private int current_Top;public MyView(Context context, AttributeSet attrs) {super(context, attrs);state = State.NORMAL;topRect=new Rect();recordFlag=false;}public  void setImageView(ImageView imageView){this.imageView=imageView;}//当布局加载完成之后调用该方法@Overrideprotected void onFinishInflate() {super.onFinishInflate();//返回加载完成后所看到的第一个item,这里就是看到的第一个item,通过对该对象的移动来实现整体的移动inner=getChildAt(0);Log.i("inner", inner.toString());}//onTouchEvent的返回值 返回true的话表示该事件已经被处理了,返回false表示改时间还未被处理@Overridepublic boolean onTouchEvent(MotionEvent ev) {if(inner!=null){commOnTouchEvent(ev);}if(shutScroll){return true;}else{return super.onTouchEvent(ev);}}private void commOnTouchEvent(MotionEvent ev) {switch(ev.getAction()){case MotionEvent.ACTION_DOWN:{if(recordFlag==false){left=inner.getLeft();top=inner.getTop();right=inner.getRight();bottom=inner.getBottom();recordFlag=true;}//开始的时候接触点的坐标值initY=(int) ev.getY();//记录下ImageView的原始高度initTop=imageView.getTop();//记录下ImageView的原始的底部的像素坐标initButtom=imageView.getBottom();break;}case MotionEvent.ACTION_MOVE:{//滑动的距离deltaY=(int) (ev.getY()-initY);if(deltaY<0){//向上滑动state=State.UP;isMoving=false;shutScroll=false;}else if(deltaY>=0){//在这里做一下判断,当getScrollY为0时,继续下拉就会进入down状态。if(getScrollY()==0){//向下滑动state=State.DOWN;isMoving=true;shutScroll=true;}}if(isMoving){if (topRect.isEmpty()) {// 保存正常的布局位置topRect.set(left, top,right,bottom);}float inner_move_H = deltaY / 5;inner.layout(topRect.left, (int) (topRect.top + inner_move_H),topRect.right, (int) (topRect.bottom + inner_move_H));float image_move_H = deltaY / 10;current_Top = (int) (initTop + image_move_H);current_Bottom = (int) (initButtom + image_move_H);imageView.layout(imageView.getLeft(), current_Top,imageView.getRight(), current_Bottom);}break;}case MotionEvent.ACTION_UP:{if(needToScroll()){animation();}if(getScrollY()==0){/*这里为什么要这么写呢?这里有很重要的一个知识点: * getScrollY()返回的是手机屏幕左上角和调用该方法的view的左上角之间的Y坐标只差。 * 在这里,自定义空间的布局方式看看布局文件就会发现,当View滑动的时候,View的状态在up,normal; * down之间切换。在View下来的过程中,normal和down有一个临界值,这个临界值就是该view的 * 左上角是不是和屏幕的左上角相等。相等的话就说明再向下拉的话就down状态了。*/state=State.NORMAL;}break;}}}private void animation() {//背景图片平移的动画TranslateAnimation image_Anim = new TranslateAnimation(0, 0,Math.abs(initTop - current_Top), 0);image_Anim.setDuration(200);imageView.startAnimation(image_Anim);imageView.layout(imageView.getLeft(), (int) initTop,imageView.getRight(), (int) initButtom);// 开启移动动画TranslateAnimation inner_Anim = new TranslateAnimation(0, 0,inner.getTop(), topRect.top);inner_Anim.setDuration(200);inner.startAnimation(inner_Anim);inner.layout(topRect.left, topRect.top, topRect.right, topRect.bottom);//state=State.NORMAL;topRect.setEmpty();}private boolean needToScroll() {if(state==State.DOWN){return true;}return false;}}



效果图:





0 0
原创粉丝点击