Scroller是Android中一个辅助View滑动的一个工具。它可以使View滑动有一个平滑的效果。下面是Scroller的一个简单实现。</span>
主要是要调用Scroller的一些方法
startScroll(int startX, int startY, int dx, int dy, int duration)
</pre><pre name="code" class="java"> @Override public void computeScroll() { if (mScroller.computeScrollOffset()) { scrollTo(mScroller.getCurrX(), mScroller.getCurrY()); postInvalidate(); } }
下面是一个简单的应用。
package com.yyw.scrollerdemo; import android.content.Context; import android.content.res.TypedArray; import android.graphics.drawable.Drawable; import android.util.AttributeSet; import android.util.Log; import android.view.GestureDetector; import android.view.MotionEvent; import android.view.ViewGroup; import android.view.animation.DecelerateInterpolator; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.Scroller; /** * Created by yyw on 2016/4/28. */ public class SliderLayout extends LinearLayout { public static final String TAG = "SliderLayout"; private Scroller mScroller; private int totalNum = 8; private int index = 0; private ImageView mSlider; private GestureDetector detector; private Drawable mSliderImage; public SliderLayout(Context context) { this(context, null); } public SliderLayout(Context context, AttributeSet attrs) { this(context, attrs, 0); } public SliderLayout(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.SliderLayout); mSliderImage = array.getDrawable(R.styleable.SliderLayout_slider_pic); if (mSliderImage == null) { mSliderImage = context.getResources().getDrawable(R.drawable.slider); } array.recycle(); init(context); } public int getIndex() { return index; } public void setIndex(int index) { if (this.index != index && index < totalNum && index >= 0) { if (getOrientation() == HORIZONTAL){ horizontalScroll(index); }else { verticalScroll(index); } this.index = index; } } //水平滑动 private void horizontalScroll(int index) { int dx = (this.index - index) * (getWidth() / totalNum);//计算偏移量 if (mScroller.computeScrollOffset()) { mScroller.abortAnimation(); } mScroller.startScroll(mScroller.getFinalX(), 0, dx, 0);//开始移动 invalidate(); } //垂直滑动 private void verticalScroll(int index) { int dy = (this.index - index) * (getHeight() / totalNum);//计算偏移量 if (mScroller.computeScrollOffset()) { mScroller.abortAnimation(); } mScroller.startScroll(0, mScroller.getFinalY(), 0, dy);//开始移动 invalidate(); } public int getTotalNum() { return totalNum; } public void setTotalNum(int totalNum) { if (this.totalNum != totalNum && totalNum > 0) { this.totalNum = totalNum; if (index >= totalNum) { index = totalNum - 1; } resetSlider(); } } private void init(Context context) { detector = new GestureDetector(context, mOnGestureListener); mScroller = new Scroller(context, new DecelerateInterpolator()); mSlider = new ImageView(context); mSlider.setImageDrawable(mSliderImage); addView(mSlider, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { super.onLayout(changed, l, t, r, b); if (changed) { resetSlider(); } } /** * 重新设置滑块 */ private void resetSlider() { if (getOrientation() == HORIZONTAL) { resetHorizontalSlider(); }else { resetVerticalSlider(); } } private void resetVerticalSlider() { int scrollY = getScrollY(); int height = getHeight(); LayoutParams params = (LayoutParams) mSlider.getLayoutParams(); params.height = height / totalNum;//重新设置滑块的大小 params.width = ViewGroup.LayoutParams.MATCH_PARENT; mSlider.setLayoutParams(params); int dy = -height / totalNum * index - scrollY;//计算滑块需要移动的位置,上 + ,下 - ; if (mScroller.computeScrollOffset()) { mScroller.abortAnimation();//如果Scroller没有结束就结束动画 } mScroller.startScroll(0, mScroller.getFinalY(), 0, dy);//开始滑动 invalidate();//必须要加上,不然没有滑动 } private void resetHorizontalSlider() { int scrollX = getScrollX(); int width = getWidth(); LayoutParams params = (LayoutParams) mSlider.getLayoutParams(); params.width = width / totalNum;//重新设置滑块的大小 params.height = ViewGroup.LayoutParams.MATCH_PARENT; mSlider.setLayoutParams(params); int dx = -width / totalNum * index - scrollX;//计算滑块需要移动的位置,左 + ,右 - ; if (mScroller.computeScrollOffset()) { mScroller.abortAnimation();//如果Scroller没有结束就结束动画 } mScroller.startScroll(mScroller.getFinalX(), 0, dx, 0);//开始滑动 invalidate();//必须要加上,不然没有滑动 } @Override public void computeScroll() { if (mScroller.computeScrollOffset()) { scrollTo(mScroller.getCurrX(), mScroller.getCurrY()); postInvalidate(); } } @Override public boolean onTouchEvent(MotionEvent event) { detector.onTouchEvent(event); return true; } private GestureDetector.SimpleOnGestureListener mOnGestureListener = new GestureDetector.SimpleOnGestureListener() { @Override public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { float dx = e1.getX() - e2.getX(); if (Math.abs(velocityX) < 1000 && Math.abs(velocityY) < 500 && Math.abs(dx) < 100) { onSingleTapConfirmed(e2); } return true; } @Override public boolean onSingleTapConfirmed(MotionEvent e) { if (getOrientation() == HORIZONTAL) { float x = e.getX(); float childW = getWidth() / totalNum; int column = (int) (x / childW); Log.i(TAG, "onSingleTapConfirmed: column " + column); setIndex(column); }else{ float y = e.getY(); float childH = getHeight() / totalNum; int row = (int) (y / childH); Log.i(TAG, "onSingleTapConfirmed: row " + row); setIndex(row); } return true; } }; }应用
<com.yyw.scrollerdemo.SliderLayout android:id="@+id/slider" android:background="@drawable/slider_bg" android:orientation="horizontal" android:layout_width="match_parent" app:slider_pic="@drawable/slider" android:layout_height="50dp"/>