oschina源码分析之侧滑菜单界面之可以拖动的ScrollView
来源:互联网 发布:淘宝店如何刷信誉 编辑:程序博客网 时间:2024/05/05 16:46
先上源码:
package net.oschina.app.widget;import android.annotation.SuppressLint;import android.content.Context;import android.graphics.Rect;import android.util.AttributeSet;import android.util.Log;import android.view.MotionEvent;import android.view.View;import android.view.animation.TranslateAnimation;import android.widget.ScrollView;/** * 可以拖动的ScrollView * */public class CustomerScrollView extends ScrollView { private static final String TAG = "CustomerScrollView"; private static final int size = 4; private View inner; private float y; private Rect normal = new Rect(); public CustomerScrollView(Context context) { super(context); } public CustomerScrollView(Context context, AttributeSet attrs) { super(context, attrs); } @Override protected void onFinishInflate() { if (getChildCount() > 0) { inner = getChildAt(0); } } @SuppressLint("ClickableViewAccessibility") @Override public boolean onTouchEvent(MotionEvent ev) { if (inner == null) { return super.onTouchEvent(ev); } else { commOnTouchEvent(ev); } return super.onTouchEvent(ev); } public void commOnTouchEvent(MotionEvent ev) { int action = ev.getAction(); switch (action) { case MotionEvent.ACTION_DOWN: y = ev.getY(); break; case MotionEvent.ACTION_UP: if (isNeedAnimation()) { // Log.v("mlguitar", "will up and animation"); animation(); } break; case MotionEvent.ACTION_MOVE: final float preY = y; float nowY = ev.getY(); /** * size=4 表示 拖动的距离为屏幕的高度的1/4 */ int deltaY = (int) (preY - nowY) / size; Log.i(TAG, "commOnTouchEvent: deltay="+ deltaY +"preY" + preY +"nowY" + nowY ); // 滚动 // scrollBy(0, deltaY); y = nowY; if (isNeedMove()) { Log.i(TAG, "commOnTouchEvent: normal.isEmpty:" + normal.isEmpty()); if (normal.isEmpty()) { Log.i(TAG, "commOnTouchEvent: inner:" + inner.getLeft() + "," + inner.getTop() + "," + inner.getRight() + "," + inner.getBottom()); normal.set(inner.getLeft(), inner.getTop(), inner.getRight(), inner.getBottom()); return; } int yy = inner.getTop() - deltaY; Log.i(TAG, "commOnTouchEvent: new layout:" + inner.getLeft() + "," + yy + "," + inner.getRight() + "," + (inner.getBottom() - deltaY)); // 移动布局 inner.layout(inner.getLeft(), yy, inner.getRight(), inner.getBottom() - deltaY); } break; default: break; } } public void animation() { TranslateAnimation ta = new TranslateAnimation(0, 0, inner.getTop(), normal.top); ta.setDuration(200); Log.i(TAG, "animation start " + "(0,0," + inner.getTop() +"," + normal.top + ")"); inner.startAnimation(ta); inner.layout(normal.left, normal.top, normal.right, normal.bottom); normal.setEmpty(); } public boolean isNeedAnimation() { Log.i(TAG, "isNeedAnimation: " + !normal.isEmpty()); return !normal.isEmpty(); } public boolean isNeedMove() { int offset = inner.getMeasuredHeight() - getHeight(); int scrollY = getScrollY(); Log.i(TAG, "isNeedMove: " + "scrollY=" + scrollY + "offset=" + offset); if (scrollY == 0 || scrollY == offset) { return true; } return false; }}
先看isNeedMove()函数:
- int offset = inner.getMeasuredHeight() - getHeight();
前者一般与后者相等,只有当view超出屏幕后前者才会比后者大,getMeasuredHeight() 等于 getHeight()加上屏幕之外没有显示的大小。
- int scrollY = getScrollY();
看下官方对这个函数的介绍:The top edge of the displayed part of your view, in pixels. 返回的是view的顶端超过屏幕部分的大小。
因此,这个函数的判断条件其实就是view在屏幕最上面或者最下面这两种情况才需要移动。
- 再看移动事件(commOnTouchEvent):
- 点击获取初始位置,抬起判断是否需要移动,主要看一下移动这个事件(MotionEvent.ACTION_MOVE)。
- 首先根据移动的Y和初始的Y得到移动的距离:int deltaY = (int) (preY - nowY) / size;
- 判断是否需要移动。如果需要,第一次用normal这个变量来记录原始的view范围,然后用inner.layout(inner.getLeft(), yy, inner.getRight(),
inner.getBottom() - deltaY);来移动布局。就是根据先前得到的移动距离来改变view的上下显示范围。 - 最后就是退回动画:TranslateAnimation ta = new TranslateAnimation(0, 0, inner.getTop(),
normal.top);就是简单的由现在的Y变化到记录的原始的Y。
0 0
- oschina源码分析之侧滑菜单界面之可以拖动的ScrollView
- OSChina 源码之 ActionServlet 控制类
- 【oschina android源码分析】缓存的设计
- layui源码详细分析之树形菜单
- Launcher3分析之拖动图标的流程
- OSChina App代码分析之摇一摇Demo
- OSChina App代码分析之BaseApplication
- Android之十SlidingMenu侧滑菜单的实现分析
- 实战 Walker 之侧滑菜单的实现分析
- 实战Walker之侧滑菜单的实现分析
- 侧滑菜单之NavigationView原理分析
- 用ViewDragHelper自定义侧滑菜单——浅析源码解决与ScrollView的滑动冲突
- Android学习之界面篇(七)侧滑菜单的实现
- Android6.0锁屏源码分析之界面布局分析
- 【oschina android源码分析】总结
- Oschina 安卓客户端源码学习之二
- Oschina 安卓客户端源码学习之三
- oschina-app 的源码分析-主页面滑动切换
- Android数据持久化的方法
- C++ const关键字
- KindEditor得不到textarea值的解决方法
- 谁的锁,锁的谁--关于synchronized、ReentrantLock的正确解锁姿势
- python Decrator 装饰器 初探
- oschina源码分析之侧滑菜单界面之可以拖动的ScrollView
- C++ 实验三
- 自动化测试方案
- Mac 使用(1)
- iOS国际化
- flask学习
- 10. 中断下半部---工作队列
- 经典的Java基础面试题集锦
- C++ 实验四