package com.wise.customView;
import com.wise.extend.OnViewChangeListener;
import android.content.Context;
import android.util.AttributeSet;
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.Scroller;
/**
* 我的车况滑滑动控件
* @author honesty
*/
public class EnergyGroup extends ViewGroup{
//private static final String TAG = "EnergyGroup";
private VelocityTracker velocityTracker;//判断手势
private static final int SNAP_VELOCITY = 600; //滑动速度
private int TOUCH_SLOP; //判断移动的阀值
private int mCurScreen = 0; //当前所在屏幕
private float downMotionX; //按下x坐标
OnViewChangeListener mOnViewChangeListener;
Scroller scroller;
Context mContext;
public EnergyGroup(Context context){
super(context);
init(context);
}
public EnergyGroup(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
private void init(Context context){
scroller = new Scroller(context);
mContext = context;
TOUCH_SLOP = ViewConfiguration.get(getContext()).getScaledTouchSlop();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int count = getChildCount();
for(int i = 0 ; i < count; i++){
getChildAt(i).measure(widthMeasureSpec, heightMeasureSpec);//设置每个view的大小
}
scrollTo(0, 0);//Scroller定位
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
int childLeft = 0;
final int count = getChildCount();
for(int i = 0 ; i < count; i++){
final View childView = getChildAt(i);
final int width = childView.getMeasuredWidth();
childView.layout(childLeft, 0, childLeft+width, childView.getMeasuredHeight());
childLeft += width;
}
}
private float mLastMotionY;
private final static int TOUCH_STATE_REST = 0;
private final static int TOUCH_STATE_SCROLLING = 1;
private int mTouchState = TOUCH_STATE_REST;
boolean isSliding = false;
float moveXOfFirst;
float x;
/**
* false子控件获取焦点
* true父控件获取焦点
*/
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
downMotionX = event.getX(0);
moveXOfFirst = event.getX(0);
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
if(velocityTracker == null){
velocityTracker = VelocityTracker.obtain();
velocityTracker.addMovement(event);
}
x = moveXOfFirst;
isSliding = false;
break;
case MotionEvent.ACTION_MOVE:
if(Math.abs(moveXOfFirst-x) > TOUCH_SLOP) {
//移动超过阈值,则表示移动了
isSliding = true;
}
break;
case MotionEvent.ACTION_UP:
break;
}
return isSliding;
}
@Override
public boolean onTouchEvent(MotionEvent event) {
float x = event.getX();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
if(velocityTracker == null){
velocityTracker = VelocityTracker.obtain();
velocityTracker.addMovement(event);
}
if(!scroller.isFinished()){ //解决在松开手滚动时,按下无效
scroller.abortAnimation();
}
downMotionX = x;
break;
case MotionEvent.ACTION_MOVE:
int deltaX = (int)(downMotionX - x);
downMotionX = x;
scrollBy(deltaX, 0);//画面跟随指尖
if (velocityTracker != null){
velocityTracker.addMovement(event);
}
break;
case MotionEvent.ACTION_UP:
int velocityX = 0;
if(velocityTracker != null){
velocityTracker.addMovement(event);
velocityTracker.computeCurrentVelocity(1000);
velocityX = (int)velocityTracker.getXVelocity();//计算x方向速度
}
if(velocityX > SNAP_VELOCITY && mCurScreen > 0){ //速度快且不是第一屏
snapToScreen(mCurScreen - 1);
}else if(velocityX < -SNAP_VELOCITY && mCurScreen < getChildCount() - 1){//速度快且不是最后一屏
snapToScreen(mCurScreen + 1);
}else{
snapToDestination(); //判断是否翻转
}
break;
case MotionEvent.ACTION_CANCEL:
break;
}
return true;
}
/**
* 跳转到那个屏幕
* @param whichScreen
*/
public void snapToScreen(int whichScreen){
if(whichScreen > (getChildCount() -1)){
addView();
}
whichScreen = Math.max(0, Math.min(whichScreen, (getChildCount() - 1)));//防止输入不再范围内的数字
if(getScrollX() != getWidth() * whichScreen){//时候需要移动
int delta = whichScreen*getWidth()-getScrollX(); //还有多少没有显示
scroller.startScroll(getScrollX(), 0, delta, 0, Math.abs(delta)*2);//滚动完剩下的距离
mCurScreen = whichScreen;
invalidate();
if(mOnViewChangeListener != null){
mOnViewChangeListener.OnViewChange(whichScreen);
}
}
}
/**
* 滑动速度过慢的话调用这个方法判断是否滑动了半个屏幕,并计算出当前显示那个屏幕
*/
private void snapToDestination(){
int screenWidth = getWidth();
int destScreen = (getScrollX() + screenWidth/2)/screenWidth;
snapToScreen(destScreen);
}
@Override
public void computeScroll() {//需要,不然松手后不会滑动
if (scroller.computeScrollOffset()) {
scrollTo(scroller.getCurrX(), scroller.getCurrY());
postInvalidate();
}
}
public void setOnViewChangeListener(OnViewChangeListener onViewChangeListener){
mOnViewChangeListener = onViewChangeListener;
}
public void addView(){
if(mOnViewChangeListener != null){
mOnViewChangeListener.OnLastView();
}
}
}