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);
		}
}
时间: 2024-11-07 04:35:48

ScrollView阻尼效果的相关文章

除去ScrollVIew拉到尽头时再拉的阴影效果和个别机型的阻尼效果

去掉衰退边缘 android:fadingEdge="none" 去掉阴影效果和阻尼效果 android:overScrollMode="never" 版权声明:本文为博主原创文章,未经博主允许不得转载.

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

玩过新浪微博,qq空间等手机客户端的童鞋,都应该清楚,在主界面向下滑动时,会有一个阻尼回弹效果,看起来挺不错,接下来我们就来实现一下这种效果,下拉后回弹刷新界面,先看效果图: 这个是编辑器里面的界面效果,不言自明: 运行效果: 正常界面下: 下拉: 下拉结束: 实现代码: 主要部分就是重写的ScrollView: package com.byl.scollower; import android.content.Context; import android.graphics.Rect; imp

Android零基础入门第61节:滚动视图ScrollView

原文:Android零基础入门第61节:滚动视图ScrollView 前面几期学习了ProgressBar系列组件.ViewAnimator系列组件.Picker系列组件和时间日期系列组件,接下来几期继续来学习常见的其他组件. 一.ScrollView概述 从前面的学习有的同学可能已经发现,当拥有很多内容时屏幕显示不完,显示不全的部分完全看不见.但是在实际项目里面,很多内容都不止一个屏幕宽度或高度,那怎么办呢?那就需要本节学习的ScrollView来完成. 在默认情况下,ScrollView只是

Android ScrollView 滚动到顶部

有时候使用ScrollView,里边控件比较多的时候,打开界面,会滑到底部,如果要设置滑动到顶部,一般有两种方法 1.使用fullScrol(),scrollView.fullScroll(ScrollView.FOCUS_DOWN);滚动到底部 scrollView.fullScroll(ScrollView.FOCUS_UP);滚动到顶部 需要注意的是,该方法不能直接被调用 因为Android很多函数都是基于消息队列来同步,所以需要一部操作, addView完之后,不等于马上就会显示,而是在

Android仿qq回弹阻尼ScrollView

仿qq写一个可以来回弹的ScrollView. 只需要重写ScrollView: public class MyScrollView extends ScrollView {     // y方向上当前触摸点的前一次记录位置     private int previousY = 0;     // y方向上的触摸点的起始记录位置     private int startY = 0;     // y方向上的触摸点当前记录位置     private int currentY = 0;    

Android的GridView和ScrollView的嵌套

来源于回答频道答题,因此内容都是基于回答频道的原题布局进行 1.布局文件如下 文件名:testxm.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" andr

一句话让你的ScrollView、ListView弹力十足

android默认的ScrollView.ListView在最顶端下拉或者最底端上拉的时候,都不会带有反弹效果,很生硬的让你不能继续拖动,不像iOS那样可以回弹,个人认为,iOS的交互还是略好一点,那么我们也来在Android下实现下这个功能,先看下效果图: 那么我们今天的目标是一句话实现,如何去做呢 我们还是先看下代码: package com.xys.flexible; import android.content.Context; import android.util.Attribute

Android 控制ScrollView滚动到底部

这里有两种办法,第一种,使用scrollTo(): ublic static void scrollToBottom(final View scroll, final View inner) { Handler mHandler = new Handler(); mHandler.post(new Runnable() { public void run() { if (scroll == null || inner == null) { return; } int offset = inner

cocos2d js ScrollView的使用方法

游戏中非常多须要用到ScrollView的情况,也就是须要滚动一片区域. 这里有两种实现方法,一种是使用cocos studio的方式,另外一种是手写代码.先看第一种 第一种记得在设置滚动区域时选取裁剪项. var size = cc.winSize; //读取json文件 var root = ccs.uiReader.widgetFromJsonFile(res.listJson); this.addChild(root); //获取在cocos studio里面设定好的scrollView