自定义ScrollView 实现上拉下拉的回弹效果--并且子控件中有Viewpager的情况

onInterceptTouchEvent就是对子控件中Viewpager的处理:左右滑动应该让viewpager消费
public class MyScrollView extends ScrollView {
private View childView;
public MyScrollView(Context context) {
super(context);
}
public MyScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MyScrollView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
// @Override
// protected void onLayout(boolean changed, int l, int t, int r, int b) {
// super.onLayout(changed, l, t, r, b);
// }
//获取子视图
@Override
protected void onFinishInflate() {
super.onFinishInflate();
if (getChildCount() > ) {
childView = getChildAt();
}
}
private int lastY;//上一次y轴方向操作的坐标位置
private Rect normal = new Rect();//用于记录临界状态的左、上、右、下
private boolean isFinishAnimation = true;//是否动画结束
private int lastX, downX, downY;
//拦截:实现父视图对子视图的拦截
//是否拦截成功,取决于方法的返回值。返回值true:拦截成功。反之,拦截失败
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
boolean isIntercept = false;
int eventX = (int) ev.getX();
int eventY = (int) ev.getY();
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
lastX = downX = eventX;
lastY = downY = eventY;
break;
case MotionEvent.ACTION_MOVE:
//获取水平和垂直方向的移动距离
int absX = Math.abs(eventX - downX);
int absY = Math.abs(eventY - downY);
if(absY > absX && absY >= UIUtils.dp2px()){
isIntercept = true;//执行拦截
}
lastX = eventX;
lastY = eventY;
break;
}
return isIntercept;
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
if (childView == null || !isFinishAnimation) {
return super.onTouchEvent(ev);
}
int eventY = (int) ev.getY();//获取当前的y轴坐标
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
lastY = eventY;
break;
case MotionEvent.ACTION_MOVE:
int dy = eventY - lastY;//微小的移动量
if (isNeedMove()) {
if (normal.isEmpty()) {
//记录了childView的临界状态的左、上、右、下
normal.set(childView.getLeft(), childView.getTop(), childView.getRight(), childView.getBottom());
}
//重新布局
childView.layout(childView.getLeft(), childView.getTop() + dy / , childView.getRight(), childView.getBottom() + dy / );
}
lastY = eventY;//重新赋值
break;
case MotionEvent.ACTION_UP:
if (isNeedAnimation()) {
//使用平移动画
int translateY = childView.getBottom() - normal.bottom;
TranslateAnimation translateAnimation = new TranslateAnimation(, , , -translateY);
translateAnimation.setDuration();
// translateAnimation.setFillAfter(true);//停留在最终位置上
translateAnimation.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
isFinishAnimation = false;
}
@Override
public void onAnimationEnd(Animation animation) {
isFinishAnimation = true;
childView.clearAnimation();//清除动画
//重新布局
childView.layout(normal.left, normal.top, normal.right, normal.bottom);
//清除normal的数据
normal.setEmpty();
}
@Override
public void onAnimationRepeat(Animation animation) {
}
});
//启动动画
childView.startAnimation(translateAnimation);
}
break;
}
return super.onTouchEvent(ev);
}
//判断是否需要执行平移动画
private boolean isNeedAnimation() {
return !normal.isEmpty();
}
private boolean isNeedMove() {
int childMeasuredHeight = childView.getMeasuredHeight();//获取子视图的高度
int scrollViewMeasuredHeight = this.getMeasuredHeight();//获取布局的高度
Log.e("TAG", "childMeasuredHeight = " + childMeasuredHeight);
Log.e("TAG", "scrollViewMeasuredHeight = " + scrollViewMeasuredHeight);
int dy = childMeasuredHeight - scrollViewMeasuredHeight;//dy >= 0
int scrollY = this.getScrollY();//获取用户在y轴方向上的偏移量 (上 + 下 -)
if (scrollY <= || scrollY >= dy) {
return true;//按照我们自定义的MyScrollView的方式处理
}
//其他处在临界范围内的,返回false。即表示,仍按照ScrollView的方式处理
return false;
}
}
自定义ScrollView 实现上拉下拉的回弹效果--并且子控件中有Viewpager的情况的更多相关文章
- Android 自定义ScrollView 支持惯性滑动,惯性回弹效果。支持上拉加载更多
先讲下原理: ScrollView的子View 主要分为3部分:head头部,滚动内容,fooder底部 我们实现惯性滑动,以及回弹,都是靠超过head或者fooder 就重新滚动到 ,内容的顶部或 ...
- 解决iscroll.js上拉下拉刷新手指划出屏幕页面无法回弹问题
博客已迁移至http://zlwis.me. 使用过iscroll.js的上拉下拉刷新效果的朋友应该都碰到过这个问题:在iOS的浏览器中,上拉或下拉刷新时,当手指划出屏幕后,页面无法弹回.很多人因为解 ...
- 打造android万能上拉下拉刷新框架——XRefreshView (二)
打造Android万能上拉下拉刷新框架--XRefreshView(一) 打造Android万能上拉下拉刷新框架--XRefreshView(三) 一.前言 自从上次发表了打造android万能上拉下 ...
- iOS不得姐项目--推荐关注模块(一个控制器控制两个tableView),数据重复请求的问题,分页数据的加载,上拉下拉刷新(MJRefresh)
一.推荐关注模块(一个控制器控制两个tableView) -- 数据的显示 刚开始加载数据值得注意的有以下几点 导航控制器会自动调整scrollView的contentInset,最好是取消系统的设置 ...
- ListView实现上拉下拉刷新加载功能
第一步.首先在你项目中创建一个包存放支持下拉刷新和上拉加载的类:
- 打造Android万能上拉下拉刷新框架--XRefreshView(三)
转载请注明出处:http://blog.csdn.net/footballclub/ 打造Android万能上拉下拉刷新框架–XRefreshView(一) 打造Android万能上拉下拉刷新框架–X ...
- iOS不得姐项目--精华模块上拉下拉的注意事项,日期显示,重构子控制器,计算cell的高度(只计算一次),图片帖子的显示
一.上拉下拉注意事项 使用MJRefresh中的上拉控件自动设置透明 当请求下页数据通过page的时候,注意的是上拉加载更多数据失败的问题,下拉加载数据失败了,页数应该还原.或者是请求成功的时候再将页 ...
- 练习使用XRecyclerView,可上拉下拉刷新。
package com.lixu.testxrecyclerview; import android.support.v7.app.AppCompatActivity; import android. ...
- swift实现UItableview上拉下拉刷新模块
最近用写个项目 发现上拉下拉刷新模块没找到合适的 so 自己写了一个 由于最近忙 教程就不写了 里面有 直接贴地址https://github.com/DaChengTechnology/DCRefr ...
随机推荐
- spring boot、cloud v2.1.0.RELEASE 使用及技术整理
2018年10月30日 springboot v2.1.0.RELEASE 发布: https://github.com/spring-projects/spring-boot/releases/ta ...
- docker:(2)通过Dockerfile构建镜像并发布web项目
上一篇讲解了docker的基本使用 http://www.cnblogs.com/xiaochangwei/p/8204511.html 虽然通过修改获取到的镜像可以达到使用目的,但是多操作几次就会发 ...
- MySQL:基础架构和工作流程
[参考文章]:01|基础架构:一条查询语句的执行流程 1. 基本架构 大体来说,MySQL可以分为Server层和存储引擎两部分. Server层包括链接器,分析器,优化器,执行器等,涵盖大多数核心服 ...
- Maven classifier 元素妙用
首先来看这么一个依赖 <dependency> <groupId>net.sf.json-lib</groupId> <artifactId>json- ...
- 第二篇:SpringBoot2.0整合ActiveMQ
本篇开始将具体介绍SpringBoot如何整合其它项目. 如何创建SpringBoot项目 访问https://start.spring.io/. 依次选择构建工具Maven Project.语言ja ...
- (转)eclipse上传项目到码云
把Eclipse项目上传到码云的步骤: 1.登录码云:新建项目 2.输入项目名: 3.空项目创建成功如下图: 4.右键点击Eclipse的项目,选择“Team”—————->“Share Pro ...
- FFmpeg使用基础
本文为作者原创,转载请注明出处:https://www.cnblogs.com/leisure_chn/p/10297002.html 本文介绍FFmpeg最基础的概念,了解FFmpeg的简单使用,帮 ...
- DML和索引内部结构变化
1.修改数据对索引结构的影响 合适的索引对查询性能和效率的提升是巨大的,但是万事有利有弊,拥有索引的表在增.删.改记录时需要去维护索引.如何让增.删.改更快速更高效?这就需要了解数据修改时对索引结构会 ...
- Linux 命令行下光标移动快捷键
常用的快捷键: Ctrl + u 删除光标之前到行首的字符 Ctrl + k 删除光标之后到行尾的字符 Ctrl + a 光标移动到行首 Ctrl + e 光标移动到行尾 Ctrl + l 清屏 Al ...
- [转]JS实现千分位
本文转自:https://www.cnblogs.com/lvmylife/p/8287247.html 方法一:正则实现 function format (num) { var reg=/\d{1, ...