• 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);
    		}
    }
    


  • 相关阅读:
    如何把数字字符'1'转换为整数(java 实现)
    栈之括号匹配问题(java实现)
    Python之匿名函数(filter,map,reduce)
    python之选择排序
    python之插入排序
    python之数组元素去重
    Java中如何获取多维数组的长度
    ASP.NET 页生命周期概述
    项目中Ajax调用ashx页面中的Function的实战
    Jquery Ajax处理,服务端三种页面aspx,ashx,asmx的比较
  • 原文地址:https://www.cnblogs.com/brucemengbm/p/7191278.html
Copyright © 2020-2023  润新知