ScrollView反弹效果的实现
来源:互联网 发布:淘宝的降价通知 编辑:程序博客网 时间:2024/04/30 14:04
发现很多APP的界面都可以滑动,QQ,微信等等,自己琢磨了下。效果如下:
代码:ScrollView
package com.wsj.wsjdemo;import android.content.Context;import android.graphics.Rect;import android.util.AttributeSet;import android.view.MotionEvent;import android.view.View;import android.view.animation.TranslateAnimation;import android.widget.ScrollView;/** * ScrollView反弹效果的实现 */public class VScrollView extends ScrollView {private View inner;// 孩子Viewprivate float y;// 点击时y坐标private int mLastMotionX;private int mLastMotionY;// 默认支持反弹效果private boolean isAllowRebound = true;private Rect normal = new Rect();// 矩形(这里只是个形式,只是用于判断是否需要动画.)private boolean isCount = false;// 是否开始计算public VScrollView(Context context) {super(context);}public VScrollView(Context context, AttributeSet attrs) {super(context, attrs);}public VScrollView(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);}/*** * 根据 XML 生成视图工作完成.该函数在生成视图的最后调用,在所有子视图添加完之后. 即使子类覆盖了 onFinishInflate * 方法,也应该调用父类的方法,使该方法得以执行. */@Overrideprotected void onFinishInflate() {if (getChildCount() > 0) {inner = getChildAt(0);}}public void setInnerView(View view) {this.inner = view;}@Overridepublic boolean onInterceptTouchEvent(MotionEvent e) {int x = (int) e.getRawX();int y = (int) e.getRawY();switch (e.getAction()) {case MotionEvent.ACTION_DOWN:mLastMotionX = x;mLastMotionY = y;case MotionEvent.ACTION_MOVE:int deltaX = x - mLastMotionX;int deltaY = y - mLastMotionY;if (Math.abs(deltaX) > 10 && Math.abs(deltaY) < 45) {return false;}}return super.onInterceptTouchEvent(e);}/*** * 监听touch */@Overridepublic boolean onTouchEvent(MotionEvent ev) {if (inner != null && getAllowRebound()) {commOnTouchEvent(ev);}return super.onTouchEvent(ev);}/*** * 触摸事件 * * @param ev */public void commOnTouchEvent(MotionEvent ev) {int action = ev.getAction();switch (action) {case MotionEvent.ACTION_DOWN:break;case MotionEvent.ACTION_UP:// 手指松开.if (isNeedAnimation()) {animation();isCount = false;}break;/*** * 排除出第一次移动计算,因为第一次无法得知y坐标, 在MotionEvent.ACTION_DOWN中获取不到, * 因为此时是MyScrollView的touch事件传递到到了LIstView的孩子item上面.所以从第二次计算开始. * 然而我们也要进行初始化,就是第一次移动的时候让滑动距离归0. 之后记录准确了就正常执行. */case MotionEvent.ACTION_MOVE:final float preY = y;// 按下时的y坐标float nowY = ev.getY();// 时时y坐标int deltaY = (int) (preY - nowY);// 滑动距离if (!isCount) {deltaY = 0; // 在这里要归0.}y = nowY;// 当滚动到最上或者最下时就不会再滚动,这时移动布局if (isNeedMove()) {// 初始化头部矩形if (normal.isEmpty()) {// 保存正常的布局位置normal.set(inner.getLeft(), inner.getTop(), inner.getRight(), inner.getBottom());}// 移动布局inner.layout(inner.getLeft(), inner.getTop() - deltaY / 2, inner.getRight(), inner.getBottom() - deltaY / 2);}isCount = true;break;default:break;}}/*** * 回缩动画 */public void animation() {// 开启移动动画TranslateAnimation ta = new TranslateAnimation(0, 0, inner.getTop(), normal.top);ta.setDuration(250);inner.startAnimation(ta);// 设置回到正常的布局位置inner.layout(normal.left, normal.top, normal.right, normal.bottom);normal.setEmpty();}// 是否需要开启动画public boolean isNeedAnimation() {return !normal.isEmpty();}/*** * 是否需要移动布局 inner.getMeasuredHeight():获取的是控件的总高度 * * getHeight():获取的是屏幕的高度 * * @return */public boolean isNeedMove() {int offset = inner.getMeasuredHeight() - getHeight();int scrollY = getScrollY();// 0是顶部,后面那个是底部if (scrollY == 0 || scrollY == offset) {return true;}return false;}public void scrollToTop() {// this.setScrollY(0);this.scrollTo(this.getLeft(), 0);}public void scrollToBottom() {// this.setScrollY(this.getHeight());this.scrollTo(this.getLeft(), this.getHeight());}public void setAllowRebound(boolean isAllowRebound) {this.isAllowRebound = isAllowRebound;}public boolean getAllowRebound() {return this.isAllowRebound;}}
Main方法:什么都没有
package com.wsj.wsjdemo;import android.os.Bundle;import android.app.Activity;import android.view.Menu;public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } }
只需要在布局只用自定义ScrollView包含内容即可:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <com.wsj.wsjdemo.VScrollView android:id="@+id/sv_mycenter" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center_horizontal" android:orientation="vertical" android:scrollbars="none" > <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/hello_world" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/hello_world" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/hello_world" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/hello_world" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/hello_world" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/hello_world" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/hello_world" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/hello_world" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/hello_world" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/hello_world" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/hello_world" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/hello_world" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/hello_world" /> </LinearLayout> </com.wsj.wsjdemo.VScrollView></LinearLayout>
结束
2 1
- ScrollView反弹效果的实现
- ScrollView反弹效果的实现
- ScrollView反弹效果的实现
- ScrollView反弹效果实现
- ScrollView的反弹效果的实现
- Android ScrollView反弹效果的实现
- Android ScrollView反弹效果的实现
- 自己的ScrollView实现反弹效果
- Android ScrollView反弹效果的实现
- Android ScrollView反弹效果的实现
- android ScrollView反弹效果的实现
- Android ScrollView反弹效果的实现
- Android ScrollView反弹效果的实现
- ScrollView的反弹效果
- scrollview实现反弹效果与解决与listview的冲突
- Android自定义ScrollView实现反弹效果
- Android自定义ScrollView实现反弹效果
- ScrollView反弹效果实现[bug修正版]
- 安装ssh
- 任意两点之间的最短路径问题(Floyd-Warshall算法)
- 按照特定轨迹遍历字符串图
- Android添加第三方so到APK中
- 常用的命令、小技巧
- ScrollView反弹效果的实现
- 大道至简-小波
- 【bzoj1193】[HNOI2006]马步距离
- hdu 1102 Constructing Roads
- xcode 常用的快捷键
- 怎么去掉Xcode工程中的某种类型的警告
- POJ Network(最小生成树--kruskul)
- Leetcode#26||Remove Duplicates from Sorted Array
- HDU 1542 Atlantis