Newer
Older
dxcgt / app / src / main / java / com / smartdot / cgt / view / ImageScrollView.java
wangxitong on 6 Apr 2021 5 KB first commit
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;
	}
}