/×
×当前代码只实现了自定义 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);
}
}