发现非常多APP的界面都能够滑动,QQ。微信等等,自己琢磨了下。效果例如以下:

代码:ScrollView

package com.wsj.wsjdemo;

import android.content.Context;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.TranslateAnimation;
import android.widget.ScrollView; /**
* ScrollView反弹效果的实现
*/
public class VScrollView extends ScrollView {
private View inner;// 孩子View
private float y;// 点击时y坐标
private int mLastMotionX;
private int mLastMotionY;
// 默认支持反弹效果
private boolean isAllowRebound = true;
private Rect normal = new Rect();// 矩形(这里仅仅是个形式。仅仅是用于推断是否须要动画.) private boolean isCount = false;// 是否開始计算 public VScrollView(Context context) {
super(context);
} public VScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
} public VScrollView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
} /***
* 依据 XML 生成视图工作完毕.该函数在生成视图的最后调用,在全部子视图加入完之后. 即使子类覆盖了 onFinishInflate
* 方法,也应该调用父类的方法,使该方法得以运行.
*/
@Override
protected void onFinishInflate() {
if (getChildCount() > 0) {
inner = getChildAt(0);
}
} public void setInnerView(View view) {
this.inner = view;
} @Override
public boolean onInterceptTouchEvent(MotionEvent e) {
int x = (int) e.getRawX();
int y = (int) e.getRawY();
switch (e.getAction()) {
case MotionEvent.ACTION_DOWN:
mLastMotionX = x;
mLastMotionY = y;
case MotionEvent.ACTION_MOVE:
int deltaX = x - mLastMotionX;
int deltaY = y - mLastMotionY;
if (Math.abs(deltaX) > 10 && Math.abs(deltaY) < 45) {
return false;
}
}
return super.onInterceptTouchEvent(e);
} /***
* 监听touch
*/
@Override
public boolean onTouchEvent(MotionEvent ev) {
if (inner != null && getAllowRebound()) {
commOnTouchEvent(ev);
}
return super.onTouchEvent(ev);
} /***
* 触摸事件
*
* @param 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;
/***
* 排除出第一次移动计算,由于第一次无法得知y坐标。 在MotionEvent.ACTION_DOWN中获取不到,
* 由于此时是MyScrollView的touch事件传递到到了LIstView的孩子item上面.所以从第二次计算開始.
* 然而我们也要进行初始化,就是第一次移动的时候让滑动距离归0. 之后记录准确了就正常运行.
*/
case MotionEvent.ACTION_MOVE:
final float preY = y;// 按下时的y坐标
float nowY = ev.getY();// 时时y坐标
int deltaY = (int) (preY - nowY);// 滑动距离
if (!isCount) {
deltaY = 0; // 在这里要归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(250);
inner.startAnimation(ta);
// 设置回到正常的布局位置
inner.layout(normal.left, normal.top, normal.right, normal.bottom); normal.setEmpty(); } // 是否须要开启动画
public boolean isNeedAnimation() {
return !normal.isEmpty();
} /***
* 是否须要移动布局 inner.getMeasuredHeight():获取的是控件的总高度
*
* getHeight():获取的是屏幕的高度
*
* @return
*/
public boolean isNeedMove() {
int offset = inner.getMeasuredHeight() - getHeight();
int scrollY = getScrollY();
// 0是顶部,后面那个是底部
if (scrollY == 0 || scrollY == offset) {
return true;
}
return false;
} public void scrollToTop() {
// this.setScrollY(0);
this.scrollTo(this.getLeft(), 0);
} public void scrollToBottom() {
// this.setScrollY(this.getHeight());
this.scrollTo(this.getLeft(), this.getHeight());
} public void setAllowRebound(boolean isAllowRebound) {
this.isAllowRebound = isAllowRebound;
} public boolean getAllowRebound() {
return this.isAllowRebound;
} }

Main方法:什么都没有

package com.wsj.wsjdemo;

import android.os.Bundle;
import android.app.Activity;
import android.view.Menu; public class MainActivity extends Activity { @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
} }

仅仅须要在布局仅仅用自己定义ScrollView包括内容就可以:

<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" > <com.wsj.wsjdemo.VScrollView
android:id="@+id/sv_mycenter"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal"
android:orientation="vertical"
android:scrollbars="none" > <LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" > <TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/hello_world" /> <TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/hello_world" /> <TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/hello_world" /> <TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/hello_world" /> <TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/hello_world" /> <TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/hello_world" /> <TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/hello_world" /> <TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/hello_world" /> <TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/hello_world" /> <TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/hello_world" /> <TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/hello_world" /> <TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/hello_world" /> <TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/hello_world" />
</LinearLayout>
</com.wsj.wsjdemo.VScrollView> </LinearLayout>

