先上一个效果图
主要核心方法,这里有一个问题ontouchEvent如果返回super,则move事件不会继续执行,down事件则没问题.所以这里要返回true
其次,就是计算滚动距离的问题
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
downX = event.getX();
break;
case MotionEvent.ACTION_MOVE:
float scrollX = event.getX();
mOffset = scrollX - downX;
// 向右滑动
if (scrollX > downX) {
// 如果滑动距离大于一个条目的大小,则减1
if (scrollX - downX >= mItemSize) {
if (selectNum > 0) {
mOffset = 0;
selectNum = selectNum - 1;
downX = scrollX;
if (mOnRollingListener != null) {
mOnRollingListener.onRolling(selectNum, data.get(selectNum));
}
}
}
} else {
//向左滑动大于一个条目的大小,则加1
if (downX - scrollX >= mItemSize) {
if (selectNum < data.size() - 1) {
mOffset = 0;
selectNum = selectNum + 1;
downX = scrollX;
if (mOnRollingListener != null) {
mOnRollingListener.onRolling(selectNum, data.get(selectNum));
}
}
}
}
invalidate();
break;
case MotionEvent.ACTION_UP:
//抬起手指时,偏移量归零,相当于回弹。
mOffset = 0;
invalidate();
break;
default:
break;
}
return true;
}
下一步则是绘制流程
注: 这步有一个问题就是如果文字过长,会导致遮住其他文字,所以我这取itemsize的时候,需要取最大值来得到能够获取的itemsize.并且修正可以看到的大小
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// 获取宽度
int width = getWidth();
int height = getHeight();
// 获取每个条目的大小
if (seeSize == 0) {
return;
}
mItemSize = width / seeSize;
int tmp = 0;
for (String datum : data) {
mOthers.getTextBounds(datum, 0, datum.length(), mRect);
int textWidth = mRect.width();
if (textWidth > tmp) {
tmp = textWidth;
}
}
// 修正文字过大导致长度bug
mItemSize = Math.max(mItemSize, tmp);
seeSize = width / mItemSize;
// | dfadf | dsafa | afasdf |
// 得到选中的条目
// 画出第一个
for (int j = 0; j < data.size(); j++) {
String datum = data.get(j);
mOthers.getTextBounds(datum, 0, datum.length(), mRect);
int textWidth = mRect.width();
int textHeight = mRect.height();
if (j != selectNum) {
// 画其他的
if (j < selectNum) {
int a = selectNum - j;
canvas.drawText(datum, mItemSize * seeSize / 2 - textWidth / 2 - a * mItemSize + mOffset, height / 2 - textHeight / 2, mOthers);
} else {
int a = j - selectNum;
canvas.drawText(datum, mItemSize * seeSize / 2 - textWidth / 2 + a * mItemSize + mOffset, height / 2 - textHeight / 2, mOthers);
}
} else {
canvas.drawText(datum, mItemSize * seeSize / 2 - textWidth / 2 + mOffset, height / 2 - textHeight / 2, mSelect);
}
}
}
更多详细可以移步我的github
EHorizontalSelectedView