android 鎖定ScrollView 使其滑到一定程度不能滑動
阿新 • • 發佈:2018-12-30
1) scrollTo 和 scrollBy
View自帶的兩個方法
左加右減,上加下減
2) 平滑效果,使用Scroller
- 建立Scroller的例項
- 呼叫startScroll()方法來初始化滾動資料並重新整理介面
- 重寫computeScroll()方法,並在其內部完成平滑滾動的邏輯
3) 案例:ScrollView滑到一定位置不能鎖定不能滑動了
package com.abilix.learn.dashpinyinisland1.view; import android.content.Context; import android.support.v4.view.ViewConfigurationCompat; import android.util.AttributeSet; import android.util.Log; import android.view.MotionEvent; import android.view.ViewConfiguration; import android.widget.ScrollView; import android.widget.Scroller; /** * Created by yanghd on 2017/6/9. */ public class SlowScrollView extends ScrollView { private Scroller mScroller; public SlowScrollView(Context context) { this(context,null); } public SlowScrollView(Context context, AttributeSet attrs) { super(context, attrs); // 第一步,建立Scroller的例項 mScroller = new Scroller(context); setUpBorder(2000); ViewConfiguration configuration = ViewConfiguration.get(context); // 獲取TouchSlop值 mTouchSlop = ViewConfigurationCompat.getScaledPagingTouchSlop(configuration); } public SlowScrollView(Context context, AttributeSet attrs, int defStyle) { this(context, attrs); } //呼叫此方法滾動到目標位置 duration滾動時間 public void smoothScrollToSlow(int fx, int fy, int duration) { int dx = fx - getScrollX();//mScroller.getFinalX(); 普通view使用這種方法 int dy = fy - getScrollY(); //mScroller.getFinalY(); smoothScrollBySlow(dx, dy, duration); } //呼叫此方法設定滾動的相對偏移 public void smoothScrollBySlow(int dx, int dy, int duration) { //設定mScroller的滾動偏移量 mScroller.startScroll(getScrollX(), getScrollY(), dx, dy, duration);//scrollView使用的方法(因為可以觸控拖動) // mScroller.startScroll(mScroller.getFinalX(), mScroller.getFinalY(), dx, dy, duration); //普通view使用的方法 invalidate();//這裡必須呼叫invalidate()才能保證computeScroll()會被呼叫,否則不一定會重新整理介面,看不到滾動效果 } @Override public void computeScroll() { //先判斷mScroller滾動是否完成 if (mScroller.computeScrollOffset()) { //這裡呼叫View的scrollTo()完成實際的滾動 scrollTo(mScroller.getCurrX(), mScroller.getCurrY()); //必須呼叫該方法,否則不一定能看到滾動效果 postInvalidate(); } super.computeScroll(); } /** * 滑動事件,這是控制手指滑動的慣性速度 */ @Override public void fling(int velocityY) { super.fling(velocityY / 400); } // ------------------- 新增方法 ------------------ /** * 手機當時所處的螢幕座標 */ private float mYMove; /** * 上次觸發ACTION_MOVE事件時的螢幕座標 */ private float mYLastMove; /** * 介面可滾動的上邊界 */ private int upBorder; /** * 手機按下時的螢幕座標 */ private float mYDown; /** * 判定為拖動的最小移動畫素數 */ private int mTouchSlop; /* @Override public boolean onInterceptTouchEvent(MotionEvent ev) { switch (ev.getAction()) { case MotionEvent.ACTION_DOWN: mYDown = ev.getRawY(); mYLastMove = mYDown; Log.d("SlowScrollView", "攔截Down"); break; case MotionEvent.ACTION_MOVE: mYMove = ev.getRawY(); float diff = Math.abs(mYMove - mYDown); mYLastMove = mYMove; // 當手指拖動值大於TouchSlop值時,認為應該進行滾動,攔截子控制元件的事件 if (diff > mTouchSlop) { Log.d("SlowScrollView", "diff:" + diff); Log.d("SlowScrollView", "mTouchSlop:" + mTouchSlop); Log.d("SlowScrollView", "攔截Move"); return true; } break; } return super.onInterceptTouchEvent(ev); }*/ @Override public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_MOVE: Log.d("SlowScrollView", "執行Move"); mYMove = event.getRawY(); int scrolledY = (int) (mYLastMove - mYMove); if (getScrollY() + scrolledY < upBorder) { scrollTo(0, upBorder); return true; } scrollBy(scrolledY, 0); mYLastMove = mYMove; break; case MotionEvent.ACTION_UP: Log.d("SlowScrollView", "執行Up"); /* // 當手指擡起時,根據當前的滾動值來判定應該滾動到哪個子控制元件的介面 int targetIndex = (getScrollX() + getWidth() / 2) / getWidth(); int dx = targetIndex * getWidth() - getScrollX(); // 第二步,呼叫startScroll()方法來初始化滾動資料並重新整理介面 mScroller.startScroll(getScrollX(), 0, dx, 0); invalidate();*/ break; } return super.onTouchEvent(event); } public void setUpBorder(int upBorder) { this.upBorder = upBorder; } }
其實可以直接不重寫 onInterceptTouchEvent 方法;