Android实现简单的下拉阻尼效应示例代码
时间:2022-09-28 09:39:41|栏目:Android代码|点击: 次
OS的下拉上拉都会出现一个很玄的动态效果。在Android中,虽然可以实现类似的效果,但有点不同的是,如果调用overScrollBy来实现类似的阻尼效应的话,最顶部会出现一片亮的区域,让人感觉不是很爽。所以决定不采用该方法来实现而是改用自定义的方式来实现。
下面是自定义控件的代码部分:
public class MyView extends ScrollView { //记录下最开始点击的位置 int initY; //移动的位置 int deltaY; int touchY; //记录第一个item的位置的矩形 Rect topRect; //用来存放第一个可见的item View 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; } //当布局加载完成之后调用该方法 @Override protected void onFinishInflate() { super.onFinishInflate(); //返回加载完成后所看到的第一个item,这里就是看到的第一个item,通过对该对象的移动来实现整体的移动 inner=getChildAt(0); Log.i("inner", inner.toString()); } //onTouchEvent的返回值 返回true的话表示该事件已经被处理了,返回false表示改时间还未被处理 @Override public 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; } }
上一篇:Android实现扫码功能
栏 目:Android代码
下一篇:Kotlin原理详析之拓展函数
本文地址:http://www.codeinn.net/misctech/214922.html