package xx.weidu;
import java.util.ArrayList;
import java.util.List;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.TextView;
public class TouchPageView extends ViewGroup{
private LinearLayout view1;
private LinearLayout view2;
private LinearLayout view3;
//速度跟踪
private VelocityTracker mVelocityTracker;
private int mMaximumVelocity;
//手势临界速度,当速度超过这个时切换到下一屏
private static final int SNAP_VELOCITY = 100;
//停止状态
private final static int TOUCH_STATE_REST = 0;
//滚动状态
private final static int TOUCH_STATE_MOVING = 1;
//减速停止状态
private final static int TOUCH_STATE_SLOWING = 2;
//当前触摸状态
private int touchState = TOUCH_STATE_REST;
private boolean lock=false;
private float lastMotionX;
private float lastMotionY;
private Context context;
private List<LinearLayout> views;
//是否移动了
private boolean isMoved;
//长按的runnable
private Runnable mLongPressRunnable;
//移动的阈值
private static final int TOUCH_SLOP=10;
public int width;
public int height;
public TouchPageView(Context context) {
super(context);
this.context=context;
init();
}
private void init()
{
views= new ArrayList<LinearLayout>();
view1=new LinearLayout(context);
view1.setBackgroundColor(Color.YELLOW);
this.addView(view1);
TextView tv=new TextView(context);
tv.setText("测试");
view1.addView(tv);
views.add(view1);
view2=new LinearLayout(context);
view2.setBackgroundColor(Color.RED);
this.addView(view2);
views.add(view2);
view3=new LinearLayout(context);
view3.setBackgroundColor(Color.GREEN);
this.addView(view3);
views.add(view3);
final ViewConfiguration configuration = ViewConfiguration.get(getContext());
mMaximumVelocity = configuration.getScaledMaximumFlingVelocity();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec){
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
final int count = views.size();
for (int i = 0; i < count; i++) {
final View child =views.get(i);
child.measure(widthMeasureSpec,heightMeasureSpec);
}
int finalWidth, finalHeight;
finalWidth = measureWidth(widthMeasureSpec);
finalHeight = measureHeight(heightMeasureSpec);
this.width=finalWidth;
this.height=finalHeight;
}
private int measureWidth(int measureSpec) {
int result = 0;
int specMode = MeasureSpec.getMode(measureSpec);
int specSize = MeasureSpec.getSize(measureSpec);
if (specMode == MeasureSpec.EXACTLY) {
result = specSize;
} else {
result = specSize;
}
return result;
}
private int measureHeight(int measureSpec) {
int result = 0;
int specMode = MeasureSpec.getMode(measureSpec);
int specSize = MeasureSpec.getSize(measureSpec);
if (specMode == MeasureSpec.EXACTLY) {
result = specSize;
} else {
result = specSize;
}
return result;
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
int childLeft = -1;
final int count = views.size();
//水平从左到右放置
for (int i = 0; i < count; i++) {
final View child =views.get(i);
if (child.getVisibility() != View.GONE) {
final int childWidth = child.getMeasuredWidth();
if(childLeft==-1)
{
childLeft=-childWidth;
}
child.layout(childLeft, 0, childLeft + childWidth, child.getMeasuredHeight());
childLeft += childWidth;
}
}
}
//绘制子元素
@Override
protected void onDraw(Canvas canvas) {
//水平从左到右放置
int count = views.size();
for (int i = 0; i < count; i++) {
View child =views.get(i);
drawChild(canvas, child, getDrawingTime());
}
}
@Override
public boolean onTouchEvent(MotionEvent ev){
if(!lock)
{
if (mVelocityTracker == null) {
mVelocityTracker = VelocityTracker.obtain();
}
mVelocityTracker.addMovement(ev);
final int action = ev.getAction();
final float x = ev.getX();
final float y = ev.getY();
switch (action) {
case MotionEvent.ACTION_DOWN://按下去
if(touchState==TOUCH_STATE_REST)
{
//记录按下去的的x坐标
lastMotionX = x;
touchState=TOUCH_STATE_MOVING;
isMoved=false;
}
break;
case MotionEvent.ACTION_MOVE://拖动时
if(touchState==TOUCH_STATE_MOVING)
{
float offsetX=x-lastMotionX;
float offsetY=y-lastMotionY;
if(isMoved)
{
lastMotionX=x;
lastMotionY=y;
final int count = views.size();
//水平从左到右放置
for (int i = 0; i < count; i++) {
final View child =views.get(i);
if (child.getVisibility() != View.GONE) {
final int childWidth = child.getMeasuredWidth();
int childLeft = child.getLeft()+(int)offsetX;
child.layout(childLeft, 0, childLeft + childWidth, child.getMeasuredHeight());
childLeft += childWidth;
}
}
}
else if(Math.abs(offsetX)>TOUCH_SLOP||Math.abs(offsetY)>TOUCH_SLOP)
{
//移动超过阈值,则表示移动了
isMoved=true;
removeCallbacks(mLongPressRunnable);
}
}
break;
case MotionEvent.ACTION_UP://放开时
//释放了
removeCallbacks(mLongPressRunnable);
if(isMoved)
{
if(touchState==TOUCH_STATE_MOVING)
{
touchState=TOUCH_STATE_SLOWING;
int sign=0;
final VelocityTracker velocityTracker = mVelocityTracker;
//计算当前速度
velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);
//x方向的速度
int velocityX = (int) velocityTracker.getXVelocity();
if(velocityX > SNAP_VELOCITY)//足够的能力向左
{
sign=1;
Log.e("enough to move left", "true");
}
else if (velocityX < -SNAP_VELOCITY)//足够的能力向右
{
sign=-1;
Log.e("enough to move right", "right");
}
else
{
sign=0;
}
moveToFitView(sign);
if (mVelocityTracker != null) {
mVelocityTracker.recycle();
mVelocityTracker = null;
}
}
}
break;
}
}
return true;
}
int offset=0;
private void moveToFitView(int sign)
{
boolean b=swapView(sign);
if(true)
{
View view1=views.get(1);
int left=view1.getLeft();
//int offset=0;
if(left!=0)
{
offset=-1*left;
}
moveView();
}
}
FlipAnimationHandler mAnimationHandler;
int ovv=40;
private void moveView()
{
final int count = views.size();
if(offset!=0)
{
int ov=0;
if(offset>0)
{
ov=ovv;
}
else
{
ov=-1*ovv;
}
ovv=ovv-3;
if(ovv<1)
{
ovv=3;
}
if(Math.abs(offset)<Math.abs(ov))
{
ov=offset;
offset=0;
}
else
{
offset=offset-ov;
}
//水平从左到右放置
for (int i = 0; i < count; i++) {
final View child =views.get(i);
final int childWidth = child.getMeasuredWidth();
int childLeft = child.getLeft()+ov;
child.layout(childLeft, 0, childLeft + childWidth, child.getMeasuredHeight());
childLeft += childWidth;
}
if(mAnimationHandler==null)
{
mAnimationHandler = new FlipAnimationHandler();
}
mAnimationHandler.sleep(1);
}
else
{
ovv=40;
touchState=TOUCH_STATE_REST;
}
}
class FlipAnimationHandler extends Handler {
@Override
public void handleMessage(Message msg) {
TouchPageView.this.moveView();
}
public void sleep(long millis) {
this.removeMessages(0);
sendMessageDelayed(obtainMessage(0), millis);
}
}
private boolean swapView(int sign)
{
boolean b=false;
if(sign==-1)//向左
{
View view0=views.get(0);
if(view0.getLeft()<=-1*view0.getMeasuredWidth())
{
swapViewIndex(sign);
View view2=views.get(1);
View view3=views.get(2);
int childWidth=view2.getMeasuredWidth();
int childLeft=view2.getLeft()+childWidth;
view3.layout(childLeft, 0, childLeft + view3.getMeasuredWidth(), view3.getMeasuredHeight());
b=true;
}
}
else if(sign==1)//向右
{
View view3=views.get(2);
if(view3.getLeft()>view3.getMeasuredWidth())
{
swapViewIndex(sign);
View view1=views.get(0);
View view2=views.get(1);
int childRight=view2.getLeft();
int childLeft=childRight-view1.getMeasuredWidth();
view1.layout(childLeft, 0, childRight, view1.getMeasuredHeight());
b=true;
}
}
return b;
}
private void swapViewIndex(int sign)
{
if(sign==-1)//向左
{
LinearLayout v=views.remove(0);
views.add(v);
}
else if(sign==1)//向右
{
LinearLayout v=views.remove(views.size()-1);
views.add(0, v);
}
}
}