package com.TestProject.MainActivity;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.ViewConfiguration;
import android.view.View.MeasureSpec;
import android.widget.LinearLayout;
import android.widget.Scroller;
/**
* @author chieh
*
* 2014-6-4
*/
public class test extends LinearLayout {
private static final String TAG = "ScrollLayout";
private Scroller mScroller;
private VelocityTracker mVelocityTracker;
public int mCurScreen;
private int mDefaultScreen = 0;
private static final int TOUCH_STATE_REST = 0;
private static final int TOUCH_STATE_SCROLLING = 1;
private static final int SNAP_VELOCITY = 600;
private static final int COMPUTE_MIN_DIFF = 30;
private int mTouchState = TOUCH_STATE_REST;
private int mTouchSlop;
private float mLastMotionX;
private float mLastMotionY;
public List<Map<String, String>> projectList = new ArrayList<Map<String, String>>();
public test(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
mScroller = new Scroller(context);
mCurScreen = mDefaultScreen;
mTouchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();
}
// @Override
// protected void onLayout(boolean changed, int l, int t, int r, int b) {
//
// if (changed) {
// int childLeft = 0;
// final int childCount = getChildCount();
//
// for (int i=0; i<childCount; i++) {
// final View childView = getChildAt(i);
// if (childView.getVisibility() != View.GONE) {
// final int childWidth = childView.getMeasuredWidth();
// childView.layout(childLeft, 0,
// childLeft+childWidth, childView.getMeasuredHeight());
// childLeft += childWidth;
// }
// }
// }
// }
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
final int width = MeasureSpec.getSize(widthMeasureSpec);
final int widthMode = MeasureSpec.getMode(widthMeasureSpec);
if (widthMode != MeasureSpec.EXACTLY) {
throw new IllegalStateException("ScrollLayout only canmCurScreen run at EXACTLY mode!");
}
final int heightMode = MeasureSpec.getMode(heightMeasureSpec);
if (heightMode != MeasureSpec.EXACTLY) {
throw new IllegalStateException("ScrollLayout only can run at EXACTLY mode!");
}
// The children are given the same width and height as the scrollLayout
final int count = getChildCount();
for (int i = 0; i < count; i++) {
getChildAt(i).measure(widthMeasureSpec, heightMeasureSpec);
}
// Log.i(TAG, "moving to screen "+mCurScreen);
scrollTo(mCurScreen * width, 0);
}
/**
* According to the position of current layout
* scroll to the destination page.
*/
public void snapToDestination() {
final int screenWidth = getWidth();
final int destScreen = (getScrollX()+ screenWidth/2)/screenWidth;
snapToScreen(destScreen);
}
public void snapToScreen(int whichScreen) {
// get the valid layout page
whichScreen = Math.max(0, Math.min(whichScreen, getChildCount()-1));
if (getScrollX() != (whichScreen*getWidth())) {
final int delta = whichScreen*getWidth()-getScrollX();
mScroller.startScroll(getScrollX(), 0,
delta, 0, Math.abs(delta)*2);
mCurScreen = whichScreen;
}
}
public void setToScreen(int whichScreen) {
whichScreen = Math.max(0, Math.min(whichScreen, getChildCount()-1));
mCurScreen = whichScreen;
scrollTo(whichScreen*getWidth(), 0);
}
public int getCurScreen() {
return mCurScreen;
}
@Override
public void computeScroll() {
if (mScroller.computeScrollOffset()) {
scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
postInvalidate();
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if (mVelocityTracker == null) {
mVelocityTracker = VelocityTracker.obtain();
}
mVelocityTracker.addMovement(event);
final int action = event.getAction();
final float x = event.getX();
final float y = event.getY();
switch (action) {
case MotionEvent.ACTION_DOWN:
if (!mScroller.isFinished()){
mScroller.abortAnimation();
}
mLastMotionX = x;
break;
case MotionEvent.ACTION_MOVE:
int deltaX = (int)(mLastMotionX - x);
mLastMotionX = x;
scrollBy(deltaX, 0);
break;
case MotionEvent.ACTION_UP:
Log.i(TAG, "event : up");
// if (mTouchState == TOUCH_STATE_SCROLLING) {
final VelocityTracker velocityTracker = mVelocityTracker;
velocityTracker.computeCurrentVelocity(1000);
int velocityX = (int) velocityTracker.getXVelocity();
Log.i(TAG, "velocityX:"+velocityX);
if (velocityX > SNAP_VELOCITY && mCurScreen > 0) {
// Fling enough to move left
onScreenChangeListener.onScreenChange(mCurScreen - 1);
Log.i(TAG, "snap left");
snapToScreen(mCurScreen - 1);
} else if (velocityX < -SNAP_VELOCITY
&& mCurScreen < getChildCount() - 1) {
// Fling enough to move right
Log.i(TAG, "snap right");
onScreenChangeListener.onScreenChange(mCurScreen + 1);
snapToScreen(mCurScreen + 1);
} else {
snapToDestination();
}
if (mVelocityTracker != null) {
mVelocityTracker.recycle();
mVelocityTracker = null;
}
// }
mTouchState = TOUCH_STATE_REST;
break;
case MotionEvent.ACTION_CANCEL:
mTouchState = TOUCH_STATE_REST;
break;
}
return true;
}
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
super.onInterceptTouchEvent(event);
if (MotionEventUtil.getPointerCount(event) > 1) {
// マルチタッチ時にスクロールはしないので判定終了
requestDisallowInterceptTouchEvent(true);
return false;
}
// onTouch()のために加速度の計算を始める
if (event.getAction() == MotionEvent.ACTION_DOWN) {
//mPrevX = event.getX();
mLastMotionX = event.getX();
mLastMotionY = event.getY();
}
// スクロールなのか、コンテンツにアクセスなのか判定する
float diffX = Math.abs(event.getX() - mLastMotionX);
float diffY = Math.abs(event.getY() - mLastMotionY);
if (!mScroller.isFinished()) {
// スクロール中なので、インターセプトする
mScroller.abortAnimation();
return true;
} else if (Math.max(diffX, diffY) < COMPUTE_MIN_DIFF) {
// まだ判定できる移動距離に達していないので見送り
return false;
} else if (diffX > (diffY * 2)) {
// 横スクロールなので、インターセプトする
mLastMotionX = event.getX();
mLastMotionY = event.getY();
- 1
- 2
- 3
- 4
前往页