/×
×当前代码只实现了自定义 viewpager 指定大小显示,滑动事件,单击事件
×/
package com.example.myviewpager.views;
import android.content.Context;
import android.graphics.Color;
import android.os.SystemClock;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Scroller;
public class MyViewPager extends ViewGroup {
    private static final String TAG = "Tag";
    private int mWidth;//总宽度
    private int mHeight;//总高
    private float startX;//记录点击时位置
    private int pagerWidth;//每个孩子宽度
    private int currentItem;//显示当前孩子index
    private Scroller scroller;
    private long downTime;
    private OnViewPagerItemClickListener onViewPagerItemClickListener;
    private OnScrollListener onScrollListener;
    public OnScrollListener getOnScrollListener() {
        return onScrollListener;
    }
    public void setOnScrollListener(OnScrollListener onScrollListener) {
        this.onScrollListener = onScrollListener;
    }
    public MyViewPager.OnViewPagerItemClickListener getOnViewPagerClickListener() {
        return onViewPagerItemClickListener;
    }
    public void setOnViewPagerClickListener(MyViewPager.OnViewPagerItemClickListener onViewPagerItemClickListener) {
        this.onViewPagerItemClickListener = onViewPagerItemClickListener;
    }
    public MyViewPager(Context context) {
        super(context);
    }
    public MyViewPager(final Context context, AttributeSet attrs) {
        super(context, attrs);
        scroller = new Scroller(context);
        ViewGroup.LayoutParams lp = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
        for (int i = 0; i < 3; i++) {
            View view = new View(context);
            if (i == 0)
                view.setBackgroundColor(Color.RED);
            if (i == 1)
                view.setBackgroundColor(Color.YELLOW);
            if (i == 2)
                view.setBackgroundColor(Color.BLUE);
            view.setLayoutParams(lp);
            view.setTag(i);
            addView(view);
        }
    }
    public MyViewPager(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }
    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        if (changed) {
            int childCount = getChildCount();
            for (int i = 0; i < childCount; i++) {//布局每个孩子
                View child = getChildAt(i);
                child.layout(i * pagerWidth, 0, (i + 1) * pagerWidth, mHeight);
            }
        }
    }
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int childCount = getChildCount();
        if (childCount > 0) {
            View childAt = getChildAt(0);
            childAt.measure(widthMeasureSpec, heightMeasureSpec);
            int measuredHeight = childAt.getMeasuredHeight();
            int measuredWidth = childAt.getMeasuredWidth();
            mWidth = measuredWidth * childCount;
            mHeight = measuredHeight;
            pagerWidth = measuredWidth;
            setMeasuredDimension(pagerWidth, mHeight);//设置pager 尺寸,宽度为一个孩子宽度,
            // 如果为所有孩子宽度之和会显示所有孩子(当pager没有沾满屏幕)
        }
    }
    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        return true;
    }
    boolean isclick = false;
    @Override
    public void computeScroll() {
        super.computeScroll();
        if (scroller.computeScrollOffset()) {
            scrollTo(scroller.getCurrX(), 0);
            if (onScrollListener != null) {
                onScrollListener.onScroll(currentItem, getScrollX());
            }
            postInvalidate();
        }
    }
    boolean once = false;
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        super.onTouchEvent(event);
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                downTime = SystemClock.currentThreadTimeMillis();
                startX = event.getX();
                break;
            case MotionEvent.ACTION_MOVE:
                if (!once) {//只要滑动距离有一次大于指定的距离就认为是滑动状态,后续滑动不受距离限制
                    float distance = event.getX() - startX;
                    if (Math.abs(distance) > 8) {
                        once = true;
                        isclick = false;//不是单击,而是滑动
                    } else isclick = true;
                } else {
                    float distance = event.getX() - startX;
                    scrollBy(-(int) distance, 0);
                    if (getScrollX() <= 0) {//当是第一页时禁止右滑
                        scrollTo(0, 0);
                        currentItem = 1;
                    }
                    if (getScrollX() - pagerWidth * (getChildCount() - 1) > 0) {//当是最后一页禁止左滑
                        scrollTo(pagerWidth * (getChildCount() - 1), 0);
                        currentItem = getChildCount();
                    }
                    if (onScrollListener != null) {//调用滑动监听
                        onScrollListener.onScroll(currentItem, getScrollX());
                    }
                    startX = event.getX();
                    isclick = false;
                }
                break;
            case MotionEvent.ACTION_UP:
                long upTime = SystemClock.currentThreadTimeMillis();
                long useTime = upTime - downTime;
                if (once && !isclick) {
                    startX = 0;
                    int scrolleX = getScrollX();
                    int index = (scrolleX + pagerWidth / 2) / pagerWidth;//滑动超半下一个,否则还原上一个
                    scroller.startScroll(scrolleX, 0, index * pagerWidth - scrolleX, 0);
                    currentItem = index;
                    postInvalidate();
                    once = false;
                }
                if (!once && isclick && useTime < 50) {//调用点击监听,小于50毫秒认为是点击,大于是长按没实现长按
                    if (onViewPagerItemClickListener != null)
                        onViewPagerItemClickListener.onClick(currentItem);
                    isclick = true;
                }
                break;
        }
        return true;
    }
    public interface OnViewPagerItemClickListener {
        void onClick(int position);
    }
    public interface OnScrollListener {
        void onScroll(int pageNum, int scrolx);
    }
}