圖紙
圖片.png
使用viewpager的效果圖
ScreenGif.gif
自定義View的效果圖
ScreenGif.gif
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, "當(dāng)前positin=" + position + " " + titles[position]);
}
});
實現(xiàn)方式
構(gòu)造方法
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
當(dāng)設(shè)置為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并且根據(jù)當(dāng)前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() 獲取當(dāng)前所處的位置
這個等以后有時間完善吧宏榕。扎酷。目前item最多支持7個。剪撬。不過你想要支持更多稍坯,只要按照這個格式繼續(xù)添加就好了。。赐稽。
//當(dāng)前的位置
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) {
// 第二步寓落,調(diào)用startScroll()方法來初始化滾動數(shù)據(jù)并刷新界面
mScroller.startScroll(getScrollX(), 0, destX - getScrollX(), 0, 200);
invalidate();
}
@Override
public void computeScroll() {
// 第三步括丁,重寫computeScroll()方法,并在其內(nèi)部完成平滑滾動的邏輯
if (mScroller.computeScrollOffset()) {
scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
invalidate();
} else {
if (isScroll) {
setScrollX(lastScrollX);
isScroll = false;
if (onScrollEndListener != null) {
onScrollEndListener.currentPosition(getCurrentPosition());
}
}
}
}
供外部使用的接口和方法
設(shè)置標(biāo)題
public void setTitles(String titles[]) {
this.titles = titles;
invalidate();
}
設(shè)置背景圖片
public void setPicIds(int[] picIds) {
this.picIds = picIds;
}
設(shè)置滑動結(jié)束后的position監(jiān)聽
public void setOnScrollEndListener(OnScrollEndListener onScrollEndListener) {
this.onScrollEndListener = onScrollEndListener;
}