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阻尼效果的更多相关文章

  1. android 自定义ScrollView实现背景图片伸缩(阻尼效果)

    android 自定义ScrollView实现强调内容背景图片伸缩(仿多米,qq空间背景的刷新) 看到一篇文章,自己更改了一下bug: 原文地址:http://www.aiuxian.com/arti ...

  2. DampView阻尼效果

    阻尼效果即是图片向下拉动时会放大,松开会回弹 1.自定义一个DampView类,继承ScrollView 2.布局最外层必须是DampView,且DampView和要拉动的图片之间只能有一层layou ...

  3. ScrollView的阻尼回弹效果实现(仿qq空间)

    玩过新浪微博,qq空间等手机客户端的童鞋,都应该清楚,在主界面向下滑动时,会有一个阻尼回弹效果,看起来挺不错,接下来我们就来实现一下这种效果,下拉后回弹刷新界面,先看效果图: 这个是编辑器里面的界面效 ...

  4. ScrollView嵌套ListView,GridView数据加载不全问题的解决

    我们大家都知道ListView,GridView加载数据项,如果数据项过多时,就会显示滚动条.ScrollView组件里面只能包含一个组件,当ScrollView里面嵌套listView,GridVi ...

  5. Android ScrollView监听滑动到顶部和底部的两种方式(你可能不知道的细节)

    Android ScrollView监听滑动到顶部和底部,虽然网上很多资料都有说,但是不全,而且有些细节没说清楚 使用场景: 1. 做一些复杂动画的时候,需要动态判断当前的ScrollView是否滚动 ...

  6. React-Native学习系列(二) Image和ScrollView

    接下来,我们接着(一)继续讲,今天我们学习的是Image组件和ScrollView组件. Image组件 Image:一个用于显示多种不同类型图片的React组件.那么要如何使用呢? 引入本地图片: ...

  7. iOS学习笔记——滚动视图(scrollView)

    滚动视图:在根视图中添加UIScrollViewDelegate协议,声明一些对象属性 @interface BoViewController : UIViewController<UIScro ...

  8. 实现下来ScrollView放大轮播图

    创建工程,创建一个UIScrollView属性,并遵循其协议: #define kWidth self.view.frame.size.width//屏幕宽 #define kHeight self. ...

  9. React Native之 ScrollView介绍和使用

    前言 学习本系列内容需要具备一定 HTML 开发基础,没有基础的朋友可以先转至 HTML快速入门(一) 学习 本人接触 React Native 时间并不是特别长,所以对其中的内容和性质了解可能会有所 ...

随机推荐

  1. nvm、npm、nodejs的关系(转载)

    nvm.npm.nodejs的关系 为什么要了解nvm.npm.nodejs的关系: reactNative的项目构建都是有这几个工具进行构建管理. 掌握他们的关系,就能了解reactNative项目 ...

  2. Low Speed High Torque Hydraulic Motor: Motion Performance

    Crank connecting rod type low speed high torque hydraulic motor is used earlier, which is called Sta ...

  3. POJ - 3126 - Prime Path(BFS)

    Prime Path POJ - 3126 题意: 给出两个四位素数 a , b.然后从a开始,每次可以改变四位中的一位数字,变成 c,c 可以接着变,直到变成b为止.要求 c 必须是素数.求变换次数 ...

  4. C语言程序返回值为int的时候,不同值代表不同的意义

    这个是我自己给自己的代码定的标准,方便自己阅读与编码.他人代码情况不可套用 1 执行成功 0 出现错误,不影响程序执行 -1 执行失败 -2 程序内部致命错误,退出程序

  5. bzoj3336 Uva10572 Black and White

    题目描述: 数据范围:2<=n,m<=8 题解: 很明显需要状压.但是怎么压不知道,压什么不知道. 然后从条件下手. 条件1要求黑色在一起白色在一起,记录轮廓线很容易做到. 条件2要求不能 ...

  6. Java方法传递参数传值还是传址的问题

    这几天重构项目代码遇到一个疑问:可不可以在方法A中定义一个boolean变量b为false,然后A调用方法C把b传递到C方法中经过一些列业务判断后修改为true,C执行结束后A方法中b的值还是原来的f ...

  7. LeetCode(101)Symmetric Tree

    题目 Given a binary tree, check whether it is a mirror of itself (ie, symmetric around its center). Fo ...

  8. angular2 启动步骤

    以下内容转自网络 1. 创建项目文件夹 创建一个新的文件夹来保存你的项目,比如一开始有个self就好了 2.安装基础库 首先确保已经安装了node.js 我们使用 npm package manage ...

  9. notepad++编辑器写python需注意使用utf-8编码

    语言:python3.4 文本编辑器:notepad++ 报错:SyntaxError: (unicode error) 'utf-8' codec can't decode byte 0xb4 in ...

  10. Python变量及数据类型

    所有编程语言几乎都会有 ’ 变量‘ ,如 a = 2,用一个a变量指代数字2,在Python中,一切皆对象,因此在变量赋值的时候实际上是在内存中开辟了一块存储变量内容的内存空间对象. 对象可以指定不同 ...