先來看右側滑動條佈局
<com.reige.addressbook.IndexBar
android:layout_alignParentRight="true"
android:layout_width="20dp"
android:layout_height="wrap_content"
android:layout_marginTop="30dp"
android:layout_marginBottom="30dp"/>
然後我們創建一個類繼承View來繪製右側字母導航滑動條
//初始化的方法
private void init() {
//抗鋸齒
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
//設置繪製的文字大小
mPaint.setTextSize(30);
mPaint.setColor(Color.BLUE);
//因爲默認的文字繪製錨點在文字的左下角,這樣會使文字的左邊在一條直線上 因爲字母的寬度不同會使繪製出的字母看上去比較亂 這個方法可以將錨點設置到文字底部中心 從而避免這個問題
mPaint.setTextAlign(Paint.Align.CENTER);
}
繪製簡單原理
public class IndexBar extends View {
private OnSlideListener onSlideListener;
private String[] arr = {"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 Paint mPaint;
private int mWidth;
private float mBoxHeight;
public IndexBar(Context context) {
super(context);
}
public IndexBar(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public IndexBar(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
private void init() {
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaint.setTextSize(30);
mPaint.setColor(Color.BLUE);
//因爲默認的文字繪製錨點在文字的左下角,這樣會使文字的左邊在一條直線上 因爲字母的寬度不同會使繪製出的字母看上去比較亂 這個方法可以將錨點設置到文字底部中心 從而避免這個問題
mPaint.setTextAlign(Paint.Align.CENTER);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mWidth = getMeasuredWidth();
mBoxHeight = getMeasuredHeight() * 1f / arr.length;
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
for (int i = 0; i < arr.length; i++) {
float textHeight = getTextHeight(arr[i]);
float x = mWidth / 2;
float y = (1 + i) * mBoxHeight;
mPaint.setColor(lastIndex==i?Color.RED:Color.BLUE);
canvas.drawText(arr[i], x, y, mPaint);
}
}
private int lastIndex = -1;
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_MOVE:
float y = event.getY();
//獲取當前點擊第幾個item
int index = (int) (y / mBoxHeight);
if (lastIndex != index) {
if (index >= 0 && index < arr.length) {
Log.e("index", "index:::" + index);
//選擇的letter變化 回調
if(onSlideListener!=null){
onSlideListener.onSlide(arr[index]);
}
}
}
lastIndex = index;
break;
case MotionEvent.ACTION_UP:
lastIndex = -1;
break;
}
invalidate();
return true;
}
/**
* @param text
* @return 返回文字的高
*/
private float getTextHeight(String text) {
Rect rect = new Rect();
mPaint.getTextBounds(text, 0, text.length(), rect);
return rect.height();
}
/**
* 設置監聽的方法
*/
public interface OnSlideListener{
void onSlide(String letter);
}
/**
* 滑動監聽
* @param osl
*/
public void setOnSlideListener(OnSlideListener osl){
this.onSlideListener = osl;
}
}