100字范文,内容丰富有趣,生活中的好帮手!
100字范文 > Android|重写ScrollView实现页面越界回弹效果

Android|重写ScrollView实现页面越界回弹效果

时间:2021-04-22 20:29:50

相关推荐

Android|重写ScrollView实现页面越界回弹效果

实现效果

实现方法

新建类ReboundScrollView.java,重写ScrollView方法:

package com.example.scrollview;import android.content.Context;import android.graphics.Rect;import android.util.AttributeSet;import android.view.MotionEvent;import android.view.View;import android.view.animation.Animation;import android.view.animation.TranslateAnimation;import android.widget.ScrollView;public class ReboundScrollView extends ScrollView {private boolean mEnableTopRebound = true;private boolean mEnableBottomRebound = true;private OnReboundEndListener mOnReboundEndListener;private View mContentView;private Rect mRect = new Rect();public ReboundScrollView(Context context) {super(context);}public ReboundScrollView(Context context, AttributeSet attrs) {super(context, attrs);}public ReboundScrollView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);}/*** after inflating view, we can get the width and height of view*/@Overrideprotected void onFinishInflate() {super.onFinishInflate();mContentView = getChildAt(0);}@Overrideprotected void onLayout(boolean changed, int l, int t, int r, int b) {super.onLayout(changed, l, t, r, b);if (mContentView == null) return;// to remember the location of mContentViewmRect.set(mContentView.getLeft(), mContentView.getTop(), mContentView.getRight(), mContentView.getBottom());}public ReboundScrollView setOnReboundEndListener(OnReboundEndListener onReboundEndListener) {this.mOnReboundEndListener = onReboundEndListener;return this;}public ReboundScrollView setEnableTopRebound(boolean enableTopRebound) {this.mEnableTopRebound = enableTopRebound;return this;}public ReboundScrollView setEnableBottomRebound(boolean mEnableBottomRebound) {this.mEnableBottomRebound = mEnableBottomRebound;return this;}private int lastY;private boolean rebound = false;private int reboundDirection = 0; //<0 表示下部回弹 >0 表示上部回弹 0表示不回弹@Overridepublic boolean dispatchTouchEvent(MotionEvent ev) {if (mContentView == null) {return super.dispatchTouchEvent(ev);}switch (ev.getAction()) {case MotionEvent.ACTION_DOWN:lastY = (int) ev.getY();break;case MotionEvent.ACTION_MOVE:if (!isScrollToTop() && !isScrollToBottom()) {lastY = (int) ev.getY();break;}//处于顶部或者底部int deltaY = (int) (ev.getY() - lastY);//deltaY > 0 下拉 deltaY < 0 上拉//disable top or bottom reboundif ((!mEnableTopRebound && deltaY > 0) || (!mEnableBottomRebound && deltaY < 0)) {break;}int offset = (int) (deltaY * 0.48);mContentView.layout(mRect.left, mRect.top + offset, mRect.right, mRect.bottom + offset);rebound = true;break;case MotionEvent.ACTION_UP:if (!rebound) break;reboundDirection = mContentView.getTop() - mRect.top;TranslateAnimation animation = new TranslateAnimation(0, 0, mContentView.getTop(), mRect.top);animation.setDuration(300);animation.setAnimationListener(new Animation.AnimationListener() {@Overridepublic void onAnimationStart(Animation animation) {}@Overridepublic void onAnimationEnd(Animation animation) {if (mOnReboundEndListener != null) {if (reboundDirection > 0) {mOnReboundEndListener.onReboundTopComplete();}if (reboundDirection < 0) {mOnReboundEndListener.onReboundBottomComplete();}reboundDirection = 0;}}@Overridepublic void onAnimationRepeat(Animation animation) {}});mContentView.startAnimation(animation);mContentView.layout(mRect.left, mRect.top, mRect.right, mRect.bottom);rebound = false;break;}return super.dispatchTouchEvent(ev);}@Overridepublic void setFillViewport(boolean fillViewport) {super.setFillViewport(true); //默认是填充ScrollView 或者再XML布局文件中设置fillViewport属性}/*** 判断当前ScrollView是否处于顶部*/private boolean isScrollToTop() {return getScrollY() == 0;}/*** 判断当前ScrollView是否已滑到底部*/private boolean isScrollToBottom() {return mContentView.getHeight() <= getHeight() + getScrollY();}/*** listener for top and bottom rebound* do your implement in the following methods*/public interface OnReboundEndListener {void onReboundTopComplete();void onReboundBottomComplete();}}

之后在XML文件中调用控件,即可实现效果:

Tips:记得改成自己的包名

<com.example.scrollview.ReboundScrollView xmlns:android="/apk/res/android"android:layout_height="match_parent"android:layout_width="match_parent"android:overScrollMode="never" ></com.example.scrollview.ReboundScrollView>

属性说明

//该属性取消到顶到底的自带光效android:overScrollMode="never"//该属性隐藏滚动条android:scrollbars="none"

全部代码

<?xml version="1.0" encoding="utf-8"?><com.example.scrollview.ReboundScrollView xmlns:android="/apk/res/android"android:layout_height="match_parent"android:layout_width="match_parent"android:overScrollMode="never" ><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="vertical"><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"><Viewandroid:layout_width="0dp"android:layout_height="60dp"android:layout_weight="2"android:background="#07C2FB" /><TextViewandroid:layout_width="0dp"android:layout_height="60dp"android:layout_weight="1"android:gravity="center"android:text="#07C2FB" /></LinearLayout><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"><Viewandroid:layout_width="0dp"android:layout_height="60dp"android:layout_weight="2"android:background="#C60426FD" /><TextViewandroid:layout_width="0dp"android:layout_height="60dp"android:layout_weight="1"android:gravity="center"android:text="#C60426FD" /></LinearLayout><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"><Viewandroid:layout_width="0dp"android:layout_height="60dp"android:layout_weight="2"android:background="#032898" /><TextViewandroid:layout_width="0dp"android:layout_height="60dp"android:layout_weight="1"android:gravity="center"android:text="#032898" /></LinearLayout><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"><Viewandroid:layout_width="0dp"android:layout_height="60dp"android:layout_weight="2"android:background="#021173" /><TextViewandroid:layout_width="0dp"android:layout_height="60dp"android:layout_weight="1"android:gravity="center"android:text="#021173" /></LinearLayout><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"><Viewandroid:layout_width="0dp"android:layout_height="60dp"android:layout_weight="2"android:background="#504DAE" /><TextViewandroid:layout_width="0dp"android:layout_height="60dp"android:layout_weight="1"android:gravity="center"android:text="#504DAE" /></LinearLayout><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"><Viewandroid:layout_width="0dp"android:layout_height="60dp"android:layout_weight="2"android:background="#3C60A6" /><TextViewandroid:layout_width="0dp"android:layout_height="60dp"android:layout_weight="1"android:gravity="center"android:text="#3C60A6" /></LinearLayout><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"><Viewandroid:layout_width="0dp"android:layout_height="60dp"android:layout_weight="2"android:background="#282EA8" /><TextViewandroid:layout_width="0dp"android:layout_height="60dp"android:layout_weight="1"android:gravity="center"android:text="#282EA8" /></LinearLayout><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"><Viewandroid:layout_width="0dp"android:layout_height="60dp"android:layout_weight="2"android:background="#273523" /><TextViewandroid:layout_width="0dp"android:layout_height="60dp"android:layout_weight="1"android:gravity="center"android:text="##5E7559" /></LinearLayout><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"><Viewandroid:layout_width="0dp"android:layout_height="60dp"android:layout_weight="2"android:background="#0E1E73" /><TextViewandroid:layout_width="0dp"android:layout_height="60dp"android:layout_weight="1"android:gravity="center"android:text="#0E1E73" /></LinearLayout><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"><Viewandroid:layout_width="0dp"android:layout_height="60dp"android:layout_weight="2"android:background="#305BC8" /><TextViewandroid:layout_width="0dp"android:layout_height="60dp"android:layout_weight="1"android:gravity="center"android:text="#305BC8" /></LinearLayout><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"><Viewandroid:layout_width="0dp"android:layout_height="60dp"android:layout_weight="2"android:background="#282EA8" /><TextViewandroid:layout_width="0dp"android:layout_height="60dp"android:layout_weight="1"android:gravity="center"android:text="#282EA8" /></LinearLayout><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"><Viewandroid:layout_width="0dp"android:layout_height="60dp"android:layout_weight="2"android:background="#0B685E" /><TextViewandroid:layout_width="0dp"android:layout_height="60dp"android:layout_weight="1"android:gravity="center"android:text="#0B685E" /></LinearLayout><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"><Viewandroid:layout_width="0dp"android:layout_height="60dp"android:layout_weight="2"android:background="#263B7E" /><TextViewandroid:layout_width="0dp"android:layout_height="60dp"android:layout_weight="1"android:gravity="center"android:text="#263B7E" /></LinearLayout><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"><Viewandroid:layout_width="0dp"android:layout_height="60dp"android:layout_weight="2"android:background="#0A7AC5" /><TextViewandroid:layout_width="0dp"android:layout_height="60dp"android:layout_weight="1"android:gravity="center"android:text="#0A7AC5" /></LinearLayout></LinearLayout></com.example.scrollview.ReboundScrollView>

结语

代码转载自该篇博客:/uIkEN

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。