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 时间并不是特别长,所以对其中的内容和性质了解可能会有所 ...
随机推荐
- 理解 Word2Vec 之 Skip-Gram 模型
理解 Word2Vec 之 Skip-Gram 模型 天雨粟 模型师傅 / 果粉 https://zhuanlan.zhihu.com/p/27234078 508 人赞同了该文章 注明:我发现知乎有 ...
- 在ios中使用FMDB
SQLite (http://www.sqlite.org/docs.html) 是一个轻量级的关系数据库.iOS SDK很早就支持了SQLite,在使用时,只需要加入 libsqlite3.dyli ...
- avalon转成Vue
需求: 旧项目中有部分页面是用avalon写的,avalon存在页面刷新,会出现重复行的问题,数组渲染出现重复行bug, 需要转成vue 总结 记录了一下大概需要改的地方 1. avalon中的ms- ...
- Global Round 2
A - Ilya and a Colorful Walk CodeForces - 1119A Ilya lives in a beautiful city of Chordalsk. There a ...
- poj3710 Christmas Game
题目描述 题解: 树上删边. 对于奇数长度的环,可以看做一条边. 对于偶数长度的环,可以看做什么都没有. 没有特别好的解释…… 代码: #include<cstdio> #include& ...
- Linux test命令
test命令 长格式的例子: test "$A" == "$B" && echo "Strings are equal" t ...
- POJ 3468 A Simple Problem with Integers (线段树多点更新模板)
题意: 给定一个区间, 每个区间有一个初值, 然后给出Q个操作, C a b c是给[a,b]中每个数加上c, Q a b 是查询[a,b]的和 代码: #include <cstdio> ...
- luogu2234 [HNOI2002]营业额统计
treap水过 #include <iostream> #include <cstdlib> #include <cstdio> using namespace s ...
- js总结(二):函数、作用域和this
function Container( properties ) { var objthis = this; for ( var i in properties ) { (function(){ // ...
- SQL server将某个字符串将按指定字符分解成子字符串(行转列)
今天突然需要用到这样的方法,在网上找过很多,大体都写的很复杂,这个简单实用.转载自ChineseMoonGod的博客:https://www.cnblogs.com/ChineseMoonGod/p/ ...