package com.smartdot.cgt.view; import android.content.Context; import android.os.Handler; import android.util.AttributeSet; import android.view.GestureDetector; import android.view.GestureDetector.OnGestureListener; import android.view.MotionEvent; import android.view.View; import android.view.ViewConfiguration; import android.view.ViewGroup; import android.widget.Scroller; /**聽 * @ClassName: ImageScrollView聽 * @Description: 涓昏鏄鐞嗗湪鍥剧墖涓婄殑涓?簺鎵嬪娍鐩戝惉 * @author zhaosw聽email:vvtale@gmail.com * @date 2013-12-5 涓嬪崍3:23:23聽聽 */ public class ImageScrollView extends ViewGroup { /** 婊氬姩瀵硅薄Scroller **/ private Scroller scroller = null; /** 鎵嬪娍璇嗗埆瀵硅薄GestureDetector **/ private GestureDetector gestureDetector = null; /** 褰撳墠灞忓箷绱㈠紩 **/ private int currentScreenIndex = 0; /** 璁剧疆涓?釜鏍囧織浣嶏紝闃叉搴曞眰鐨刼nTouch浜嬩欢閲嶅澶勭悊UP浜嬩欢 **/ private boolean fling = false; Handler handler; int time; OnClickListener clickListener; public ImageScrollView(Context context, AttributeSet attrs) { super(context, attrs); initView(context); } @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { /** 璁剧疆甯冨眬锛屽皢瀛愯鍥鹃『搴忔í灞忔帓鍒?**/ for (int i = 0; i < getChildCount(); i++) { View child = getChildAt(i); child.setVisibility(View.VISIBLE); child.measure(right - left, bottom - top); child.layout(i * getWidth(), 0, (i + 1) * getWidth(), getHeight()); } } /** 鍒濆鍖?**/ private void initView(final Context context) { this.scroller = new Scroller(context); handler = new Handler(); // 鍒濆鍖栨粦鍔ㄦ墜鍔挎娴嬪櫒 this.gestureDetector = new GestureDetector(new OnGestureListener() { @Override public boolean onSingleTapUp(MotionEvent e) { if (clickListener != null) { clickListener.onClick(ImageScrollView.this); } return false; } @Override public void onShowPress(MotionEvent e) { } @Override public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { // 闃叉绉诲姩杩囨渶鍚庝竴椤? if ((distanceX > 0 && getScrollX() < getWidth() * (getChildCount() - 1)) || (distanceX < 0 && getScrollX() > 0)) {// 闃叉鍚戠涓?〉涔嬪墠绉诲姩 scrollBy((int) distanceX, 0); } return true; } @Override public void onLongPress(MotionEvent e) { } @Override public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { // 鍒ゆ柇鏄惁杈惧埌鏈?皬杞绘澗閫熷害锛屽彇缁濆鍊肩殑 if (Math.abs(velocityX) > ViewConfiguration.get(context) .getScaledMinimumFlingVelocity()) { if (velocityX > 0 && currentScreenIndex >= 0) { fling = true; scrollToScreen((currentScreenIndex - 1 + getChildCount()) % getChildCount()); } else if (velocityX < 0 && currentScreenIndex <= getChildCount() - 1) { fling = true; scrollToScreen((currentScreenIndex + 1 + getChildCount()) % getChildCount()); } } return true; } @Override public boolean onDown(MotionEvent e) { return false; } }); } /** 鍒囨崲鍒版寚瀹氬睆 **/ public void scrollToScreen(int whichScreen) { if (whichScreen != currentScreenIndex && getFocusedChild() != null && getFocusedChild() == getChildAt(currentScreenIndex)) { getFocusedChild().clearFocus(); // 娓呴櫎鐒︾偣 } final int delta = whichScreen * getWidth() - getScrollX(); int show = 0; if (Math.abs(delta) < getWidth() * (getChildCount() - 1) - getWidth() / 2) show = Math.abs(delta) * 2; scroller.startScroll(getScrollX(), 0, delta, 0, show); invalidate(); currentScreenIndex = whichScreen; // 璁剧疆褰撳墠灞忓箷绱㈠紩 if (scrollToScreenCallback != null) { // 鍒锋柊鍦嗗湀 scrollToScreenCallback.callback(currentScreenIndex); } } @Override public void computeScroll() { // 褰撴粴鍔ㄦ病鏈夊畬鎴? if (scroller.computeScrollOffset()) { scrollTo(scroller.getCurrX(), 0); postInvalidate(); } } @Override public boolean onTouchEvent(MotionEvent event) { gestureDetector.onTouchEvent(event); if (event.getAction() == MotionEvent.ACTION_UP) { handler.removeCallbacks(next); if (time >= 500) handler.postDelayed(next, time); if (!fling) { // 褰撶敤鎴峰仠姝㈡嫋鍔? snapToDestination(); } fling = false; } return true; } /** 鏍规嵁褰撳墠x鍧愭爣浣嶇疆纭畾鍒囨崲鍒扮鍑犲睆 **/ private void snapToDestination() { scrollToScreen((getScrollX() + (getWidth() / 2)) / getWidth()); } /** 搴曢儴鍦嗗湀鏄剧ず鍥炶皟鎺ュ彛 **/ interface ScrollToScreenCallback { public void callback(int currentIndex); } /** ScrollToScreenCallback鍥炶皟瀵硅薄 **/ private ScrollToScreenCallback scrollToScreenCallback; /** 璁剧疆鍥炶皟鍑芥暟瀵硅薄 **/ public void setScrollToScreenCallback( ScrollToScreenCallback scrollToScreenCallback) { this.scrollToScreenCallback = scrollToScreenCallback; } public void start(int time) { if (time > 500) this.time = time; else this.time = 500; handler.postDelayed(next, time); } public void stop() { handler.removeCallbacks(next); } Runnable next = new Runnable() { @Override public void run() { scrollToScreen((currentScreenIndex + 1) % getChildCount()); handler.postDelayed(next, time); } }; public int getCurrentScreenIndex() { return currentScreenIndex; } public void setClickListener(OnClickListener clickListener) { this.clickListener = clickListener; } }