package org.execise.make.viewgroup;
import android.annotation.SuppressLint;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.GestureDetector;
import android.view.GestureDetector.OnGestureListener;
import android.view.MotionEvent;
import android.view.ScaleGestureDetector;
import android.view.ScaleGestureDetector.OnScaleGestureListener;
import android.view.View;
import android.view.animation.AccelerateInterpolator;
import android.widget.FrameLayout;
import android.widget.Scroller;
/**
* 子曰:如果有了轮子,就不要重新发明轮子。
*
* 子又曰:只是说不要重新发明轮子,但是没有说不能仿造一个轮子
*
* 我曰:那我就自己仿制一个轮子
*
* 仿制一个ViewPager
*
* @author Liang
*
*/
public class PagedView extends FrameLayout {
private static final String TAG = "TAG";
public void log(String s) {
Log.d(TAG, s);
}
GestureDetector mGestureDetector = null;
ScaleGestureDetector mScaleGestureDetector = null;
GestureImpl mGestureImpl = new GestureImpl();
Scroller scroller;
public boolean isFling = false;
int mCurrentTabId = 0;
public PagedView(Context context) {
super(context);
init();
}
public PagedView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public PagedView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
private void init() {
mGestureDetector = new GestureDetector(getContext(), mGestureImpl);
mScaleGestureDetector = new ScaleGestureDetector(getContext(), mGestureImpl);
scroller = new Scroller(getContext(), new AccelerateInterpolator());
}
@Override
public void computeScroll() {
super.computeScroll();
if (scroller.computeScrollOffset()) {
// log("scroller.getCurrX() : " + scroller.getCurrX());
scrollTo(scroller.getCurrX(), 0);
invalidate();
}
}
class GestureImpl implements OnGestureListener, OnScaleGestureListener {
@Override
public boolean onDown(MotionEvent e) {
return true;
}
@Override
public void onShowPress(MotionEvent e) {
}
@Override
public boolean onSingleTapUp(MotionEvent e) {
return false;
}
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
log("onScroll: distanceX: " + distanceX);
scrollBy((int) distanceX, 0);
return false;
}
@Override
public void onLongPress(MotionEvent e) {
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
isFling = true;
if (velocityX > 0 && mCurrentTabId > 0) {
mCurrentTabId--;
} else if (velocityX < 0 && mCurrentTabId < getChildCount()) {
mCurrentTabId++;
}
moveToDest(mCurrentTabId);
return false;
}
@Override
public boolean onScale(ScaleGestureDetector detector) {
return false;
}
@Override
public boolean onScaleBegin(ScaleGestureDetector detector) {
return false;
}
@Override
public void onScaleEnd(ScaleGestureDetector detector) {
}
}
@SuppressLint("ClickableViewAccessibility")
@Override
public boolean onTouchEvent(MotionEvent event) {
super.onTouchEvent(event);
mGestureDetector.onTouchEvent(event);
// mScaleGestureDetector.onTouchEvent(event);
int downX = 0;
int upX = 0;
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
downX = (int) event.getX();
break;
case MotionEvent.ACTION_MOVE:
break;
case MotionEvent.ACTION_UP:
upX = (int) event.getX();
if (!isFling) {
int nextId = 0;
if (upX - downX < getWidth() / 2) {// Slide to left
nextId = mCurrentTabId + 1;
} else if (upX - downX > getWidth() / 2) {// Slide to right
nextId = mCurrentTabId - 1;
} else {
nextId = mCurrentTabId;
}
moveToDest(nextId);
}
isFling = false;
// log("action_up:x: " + upX);
break;
}
return true;
}
private void moveToDest(int nextId) {
mCurrentTabId = (nextId < getChildCount()) ? ((nextId >= 0) ? nextId : 0) : getChildCount() - 1;
int distance = mCurrentTabId * getWidth() - getScrollX();
log("tap to : " + mCurrentTabId);
scroller.startScroll(getScrollX(), 0, distance, 0, Math.abs(distance));
invalidate();
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
if (changed) {
for (int i = 0; i < getChildCount(); i++) {
View view = getChildAt(i);
// 指明每个子View的所在位置
view.layout(i * getWidth(), 0, getWidth() * (i + 1), getHeight());
}
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
for (int i = 0; i < getChildCount(); i++) {
getChildAt(i).measure(widthMeasureSpec, heightMeasureSpec);
}
}
}