Android|重写ScrollView实现页面越界回弹效果
实现效果
实现方法
新建类ReboundScrollView.java,重写ScrollView方法:
package com.example.scrollview;import android.content.Context;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.TranslateAnimation;
import android.widget.ScrollView;public class ReboundScrollView extends ScrollView {private boolean mEnableTopRebound = true;private boolean mEnableBottomRebound = true;private OnReboundEndListener mOnReboundEndListener;private View mContentView;private Rect mRect = new Rect();public ReboundScrollView(Context context) {super(context);}public ReboundScrollView(Context context, AttributeSet attrs) {super(context, attrs);}public ReboundScrollView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);}/*** after inflating view, we can get the width and height of view*/@Overrideprotected void onFinishInflate() {super.onFinishInflate();mContentView = getChildAt(0);}@Overrideprotected void onLayout(boolean changed, int l, int t, int r, int b) {super.onLayout(changed, l, t, r, b);if (mContentView == null) return;// to remember the location of mContentViewmRect.set(mContentView.getLeft(), mContentView.getTop(), mContentView.getRight(), mContentView.getBottom());}public ReboundScrollView setOnReboundEndListener(OnReboundEndListener onReboundEndListener) {this.mOnReboundEndListener = onReboundEndListener;return this;}public ReboundScrollView setEnableTopRebound(boolean enableTopRebound) {this.mEnableTopRebound = enableTopRebound;return this;}public ReboundScrollView setEnableBottomRebound(boolean mEnableBottomRebound) {this.mEnableBottomRebound = mEnableBottomRebound;return this;}private int lastY;private boolean rebound = false;private int reboundDirection = 0; //<0 表示下部回弹 >0 表示上部回弹 0表示不回弹@Overridepublic boolean dispatchTouchEvent(MotionEvent ev) {if (mContentView == null) {return super.dispatchTouchEvent(ev);}switch (ev.getAction()) {case MotionEvent.ACTION_DOWN:lastY = (int) ev.getY();break;case MotionEvent.ACTION_MOVE:if (!isScrollToTop() && !isScrollToBottom()) {lastY = (int) ev.getY();break;}//处于顶部或者底部int deltaY = (int) (ev.getY() - lastY);//deltaY > 0 下拉 deltaY < 0 上拉//disable top or bottom reboundif ((!mEnableTopRebound && deltaY > 0) || (!mEnableBottomRebound && deltaY < 0)) {break;}int offset = (int) (deltaY * 0.48);mContentView.layout(mRect.left, mRect.top + offset, mRect.right, mRect.bottom + offset);rebound = true;break;case MotionEvent.ACTION_UP:if (!rebound) break;reboundDirection = mContentView.getTop() - mRect.top;TranslateAnimation animation = new TranslateAnimation(0, 0, mContentView.getTop(), mRect.top);animation.setDuration(300);animation.setAnimationListener(new Animation.AnimationListener() {@Overridepublic void onAnimationStart(Animation animation) {}@Overridepublic void onAnimationEnd(Animation animation) {if (mOnReboundEndListener != null) {if (reboundDirection > 0) {mOnReboundEndListener.onReboundTopComplete();}if (reboundDirection < 0) {mOnReboundEndListener.onReboundBottomComplete();}reboundDirection = 0;}}@Overridepublic void onAnimationRepeat(Animation animation) {}});mContentView.startAnimation(animation);mContentView.layout(mRect.left, mRect.top, mRect.right, mRect.bottom);rebound = false;break;}return super.dispatchTouchEvent(ev);}@Overridepublic void setFillViewport(boolean fillViewport) {super.setFillViewport(true); //默认是填充ScrollView 或者再XML布局文件中设置fillViewport属性}/*** 判断当前ScrollView是否处于顶部*/private boolean isScrollToTop() {return getScrollY() == 0;}/*** 判断当前ScrollView是否已滑到底部*/private boolean isScrollToBottom() {return mContentView.getHeight() <= getHeight() + getScrollY();}/*** listener for top and bottom rebound* do your implement in the following methods*/public interface OnReboundEndListener {void onReboundTopComplete();void onReboundBottomComplete();}
}
之后在XML文件中调用控件,即可实现效果:
Tips:记得改成自己的包名
<com.example.scrollview.ReboundScrollView xmlns:android="http://schemas.android.com/apk/res/android"android:layout_height="match_parent"android:layout_width="match_parent"android:overScrollMode="never" ></com.example.scrollview.ReboundScrollView>
属性说明
//该属性取消到顶到底的自带光效
android:overScrollMode="never"//该属性隐藏滚动条
android:scrollbars="none"
全部代码
<?xml version="1.0" encoding="utf-8"?>
<com.example.scrollview.ReboundScrollView xmlns:android="http://schemas.android.com/apk/res/android"android:layout_height="match_parent"android:layout_width="match_parent"android:overScrollMode="never" ><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="vertical"><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"><Viewandroid:layout_width="0dp"android:layout_height="60dp"android:layout_weight="2"android:background="#07C2FB" /><TextViewandroid:layout_width="0dp"android:layout_height="60dp"android:layout_weight="1"android:gravity="center"android:text="#07C2FB" /></LinearLayout><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"><Viewandroid:layout_width="0dp"android:layout_height="60dp"android:layout_weight="2"android:background="#C60426FD" /><TextViewandroid:layout_width="0dp"android:layout_height="60dp"android:layout_weight="1"android:gravity="center"android:text="#C60426FD" /></LinearLayout><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"><Viewandroid:layout_width="0dp"android:layout_height="60dp"android:layout_weight="2"android:background="#032898" /><TextViewandroid:layout_width="0dp"android:layout_height="60dp"android:layout_weight="1"android:gravity="center"android:text="#032898" /></LinearLayout><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"><Viewandroid:layout_width="0dp"android:layout_height="60dp"android:layout_weight="2"android:background="#021173" /><TextViewandroid:layout_width="0dp"android:layout_height="60dp"android:layout_weight="1"android:gravity="center"android:text="#021173" /></LinearLayout><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"><Viewandroid:layout_width="0dp"android:layout_height="60dp"android:layout_weight="2"android:background="#504DAE" /><TextViewandroid:layout_width="0dp"android:layout_height="60dp"android:layout_weight="1"android:gravity="center"android:text="#504DAE" /></LinearLayout><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"><Viewandroid:layout_width="0dp"android:layout_height="60dp"android:layout_weight="2"android:background="#3C60A6" /><TextViewandroid:layout_width="0dp"android:layout_height="60dp"android:layout_weight="1"android:gravity="center"android:text="#3C60A6" /></LinearLayout><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"><Viewandroid:layout_width="0dp"android:layout_height="60dp"android:layout_weight="2"android:background="#282EA8" /><TextViewandroid:layout_width="0dp"android:layout_height="60dp"android:layout_weight="1"android:gravity="center"android:text="#282EA8" /></LinearLayout><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"><Viewandroid:layout_width="0dp"android:layout_height="60dp"android:layout_weight="2"android:background="#273523" /><TextViewandroid:layout_width="0dp"android:layout_height="60dp"android:layout_weight="1"android:gravity="center"android:text="##5E7559" /></LinearLayout><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"><Viewandroid:layout_width="0dp"android:layout_height="60dp"android:layout_weight="2"android:background="#0E1E73" /><TextViewandroid:layout_width="0dp"android:layout_height="60dp"android:layout_weight="1"android:gravity="center"android:text="#0E1E73" /></LinearLayout><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"><Viewandroid:layout_width="0dp"android:layout_height="60dp"android:layout_weight="2"android:background="#305BC8" /><TextViewandroid:layout_width="0dp"android:layout_height="60dp"android:layout_weight="1"android:gravity="center"android:text="#305BC8" /></LinearLayout><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"><Viewandroid:layout_width="0dp"android:layout_height="60dp"android:layout_weight="2"android:background="#282EA8" /><TextViewandroid:layout_width="0dp"android:layout_height="60dp"android:layout_weight="1"android:gravity="center"android:text="#282EA8" /></LinearLayout><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"><Viewandroid:layout_width="0dp"android:layout_height="60dp"android:layout_weight="2"android:background="#0B685E" /><TextViewandroid:layout_width="0dp"android:layout_height="60dp"android:layout_weight="1"android:gravity="center"android:text="#0B685E" /></LinearLayout><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"><Viewandroid:layout_width="0dp"android:layout_height="60dp"android:layout_weight="2"android:background="#263B7E" /><TextViewandroid:layout_width="0dp"android:layout_height="60dp"android:layout_weight="1"android:gravity="center"android:text="#263B7E" /></LinearLayout><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"><Viewandroid:layout_width="0dp"android:layout_height="60dp"android:layout_weight="2"android:background="#0A7AC5" /><TextViewandroid:layout_width="0dp"android:layout_height="60dp"android:layout_weight="1"android:gravity="center"android:text="#0A7AC5" /></LinearLayout></LinearLayout></com.example.scrollview.ReboundScrollView>
结语
代码转载自该篇博客:http://t.csdn.cn/uIkEN
Android|重写ScrollView实现页面越界回弹效果相关推荐
- Android 列表越界回弹效果实现
一.越界回弹效果的例子 二.效果拆分 下拉.上拉越界回弹:已到达列表顶部,执行下拉操作,此时会进行越界回弹 惯性滑动 越界回弹:快速滑动列表,列表已到达底部,但由于惯性会继续前进一部分,此时会根据速度 ...
- Android实现背景图下拉回弹效果
Android实现背景图下拉回弹效果 增加设置不横向拉伸时增加回弹效果 增加切换横屏时可滑动效果 效果 实现 public class HeadZoomScrollView extends Neste ...
- Android 实现类似微信页面底部导航效果
Android 实现类似微信页面底部导航效果 参考的时候需要修改的地方做一下更改,里面有一些多余的代码没有删除. .java里面的主要代码 public class MainActivity exte ...
- Android仿Ios下拉回弹,Android ReboundScrollView仿IOS拖拽回弹效果
初衷: 其实github上有很多这种ScrollView的项目,但是不得不说功能太多太乱了,我就只是想要一个简单效果的ScrollView,另外监听下滑动距离而已,想想还是自己写了个. 这里先说下思路 ...
- android组件的下拉回弹,Android自定义控件仿ios下拉回弹效果
网上有很多类似的文章,大多数还是继承listview来实现(主要是listview.addHeaderView()和listview.addFooterView在listview的首尾添加view,也 ...
- 手机端html回弹,处理iOS微信H5页面橡皮回弹效果
- android 列表回弹效果,Android ListView ScrollView回弹效果
ios中对可以滚动的视图都在系统层面上实现了触碰到边缘的阻尼回弹效果,用户一看便知自己的操作已经到了边界.android中也有类似的方案,不过当到达边界的时候不是用阻尼的方式,而是逐渐显示一个渐变颜色 ...
- Android回弹效果新思考与更加易用的实现
前言 最近app需要在首页上做一个类似iOS的回弹效果, 我们的首页是一个ExpandableListView, 如果要做到类似iOS的回弹效果, 最先想到的思路就是使用额外添加的Header和Foo ...
- Android 对ScrollView滚动监听,实现美团、大众点评的购买悬浮效果
转帖请注明本文出自xiaanming的博客(http://blog.csdn.net/xiaanming),请尊重他人的辛勤劳动成果,谢谢! 随着移动互联网的快速发展,它已经和我们的生活息息相关了,在 ...
最新文章
- 影响和改变世界的50件发明专利,猜下中国有几个?
- 平方剩余(二次剩余)
- 组合查询(机房重构知识点总结)
- STM32的FLASH ID加密
- 最近ゲームにはまってる。
- 这可能是最简单又有效的自监督学习方法了
- roundcube邮箱手机端_求一款能够云备份的安卓手机便签记事本?
- 什么是Docker?看这一篇干货文章就够了!
- 0113——代理模式
- 窗口拖动后,还原窗口位置
- 讲幻灯片的基本技巧——2021年中会议发言之二
- 阀体端面钻6孔组合机床设计及夹具设计
- devc 能优化吗_Devc 、一元多项式的加法、减法、乘法的实现
【问题描述】
设有 联合开发网 - pudn.com...
- JAVA循环嵌套 方法的定义与重载 数组 数组异常 练习
- 【预测模型】基于遗传算法优化最小二乘支持向量机lssvm实现数据预测matlab代码
- 2019年信息泄露事件汇总
- h3c s5820交换机_简单配置
- linux 限制单个ip流量,centos 的单ip流量控制-CentOS下利用iptables限速及限制每IP连接数...
- 2008 go server sql 批处理_Transact-SQL批处理
- 微信小程序-一次性订阅消息推送
热门文章
- 移动端px和rem的换算
- 报考PMP怕上当,都会遇到哪些坑,我该如何避开这些坑?
- 手机号 imsi tmsi_《天网行动》就剧中出现个人手机号致歉 机主称仍打算起诉
- 有效管理自己知识,多总结和分享——2018七月份的尾巴
- ABAP BAPI_PO_CREATE1 净价net_price 无效
- 纯css实现坤坤经典动作-“铁山靠”
- 商汤科技20年秋招智慧城市-数据运营工程师笔试题(2019.8.19)
- hadoop 集群启动 ERROR: Cannot write datanode pid /tmp/hadoop-user-datanode.pid. 问题的解决
- 牛客寒假算法基础集训营6 I wzoi
- David P.Williams论文系列 合成孔径声纳图像快速目标检测:一种新算法及大规模性能分析