做地址选择的时候的经常会用到字母筛选,如下图所示
我们只实现右边的字母,字母的实现可以使用列表的形式实现,也可以自定义View来实现,本次我们采用第二种自定义View,代码如下:
public class LetterSortView extends View {
//一个是选中的画笔,一个是默认的画笔
private Paint defaultPaint;
private Paint selectPaint;
private String mCurrentTouchLetter;
private OnTouchLetterListener listener;
public void setListener(OnTouchLetterListener listener) {
this.listener = listener;
}
// 26个字母
public static final String[] LETTERS = {"A", "B", "C", "D", "E", "F", "G", "H", "I",
"J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V",
"W", "X", "Y", "Z"};
public LetterSortView(Context context) {
super(context,null);
initPaint();
}
public LetterSortView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
initPaint();
}
public LetterSortView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initPaint();
}
private void initPaint() {
defaultPaint = new Paint();
defaultPaint.setAntiAlias(true);
//颜色大小这里可以随需求自定义
defaultPaint.setTextSize(sp2px(12));
defaultPaint.setColor(Color.GRAY);
selectPaint = new Paint();
selectPaint.setAntiAlias(true);
//颜色大小这里可以随需求自定义
selectPaint.setTextSize(sp2px(12));
selectPaint.setColor(Color.RED);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
@Override
protected void onDraw(Canvas canvas) {
//相邻字母间的高度差
int itemHeight = (getHeight() - getPaddingTop() - getPaddingBottom())/LETTERS.length;
for (int i = 0; i < LETTERS.length; i++) {
//x 坐标 取文本最左边位置,默认的文本对齐方式是靠左
int textWidth = (int) defaultPaint.measureText(LETTERS[i]);
int dx = getWidth()/2 - textWidth/2;
//y基线坐标
Paint.FontMetrics fontMetrics = defaultPaint.getFontMetrics();
//这里不能用控件高度的1/2 来作为基线,可以从网上详细查看基线的计算公式
int dy = (int) ((fontMetrics.bottom - fontMetrics.top) / 2 - fontMetrics.bottom);
int baseY = dy + itemHeight * i + itemHeight /2 - getPaddingTop();
if (LETTERS[i].equals(mCurrentTouchLetter)){
//触摸的是当前的字母
canvas.drawText(LETTERS[i],dx,baseY,selectPaint);
}else {
canvas.drawText(LETTERS[i],dx,baseY,defaultPaint);
}
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()){
//只关注按下的时候
case MotionEvent.ACTION_DOWN:
int itemHeight = (getHeight() - getPaddingTop() - getPaddingBottom())/LETTERS.length;
int currentY = (int) event.getY();
int currentPos = currentY/itemHeight;
if (currentPos < 0){
currentPos = 0;
}
if (currentPos > LETTERS.length -1){
currentPos = LETTERS.length -1;
}
mCurrentTouchLetter = LETTERS[currentPos];
invalidate();
break;
case MotionEvent.ACTION_UP:
if (listener != null){
listener.onTouchLetter(mCurrentTouchLetter);
}
break;
}
return true;
}
// sp 转 px
private float sp2px(int sp) {
return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,
sp, getResources().getDisplayMetrics());
}
//将选中的字母回调出去
public interface OnTouchLetterListener{
void onTouchLetter(String letter);
}
}
在使用的时候可以拿到回调的字母,来进行操作,比如要在界面中间展示选中的字母,以及进行查询列表操作
LetterSortView letterSortView = findViewById(R.id.letter);
letterSortView.setListener(new LetterSortView.OnTouchLetterListener() {
@Override
public void onTouchLetter(String letter) {
}
});