公司项目,需要用到ScrollView的下拉刷新,一开始使用的时候PullToRefresh三方库的下拉刷新,我比较纠结第三档库,很强大,但是,公司项目的需求,PullToRefresh就不能做到了,改来改去的还是自己写一个下拉刷新比较靠谱,很多东西能够自己去控制。效果图就不上传了。直接解释关键代码。
ScrollView的下拉刷新比ListView的好做多了。
因为ScroTo的性质,ScrollView的下拉刷新,需要在外部添加一个父布局,通过父布局来控制触摸手势时候下传,什么时候下拉。
我自定义了一个PullScrollView
public class PullScrollView extends RelativeLayout
public PullScrollView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(context);
}
public PullScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
public PullScrollView(Context context) {
super(context);
init(context);
}
private Scroller mScroller ;
private int mTouchSlop ;
private void init(Context context){
ViewConfiguration configuration = ViewConfiguration.get(getContext());
mTouchSlop = configuration.getScaledTouchSlop();
mScroller = new Scroller(context, new DecelerateInterpolator());
}
首先是初始化mTouchSlop 是触摸手势滑动的最小像素值,也就是说滑动多少的距离才算是手势滑动,这样可以防止手势一点点的移动就引起的滑动事件。
mScroller 是用来处理平滑滚动的。之前的博客有介绍。
第二点:
@Override
protected void onFinishInflate() {
super.onFinishInflate();
if (getChildCount() > 2) {
throw new RuntimeException("子孩子只能有两个");
}
bottomView = (ViewGroup) getChildAt(0);
contentView = (ScrollView) getChildAt(1);
}
在布局初始化结束之后,得到布局中的两个子孩子,为啥只能有两个孩子那?? BottomView是用来下拉刷新展示的View contentView 就是我们的ScrollView了。如果子孩子多了,怎么知道哪个VIew是需要被隐藏的?所以只处理两个View的情况,当然,如果还有上拉加载更多,就需要三个子孩子了。
第三:
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
bottomHeight = getBottomViewHeight() ;
Log.i("Test", l + "ceshi" + " t="+t + " r"+r + " b=" + b + " height= " + bottomHeight);
bottomView.layout(l, - bottomHeight, r, t);
contentView.layout(l, 0, r, b);
}
onLayout,做过自定义的都应该很熟悉这个方法,放置子孩子位置的一个方法,因为我们需要有一个子孩子隐藏掉,当我们需要它显示的时候才去显示,所以 需要手动的去将BottomView放到布局-hight到0的位置,这样下拉的时候才能显示出来。
第四:
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
if (getScrollY() < 0 ) {
return true ;
}
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
startY = (int) ev.getY();
break;
case MotionEvent.ACTION_MOVE:
int moveY = (int) ev.getY();
int delayY = moveY - startY ;
Log.i("Test", delayY + " = " + mTouchSlop) ;
if (getTopPosition() && delayY > mTouchSlop) {
ev.setAction(MotionEvent.ACTION_DOWN);
return true ;
}
break ;
case MotionEvent.ACTION_UP:
break;
}
return super.onInterceptTouchEvent(ev);
}
手势的拦截动作,通过getTopPosition()方式,来判断ScrollView时候处于下拉需要显示隐藏子View的状态,delayY > mTouchSlop 是用来判断是不是下拉的动作的。 如果符合条件 我们就需要将手势拦截掉,return true。
为什么我觉得ScrollView做下来刷新比较好做那? 就是因为ScrollView的判断比较好判断。
private boolean getTopPosition(){
if (contentView.getScrollY() <= 0 ) {
return true ;
}
return false ;
}
是不是很简单!!!!
第五:
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
startY = (int) event.getY();
break;
case MotionEvent.ACTION_MOVE:
int delayY = (int) (event.getY() - startY) ;
if (getTopPosition() && getScrollY() <= 0 ) {
pullMove((int) (-delayY * 0.8)); // 跟随手势滑动
}
startY = (int) event.getY();
return true ;
case MotionEvent.ACTION_UP:
int scrollY = getScrollY();
if (state == PullState.ON_REFRESH && scrollY < 0 && Math.abs(scrollY) > bottomHeight) {
restView(-getScrollY() - bottomHeight); // 回弹到下拉刷新的状态
return true ;
}else if (state == PullState.ON_REFRESH && scrollY < 0 && Math.abs(scrollY) < bottomHeight) {
return true ;
}
if (scrollY < 0 && Math.abs(scrollY) < bottomHeight ) {
returnView(); // 回弹到原来的位置。
}else if (scrollY < 0 && Math.abs(scrollY) > bottomHeight && state != PullState.ON_REFRESH) {
if (onreListener != null) {
state = PullState.ON_REFRESH ;
onreListener.refresh(); // 回调函数
}
restView(-getScrollY() - bottomHeight);
}
break;
}
return true ;
}
这个就是做移动的处理手势的方法了。
ScrollView的下拉刷新比起Listview ,要好做的多了。哈哈………………
下面是源码附上,用做学习之用。代码还有不完善之处,等我项目完成之后,我会把项目中的封装很完善的下拉刷新代码重新打包上传。
下载地址: http://pan.baidu.com/s/1jG67mzc
- Android仿苹果版QQ下拉刷新实现(二) ——贝塞尔曲线开发"鼻涕"下拉粘连效果
前言 接着上一期Android仿苹果版QQ下拉刷新实现(一) ——打造简单平滑的通用下拉刷新控件 的博客开始,同样,在开始前我们先来看一下目标效果: 下面上一下本章需要实现的效果图: 大家看到这个效果 ...
- Android仿苹果版QQ下拉刷新实现(一) ——打造简单平滑的通用下拉刷新控件
前言: 忙完了结婚乐APP的开发,终于可以花一定的时间放在博客上了.好了,废话不多说,今天我们要带来的效果是苹果版本的QQ下拉刷新.首先看一下目标效果以及demo效果: 因为此效果实现的步骤 ...
- Android—自定义控件实现ListView下拉刷新
这篇博客为大家介绍一个android常见的功能——ListView下拉刷新(参考自他人博客,网址忘记了,阅读他的代码自己理解注释的,希望能帮助到大家): 首先下拉未松手时候手机显示这样的界面: 下面的 ...
- android 引用 project以及下拉刷新开源类库Android-PullToRefresh 的使用
Android-PullToRefresh 是一个github上的开源下拉刷新类库, GitHub .此外,该作者还有另外一个实用度和关注量极高的项目–另一种Android ActionBar的实现 ...
- Swift 自定义炫酷下拉刷新效果
先来看下效果 下拉刷新 其实下拉刷新没大家想得那么难.本文已第二个为例子.给大家讲解下下拉刷新的做法(完整代码后面会放上) 首先,先搞一个single View Application .然后进Mai ...
- Android实现RecyclerView的下拉刷新和上拉载入很多其它
需求 先上效果图, Material Design风格的下拉刷新和上拉载入很多其它. 源代码地址(欢迎star) https://github.com/studychen/SeeNewsV2 假设对于 ...
- 自定义ListView实现下拉刷新,下拉加载的功能
package com.loaderman.myrefreshlistviewdemo; import android.content.Context; import android.util.Att ...
- android SwipeRefreshLayout google官方下拉刷新控件
下拉刷新功能之前一直使用的是XlistView很方便我前面的博客有介绍 SwipeRefreshLayout是google官方推出的下拉刷新控件使用方法也比较简单 今天就来使用下SwipeRefres ...
- Android PullToRefresh (GridView 下拉刷新上拉加载)
做这个需要自己去git hub上下载个pull-to-refresh 里面有个library为依赖包自己导到自己的项目中 (下载地址:https://github.com/chrisbanes/And ...
随机推荐
- HTML 培训教程
HTML培训教程 1. HTML概述 1.1. 什么是 HTML 文件? n ...
- Java过滤器详细文档,简介,实例,应用
简介 Filter也称之为过滤器,它是Servlet技术中最激动人心的技术,WEB开发人员通过Filter技术,对web服务器管理的所有web资源:例如Jsp, Servlet, 静态图片文件或静态 ...
- flask-login
创建扩展对象实例 from flask_login import LoginManager login_manager = LoginManager() login_manager.login_vie ...
- 洛谷P2146 [NOI2015]软件包管理器
https://www.luogu.org/problemnew/show/P2146 传送门 简单的树链剖分......维护下当前安装了多少个包......修改后查询下就行了......附上极其丑陋 ...
- P2048 [NOI2010]超级钢琴
传送门 考虑维护前缀和 $sum[i]$ 那么对于每一个位置 $i$ ,左端点为 $i$ 右端点在 $[i+L-1,i+R-1]$ 区间的区间最大值容易维护 维护三元组 $(o,l,r)$ ,表示左端 ...
- Codeforces - 662A 思路巧妙的异或
题意:给你\(n\)堆石子玩尼姆博弈,每堆石子可以是\(a_i\)也可以是\(b_i\),选择概率相等且每堆选择相互独立,求先手必胜(异或不为0)的概率 首先需要找出一种优雅的策略表示方法(利用异或的 ...
- 怎样把ppt格式文件放到网页上?
方法一:把ppt文件的扩展名直接修改为pps,嵌入到网页中嵌入代码:缺点:这种方式浏览器会提示是打开,还是下载,选择打开的话会直接在浏览器中打开,并且客户端一定要安装Office PowerPoint ...
- HTTP security headers 安全头例子
这是从以下网站测试得到的结果,参考测试项目可以知道哪些安全头应该如何设置. https://observatory.mozilla.org/analyze.html?host=appcanary.co ...
- linux 工具(1)------终端提示符配置
Linux环境变量,PS1用于设置终端的提示符. 设置规则 设置方法 设置规则 \d :代表日期,格式为 Weekday Month Date,例如 "Mon Aug 1" \H ...
- vue-vli3创建的项目配置热更新
vue-vli3创建的项目配置热更新 问题描述:使用vue-cli3创建的项目,修改代码之后,浏览器页面不会自动刷新,然而之前使用webpack初始化的vue项目修改代码之后浏览器会重新加载一下,因为 ...