android 索引界面,Android 自定义View 字母索引列表

1.字母索引列表效果

0e358b5ce98b

image.png

2.效果分析

2.1 当用于手指触摸右侧字母列表时,手指滑动,页面中间显示显示字母大写,同时,右侧的字母列表中的当前字母同时变大,变红色。

2.2 绘制右侧字母列表

2.3 处理手指触摸事件,根据手指当前的高度除以右侧字母列表高度,计算得出当前手指所处高度的字母。

2.4 添加回调事件,手指移动时,回调显示页面中央的字母。

3.代码实现

3.1 创建自定义View

public class CMLetterSiderView extends View {

//定义26个字母

private static String[] cmLetterSiderViewLetters = {"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 cmLetterNormalPaint,cmLetterChoosePaint;

private int cmLetterChooseTextSize;

private int cmLetterChooseTextColor;

private int cmLetterNormalTextSize;

private int cmLetterNormalTextColor;

private String cmLetterCurrent;

public CMLetterSiderView(Context context) {

this(context,null);

}

public CMLetterSiderView(Context context, @Nullable AttributeSet attrs) {

this(context, attrs,0);

}

public CMLetterSiderView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {

super(context, attrs, defStyleAttr);

}

3.2 添加自定义属性

3.3 获取属性,添加画笔

/**

* 创建画笔

* 1.获取自定义属性

* 2.创建画笔

*/

private void initPaint(Context context, @Nullable AttributeSet attrs) {

TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.CMLetterSiderView);

cmLetterNormalTextColor = typedArray.getColor(R.styleable.CMLetterSiderView_cmLetterSiderNormalTextColor,cmLetterNormalTextColor);

cmLetterNormalTextSize = (int) typedArray.getDimension(R.styleable.CMLetterSiderView_cmLetterSiderNormalTextSize,cmLetterNormalTextSize);

cmLetterChooseTextColor = typedArray.getColor(R.styleable.CMLetterSiderView_cmLetterSiderChooseTextColor, cmLetterChooseTextColor);

cmLetterChooseTextSize = (int) typedArray.getDimension(R.styleable.CMLetterSiderView_cmLetterSiderChooseTextSize,cmLetterChooseTextSize);

typedArray.recycle();

cmLetterNormalPaint = new Paint();

cmLetterNormalPaint.setAntiAlias(true);

cmLetterNormalPaint.setColor(cmLetterNormalTextColor);

cmLetterNormalPaint.setTextSize(cmLetterNormalTextSize);

cmLetterChoosePaint = new Paint();

cmLetterChoosePaint.setAntiAlias(true);

cmLetterChoosePaint.setColor(cmLetterChooseTextColor);

cmLetterChoosePaint.setTextSize(cmLetterChooseTextSize);

}

3.4 从新测量,设置字母列表的宽高

/**

* 重新测量宽高

* @param widthMeasureSpec

* @param heightMeasureSpec

*/

@Override

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

super.onMeasure(widthMeasureSpec, heightMeasureSpec);

int width = MeasureSpec.getSize(widthMeasureSpec);

int height = MeasureSpec.getSize(heightMeasureSpec);

int textWidth = (int) cmLetterNormalPaint.measureText("A");// A字母的宽度

width = getPaddingLeft()+getPaddingLeft()+textWidth;

height = height + 1*cmLetterSiderViewLetters.length;

//重新设置宽高

setMeasuredDimension(width,height);

}

3.5 绘制字母列表

/**

* 重新绘制

* @param canvas

*/

@Override

protected void onDraw(Canvas canvas) {

//重新绘制

//获取单个字母条目的高度

int itemsHeight = (getHeight() - getPaddingBottom() - getPaddingTop())/cmLetterSiderViewLetters.length;

//for循环画出26个字母

for (int i = 0; i < cmLetterSiderViewLetters.length; i++){

float y = (getHeight() - getPaddingBottom() - getPaddingTop())/cmLetterSiderViewLetters.length;

int letterCenterY = (int) (y*i + y/2 + getPaddingTop());

Paint.FontMetrics fontMetrics = cmLetterNormalPaint.getFontMetrics();

int dy = (int) ((fontMetrics.bottom - fontMetrics.top)/2 - fontMetrics.bottom);

int baseLine = letterCenterY + dy;

if(cmLetterSiderViewLetters[i].equals(cmLetterCurrent)){

float x = getWidth()/2 - cmLetterChoosePaint.measureText(cmLetterSiderViewLetters[i])/2;

canvas.drawText(cmLetterSiderViewLetters[i],x,baseLine,cmLetterChoosePaint);

}else{

float x = getWidth()/2 - cmLetterNormalPaint.measureText(cmLetterSiderViewLetters[i])/2;

canvas.drawText(cmLetterSiderViewLetters[i],x,baseLine,cmLetterNormalPaint);

}

}

}

3.6 重写onTouchEvent()方法,处理move事件

@Override

public boolean onTouchEvent(MotionEvent event) {

switch (event.getAction()){

case MotionEvent.ACTION_DOWN:

case MotionEvent.ACTION_MOVE:

//获取当前手指的位置(高度),用当前手指的高度除以单个字母的高度,得出手指当前所处于哪个字母上

float currentMoveY = event.getY();

float itemHeight = (getHeight() - getPaddingTop() - getPaddingBottom())/cmLetterSiderViewLetters.length;

int currentPosition = (int) (currentMoveY/itemHeight);

if(0 > currentPosition){

currentPosition = 0;

}

if((cmLetterSiderViewLetters.length - 1) < currentPosition){

currentPosition = cmLetterSiderViewLetters.length - 1;

}

cmLetterCurrent = cmLetterSiderViewLetters[currentPosition];

if(mCMLetterSiderTouchListener != null){

mCMLetterSiderTouchListener.cmLetterSiderTouchListener(cmLetterCurrent,true);

}

invalidate();

break;

case MotionEvent.ACTION_UP:

if(mCMLetterSiderTouchListener != null){

mCMLetterSiderTouchListener.cmLetterSiderTouchListener(cmLetterCurrent,false);

}

break;

}

return true;

}

3.6 提供回调方法

//提供回掉方法

private CMLetterSiderTouchListener mCMLetterSiderTouchListener;

public void setOnCMLetterSiderTouchListener(CMLetterSiderTouchListener mCMLetterSiderTouchListener){

this.mCMLetterSiderTouchListener = mCMLetterSiderTouchListener;

}

public interface CMLetterSiderTouchListener{

void cmLetterSiderTouchListener(CharSequence letter,boolean isTouch);

}

4

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值