图纸
使用viewpager的效果图
自定义View的效果图
github地址
使用
compile 'com.github.superSp:ScrollChooseView:v1.0.2'
String titles[] = new String[]{"早餐前", "早餐后", "午餐前", "午餐后", "晚餐前", "晚餐后", "睡前"};
private int picIds[] = new int[]{
R.mipmap.time_bg_breakfastbefore, R.mipmap.time_bg_breakfastafter,
R.mipmap.time_bg_lunchbefore, R.mipmap.time_bg_lunchafter,
R.mipmap.time_bg_dinnerbefor, R.mipmap.time_bg_dinnerafter,
R.mipmap.time_bg_sleep
};
scrollChooseView.setTitles(titles);
scrollChooseView.setPicIds(picIds);
scrollChooseView.setOnScrollEndListener(new ScrollChooseView.OnScrollEndListener() {
@Override
public void currentPosition(int position) {
Log.d(TAG, "当前positin=" + position + " " + titles[position]);
}
});
实现方式
构造方法
public ScrollChooseView(Context context) {
this(context, null);
}
public ScrollChooseView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public ScrollChooseView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
textBound = new Rect();
paint = new Paint();
paint.setAntiAlias(true);
paint.setColor(Color.WHITE);
paint.setTextSize(DensityUtils.sp2px(getContext(), 10));
mScroller = new Scroller(context);
}
onMeasure
当设置为wrap时候 高度显示为200
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
int widhtMode = MeasureSpec.getMode(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
setMeasuredDimension(widhtMode == MeasureSpec.EXACTLY ? widthSize : widthSize, heightMode == MeasureSpec.EXACTLY ? heightSize : DensityUtils.dp2px(getContext(),100));
}
}
onDraw
绘制text并且根据当前position切换背景和字体大小以及底部线
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (titles == null) {
return;
}
drawText(canvas);
}
private void drawText(Canvas canvas) {
for (int i = 0; i < titles.length; i++) {
if (getCurrentPosition() == i) {
paint.setTextSize(DensityUtils.sp2px(getContext(), 20));
paint.getTextBounds(titles[i], 0, titles[i].length(), textBound);
canvas.drawText(titles[i], getMeasuredWidth() / 6 * (2 * i + 1) - (textBound.width() / 2), (getMeasuredHeight() / 2) + textBound.height() / 2, paint);
paint.setStrokeWidth(3);
canvas.drawLine(getMeasuredWidth() / 6 * (2 * i + 1) - (textBound.width() / 2) - 10, (getMeasuredHeight() / 2) + textBound.height(),
getMeasuredWidth() / 6 * (2 * i + 1) + (textBound.width() / 2) + 10, (getMeasuredHeight() / 2) + textBound.height(), paint);
} else {
paint.setTextSize(DensityUtils.sp2px(getContext(), 10));
paint.getTextBounds(titles[i], 0, titles[i].length(), textBound);
canvas.drawText(titles[i], getMeasuredWidth() / 6 * (2 * i + 1) - (textBound.width() / 2), (getMeasuredHeight() / 2) + textBound.height() / 2, paint);
}
setBackgroundResource(picIds[getCurrentPosition()]);
}
}
getCurrentPosition() 获取当前所处的位置
这个等以后有时间完善吧。。目前item最多支持7个。。不过你想要支持更多,只要按照这个格式继续添加就好了。。。
//当前的位置
private int getCurrentPosition() {
int position = 1;
if (getScrollX() > getMeasuredWidth() / 6 * 1 * -3 && getScrollX() <= getMeasuredWidth() / 6 * 1 * -1) {
position = 0;
} else if (getScrollX() > getMeasuredWidth() / 6 * 1 * -1 && getScrollX() <= getMeasuredWidth() / 6 * 1 * 1) {
position = 1;
} else if (getScrollX() > getMeasuredWidth() / 6 * 1 * 1 && getScrollX() <= getMeasuredWidth() / 6 * 1 * 3) {
position = 2;
} else if (getScrollX() > getMeasuredWidth() / 6 * 1 * 3 && getScrollX() <= getMeasuredWidth() / 6 * 1 * 5) {
position = 3;
} else if (getScrollX() > getMeasuredWidth() / 6 * 1 * 5 && getScrollX() <= getMeasuredWidth() / 6 * 1 * 7) {
position = 4;
} else if (getScrollX() > getMeasuredWidth() / 6 * 1 * 7 && getScrollX() <= getMeasuredWidth() / 6 * 1 * 9) {
position = 5;
} else if (getScrollX() > getMeasuredWidth() / 6 * 1 * 9 && getScrollX() <= getMeasuredWidth() / 6 * 1 * 11) {
position = 6;
} else if (getScrollX() > getMeasuredWidth() / 6 * 1 * 11 && getScrollX() <= getMeasuredWidth() / 6 * 1 * 13) {
position = 7;
} else if (getScrollX() > getMeasuredWidth() / 6 * 1 * 13 && getScrollX() <= getMeasuredWidth() / 6 * 1 * 15) {
position = 8;
}
return position;
}
onTouchEvent() 处理滑动
@Override
public boolean onTouchEvent(MotionEvent event) {
if (titles.length <= 1) {
return super.onTouchEvent(event);
}
int x = (int) event.getX();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
isClick = true;
downX = x;
break;
case MotionEvent.ACTION_MOVE:
isClick = false;
int offset = x - downX;
if (getScrollX() < -getMeasuredWidth() / 3 || getScrollX() > getMeasuredWidth() / 3 * titles.length - getMeasuredWidth() + getMeasuredWidth() / 3) {
return super.onTouchEvent(event);
} else {
scrollX(lastScrollX - offset, true);
}
break;
case MotionEvent.ACTION_UP:
if (isClick) {
return true;
}
if (getScrollX() < -getMeasuredWidth() / 3) {
scrollX(-getMeasuredWidth() / 3, true);
}
if (getScrollX() > getMeasuredWidth() / 3 * titles.length - getMeasuredWidth() + getMeasuredWidth() / 3) {
scrollX(getMeasuredWidth() / 3 * titles.length - getMeasuredWidth() + getMeasuredWidth() / 3, true);
}
scrollX(getMeasuredWidth() / 3 * (getCurrentPosition() - 1), false);
break;
}
return true;
}
接下来是Scroller自动滑动的普遍写法。。
/**
* b 是代表手动滑 还是自动滑动。。
*
* @param endX
* @param b
*/
private void scrollX(int endX, boolean b) {
if (b) {
scrollTo(endX, 0);
} else {
isScroll = true;
lastScrollX = endX;
smoothScrollTo(endX, 0);
}
}
public void smoothScrollTo(int destX, int destY) {
// 第二步,调用startScroll()方法来初始化滚动数据并刷新界面
mScroller.startScroll(getScrollX(), 0, destX - getScrollX(), 0, 200);
invalidate();
}
@Override
public void computeScroll() {
// 第三步,重写computeScroll()方法,并在其内部完成平滑滚动的逻辑
if (mScroller.computeScrollOffset()) {
scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
invalidate();
} else {
if (isScroll) {
setScrollX(lastScrollX);
isScroll = false;
if (onScrollEndListener != null) {
onScrollEndListener.currentPosition(getCurrentPosition());
}
}
}
}
供外部使用的接口和方法
设置标题
public void setTitles(String titles[]) {
this.titles = titles;
invalidate();
}
设置背景图片
public void setPicIds(int[] picIds) {
this.picIds = picIds;
}
设置滑动结束后的position监听
public void setOnScrollEndListener(OnScrollEndListener onScrollEndListener) {
this.onScrollEndListener = onScrollEndListener;
}