结束

ScrollView反弹效果的实现的更多相关文章

  1. ScrollView反弹效果 仿小米私密短信效果

    转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/28441197 如今非常多APP都给ScrollView加入了反弹效果.QQ.小米 ...

  2. ScrollView反弹效果

    public class BounceScrollView extends ScrollView { private View inner;// 孩子View private float y;// 点 ...

  3. Android 自定义ScrollView(具有反弹效果的ScrollView,能够兼容横向的滑动)

    package com.itau.jingdong.widgets; import android.content.Context; import android.graphics.Rect; imp ...

  4. 【Android】Android开发实现带有反弹效果,仿IOS反弹scrollview详解教程

    作者:程序员小冰,GitHub主页:https://github.com/QQ986945193 新浪微博:http://weibo.com/mcxiaobing 首先给大家看一下我们今天这个最终实现 ...

  5. Android -- 仿ios上下反弹效果

    1,前几天在一个app上看到了滑动反弹效果,觉得这个效果挺不错的,然后想自己来实现一下,在网上查了一下基本上都是大致的说了下思路,自己看了一下,决定把实现的思路来详细的写下来,先看一下我们实现的效果吧 ...

  6. WPF触控程序开发(三)——类似IPhone相册的反弹效果

    用过IPhone的都知道,IPhone相册里,当图片放大到一定程度后,手指一放,会自动缩回,移动图片超出边框后手指一放,图片也会自动缩回,整个过程非常和谐.自然.精确,那么WPF能否做到呢,答案是肯定 ...

  7. Android中的ScrollView实现 拖拽反弹效果

    public class BounceScrollView extends ScrollView { private View inner;// 孩子View private float y;// 点 ...

  8. Unity3D UGUI之ScrollView弹簧效果

    unity3d版本5.3.2p4 UGUI中ScrollView包含Viewport(Content) ScrollView包含脚本.其Movement Type一共3个选项.Elastic就是弹簧效 ...

  9. Scrollview回弹效果自定义控件

    滚动回弹效果分析: 首先,创建一个类,继承scrollview,重写ontouch事件,实现伸缩回弹效果. [scroollview节点下只能有一个子节点,这个子节点就是我们要移动的view布局]   ...

随机推荐

  1. python_for循环

    #for循环'''for i in range(0,10,2):age_oldboy = 56for i in range(3): guess_age = int(input("guess ...

  2. 命令行 对MYSQL导入sql

    1 use database name;  //选择使用的数据库 2 mysql>source d:\datafilename.sql  导入sql

  3. Spring中 @Autowired标签与 @Resource标签 的区别(转)

    spring不但支持自己定义的@Autowired注解,还支持由JSR-250规范定义的几个注解,如:@Resource. @PostConstruct及@PreDestroy. 1. @Autowi ...

  4. 零基础学HTML 5实战开发(第一季)

    開始学习html5了.趋势不得不学习啊,之前老毛说过落后就要挨打,如今是不学习就要被市场淘汰,被社会淘汰.喜欢挑战,喜欢冒险.来吧.csdn给我们提供了那么好的平台.用起来..零基础学HTML 5的实 ...

  5. 一个软件实现的Linux看门狗—soft_wdt

    soft_wdt(下面简称本软件)是一个软件实现的Linux看门狗. 本软件是一款开源.免费软件. 下载地址: https://github.com/sunmingbao/soft-wdt/archi ...

  6. jni javah

    如何通过javah生成jni头文件 1.javah的使用说明:   -classpath 给出包含native接口的java类的.class文件路径 -d / –o 指定生成的头文件的,-d只给出文件 ...

  7. codeblocks的c程序目录结构与执行过程

    执行过程 编译 形成 .o .obj 连接 形成.exe文件 执行 目录结构 主程序main.c #include <stdio.h> #include <stdlib.h> ...

  8. Python 异常(Exception)

    1. 字符串为构造函数的参数 >> raise Exception('hyperdirve overload') Exception Traceback (most recent call ...

  9. Defining and using constants from PySide in QML

    Defining and using constants from PySide in QML This PySide tutorial shows you how to define constan ...

  10. Ubuntu16.04+GTX 1080Ti+CUDA 8.0+cuDNN+Tesnorflow1.0深度学习服务器安装之路

    0.安装背景 系统:ubuntu 16.04 内核:4.4.0-140-generic GPU:GTX 1080Ti nvidia驱动版本: 384.111 cuda: CUDA 8.0 深度学习库c ...