看图片右侧字母排序的控件,触摸上面的字母,可迅速跳至指定字母分类,配合上一篇汉字转拼音,可以实现此功能。
如下代码,新建类,可copy直接使用。
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.view.MotionEvent;
import android.view.View;
/**
* 根据字母形成的索引栏 测试
*
* Created by yangxiix on 2015/11/16.
*/
public class LetterIndexBar extends View {
private String[] mIndexer = {"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", "#"};
private int height;
private int curChoose = -1; //当前选中
private OnTouchingLetterChangedListener onTouchingLetterChangedListener;
private Paint mPaint;
public LetterIndexBar(Context context) {
this(context, null);
}
public LetterIndexBar(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public LetterIndexBar(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
initData(canvas);
}
private void initData(Canvas canvas) {
DisplayMetrics dm = getResources().getDisplayMetrics();
float density = dm.density; //像素密度
int width = getWidth();
height = getHeight();
int perHeight = height / mIndexer.length;
canvas.drawColor(Color.parseColor("#FFC0CB")); //设置背景栏
mPaint = new Paint();
for (int i = 0; i < mIndexer.length; i++) {
if (curChoose != -1 && i == curChoose) {
mPaint.setTextSize(12 * density);
mPaint.setColor(Color.parseColor("#FFFFFF")); //设置选中后的颜色
mPaint.setAntiAlias(true); //是否反锯齿
canvas.drawText(mIndexer[i], width / 2f - mPaint.measureText(mIndexer[i]) / 2f, perHeight + perHeight * i, mPaint);
} else {
mPaint.setTextSize(12 * density);
mPaint.setColor(Color.parseColor("#FF0000")); //正常的颜色
mPaint.setAntiAlias(true); //是否反锯齿
canvas.drawText(mIndexer[i], width / 2f - mPaint.measureText(mIndexer[i]) / 2f, perHeight + perHeight * i, mPaint); //文字居中显示,宽度的一半 + 文体的一半
}
mPaint.reset();
}
}
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
float posY = event.getY();
final int oldChoose = curChoose;
int curLetterPos = (int) (posY / height * mIndexer.length);
final OnTouchingLetterChangedListener listener = onTouchingLetterChangedListener;
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
if (oldChoose != curLetterPos && listener != null) {
if (curLetterPos < mIndexer.length && curLetterPos >= 0) {
listener.onTouchingLetterChanged(mIndexer[curLetterPos]);
curChoose = curLetterPos;
invalidate();
}
}
break;
case MotionEvent.ACTION_MOVE:
if (oldChoose != curLetterPos && listener != null) {
if (curLetterPos < mIndexer.length && curLetterPos >= 0) {
listener.onTouchingLetterChanged(mIndexer[curLetterPos]);
curChoose = curLetterPos;
invalidate();
}
}
break;
case MotionEvent.ACTION_UP:
curChoose = -1;
invalidate();
break;
}
return true;
}
public void setOnTouchingLetterChangedListener(
OnTouchingLetterChangedListener onTouchingLetterChangedListener) {
this.onTouchingLetterChangedListener = onTouchingLetterChangedListener;
}
public interface OnTouchingLetterChangedListener {
public void onTouchingLetterChanged(String s);
}
}
我这边运行之后的效果是这样子的(颜色,字体都可以根据注释去改动):
如果你想做成颜色,字体大小由布局去实现你可以做如下小小的改进即可
定义一个attr.xml
里面定义代码:
<declare-styleable name="IndexerBar">
<attr name="show_common_icon" format="boolean" />
</declare-styleable>
然后在自定义的控件里面初始化时获取相关参数:
TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.IndexerBar);
boolean show_common_icon = ta.getBoolean(R.styleable.IndexerBar_show_common_icon, true);
然后就可以用相关定义的参数啦,动动脑,定义字体大小颜色可以用此类似方法。