ScrollView阻尼效果
activity_main.xml
<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"
tools:context="com.example.scrollviewdemo.MainActivity" > <com.example.scrollviewdemo.CustomScrollView android:id="@+id/scrollview"
android:layout_width="fill_parent"
android:layout_height="fill_parent" > <LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" > <TextView
android:layout_width="fill_parent"
android:layout_height="100dp"
android:text="AAA" >
</TextView> <TextView
android:layout_width="fill_parent"
android:layout_height="100dp"
android:text="AAA" >
</TextView> <TextView
android:layout_width="fill_parent"
android:layout_height="100dp"
android:text="AAA" >
</TextView> <TextView
android:layout_width="fill_parent"
android:layout_height="100dp"
android:text="AAA" >
</TextView> <TextView
android:layout_width="fill_parent"
android:layout_height="100dp"
android:text="AAA" >
</TextView>
<TextView
android:layout_width="fill_parent"
android:layout_height="100dp"
android:text="AAA" >
</TextView>
<TextView
android:layout_width="fill_parent"
android:layout_height="100dp"
android:text="AAA" >
</TextView>
<TextView
android:layout_width="fill_parent"
android:layout_height="100dp"
android:text="AAA" >
</TextView>
<TextView
android:layout_width="fill_parent"
android:layout_height="100dp"
android:text="AAA" >
</TextView>
</LinearLayout>
</com.example.scrollviewdemo.CustomScrollView
> </LinearLayout>
MainActivity
package com.example.scrollviewdemo; import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.ScrollView; public class MainActivity extends Activity {
ScrollView scrollView;
private static final int TOUCH_EVENT_ID = 1; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
scrollView = (ScrollView) findViewById(R.id.scrollview); }
}
方式一
ElasticScrollView
package com.example.scrollviewdemo; import android.annotation.SuppressLint;
import android.content.Context;
import android.util.AttributeSet;
import android.widget.ScrollView;
import android.graphics.Rect;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.TranslateAnimation; public class ElasticScrollView extends ScrollView {
//scrollView下的控件
private View inner; private float y; //保存状态的矩形框
private Rect normal = new Rect(); //是否要计算
private boolean isCount = false; @SuppressLint("NewApi")
public ElasticScrollView(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) {
commOnTouchEvent(ev);
}
return super.onTouchEvent(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;
case MotionEvent.ACTION_MOVE:
final float preY = y;
float nowY = ev.getY();
int deltaY = (int) (preY - nowY);
if (!isCount) {
deltaY = 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(200);
inner.startAnimation(ta);
inner.layout(normal.left, normal.top, normal.right, normal.bottom);
normal.setEmpty(); } // return left >= right || top >= bottom;
public boolean isNeedAnimation() {
return !normal.isEmpty();
} public boolean isNeedMove() {
int offset = inner.getMeasuredHeight() - getHeight();
int scrollY = getScrollY();
if (scrollY == 0 || scrollY == offset) {
return true;
}
return false;
}
}
——————————————————————————方式二——————————————————————————
CustomScrollView
package com.example.scrollviewdemo; import android.content.Context;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.TranslateAnimation;
import android.widget.ScrollView; public class CustomScrollView extends ScrollView { // y方向上当前触摸点的前一次记录位置
private int previousY = 0;
// y方向上的触摸点的起始记录位置
private int startY = 0;
// y方向上的触摸点当前记录位置
private int currentY = 0;
// y方向上两次移动间移动的相对距离
private int deltaY = 0; // 第一个子视图
private View childView; // 用于记录childView的初始位置
private Rect topRect = new Rect(); public CustomScrollView(Context context) {
super(context);
;
} public CustomScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
;
} public CustomScrollView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
;
} @Override
protected void onFinishInflate() {
if (getChildCount() > 0) {
childView = getChildAt(0);
}
} @Override
public boolean dispatchTouchEvent(MotionEvent event) {
if (null == childView) {
return super.dispatchTouchEvent(event);
} switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
startY = (int) event.getY();
previousY = startY;
break;
case MotionEvent.ACTION_MOVE:
currentY = (int) event.getY();
deltaY = previousY - currentY;
previousY = currentY; if (0 == getScrollY()
|| childView.getMeasuredHeight() - getHeight() <= getScrollY()) {
// 记录childView的初始位置
if (topRect.isEmpty()) {
topRect.set(childView.getLeft(), childView.getTop(),
childView.getRight(), childView.getBottom());
} // 更新childView的位置
childView.layout(childView.getLeft(), childView.getTop()
- deltaY / 3, childView.getRight(),
childView.getBottom() - deltaY / 3);
}
break;
case MotionEvent.ACTION_UP:
if (!topRect.isEmpty()) {
upDownMoveAnimation();
// 子控件回到初始位置
childView.layout(topRect.left, topRect.top, topRect.right,
topRect.bottom);
} startY = 0;
currentY = 0;
topRect.setEmpty();
break;
default:
break;
} return super.dispatchTouchEvent(event);
} // 初始化上下回弹的动画效果
private void upDownMoveAnimation() {
TranslateAnimation animation = new TranslateAnimation(0.0f, 0.0f,
childView.getTop(), topRect.top);
animation.setDuration(200);
animation.setInterpolator(new AccelerateInterpolator());
childView.setAnimation(animation);
}
}
ScrollView阻尼效果的更多相关文章
- android 自定义ScrollView实现背景图片伸缩(阻尼效果)
android 自定义ScrollView实现强调内容背景图片伸缩(仿多米,qq空间背景的刷新) 看到一篇文章,自己更改了一下bug: 原文地址:http://www.aiuxian.com/arti ...
- DampView阻尼效果
阻尼效果即是图片向下拉动时会放大,松开会回弹 1.自定义一个DampView类,继承ScrollView 2.布局最外层必须是DampView,且DampView和要拉动的图片之间只能有一层layou ...
- ScrollView的阻尼回弹效果实现(仿qq空间)
玩过新浪微博,qq空间等手机客户端的童鞋,都应该清楚,在主界面向下滑动时,会有一个阻尼回弹效果,看起来挺不错,接下来我们就来实现一下这种效果,下拉后回弹刷新界面,先看效果图: 这个是编辑器里面的界面效 ...
- ScrollView嵌套ListView,GridView数据加载不全问题的解决
我们大家都知道ListView,GridView加载数据项,如果数据项过多时,就会显示滚动条.ScrollView组件里面只能包含一个组件,当ScrollView里面嵌套listView,GridVi ...
- Android ScrollView监听滑动到顶部和底部的两种方式(你可能不知道的细节)
Android ScrollView监听滑动到顶部和底部,虽然网上很多资料都有说,但是不全,而且有些细节没说清楚 使用场景: 1. 做一些复杂动画的时候,需要动态判断当前的ScrollView是否滚动 ...
- React-Native学习系列(二) Image和ScrollView
接下来,我们接着(一)继续讲,今天我们学习的是Image组件和ScrollView组件. Image组件 Image:一个用于显示多种不同类型图片的React组件.那么要如何使用呢? 引入本地图片: ...
- iOS学习笔记——滚动视图(scrollView)
滚动视图:在根视图中添加UIScrollViewDelegate协议,声明一些对象属性 @interface BoViewController : UIViewController<UIScro ...
- 实现下来ScrollView放大轮播图
创建工程,创建一个UIScrollView属性,并遵循其协议: #define kWidth self.view.frame.size.width//屏幕宽 #define kHeight self. ...
- React Native之 ScrollView介绍和使用
前言 学习本系列内容需要具备一定 HTML 开发基础,没有基础的朋友可以先转至 HTML快速入门(一) 学习 本人接触 React Native 时间并不是特别长,所以对其中的内容和性质了解可能会有所 ...
随机推荐
- 将自己的数据制作成voc格式
VOCdevkit2007文件下只保存VOC2007,VOC2007下只保存Annotations ImageSets JPEGImages. JPEGImages存放所有的图片数据(即训练测试验证的 ...
- C++静态全局变量和全局变量的区别
静态全局变量 非静态全局变量 存储方式 静态存储 静态存储 作用域 定义该变量的源文件内 所有源文件 解释: 共同点:全局变量(外部变量)的说明之前再冠以static 就构 成了静态的全局变量.全 ...
- CPP-基础:快速排序
快速排序(Quicksort)是对冒泡排序的一种改进. 它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分 ...
- 暑假集训 || 状压DP
emm 位操作实现技巧: 获得第i位的数据: if(!(data & (1<< i))) 则data的第 i 位为0,else 为 1 设置第i位为1,data=(data | ...
- install docker-ce for ubuntu
may need login vpn first docker-ce for ubuntu chinese version docker-ce for ubuntu
- VS2015安装SVN插件
一.下载VISUALlSVN 官网下载:地址 选择[VisualSVN for Visual Studio 2015 and older]的下载按钮下载,目前版本号VisualSVN 5.1.9,支持 ...
- 测试网站链接是否可用(wget和curl)
一.wget用法案例 系统给的命令参数如下: [root@litong_centos mysql3307]# wget --help GNU Wget 1.14, a non-interactive ...
- 如何用纯 CSS 创作一个金属光泽 3D 按钮特效
效果预览 在线演示 按下右侧的"点击预览"按钮在当前页面预览,点击链接全屏预览. https://codepen.io/zhang-ou/full/MGeRRO 可交互视频教程 此 ...
- 在cmd 命令中 用cd E:\ 进入不了E盘 问题
cd 路径 只能在本盘符中切换路径需要切换到e盘 需要cd /d e:\
- 简单的自动化使用--使用selenium实现学习通网站的刷慕课程序。注释空格加代码大概200行不到
简单的自动化使用--使用selenium实现学习通网站的刷慕课程序.注释空格加代码大概200行不到 相见恨晚啊 github地址 环境Python3.6 + pycharm + chrom浏览器 + ...