字母条

 一:代码链接

二:需求描述

  看很多应用里都有字母条的效果,例如在联系人里就有字母条,方便用户快通过名字的首字母快速定位想找的联系人。 实现要求就是在手机里完整显A~Z的字母,当用户点击特定字母的时候,给出回调,同时把选中的字母颜色置红。

三:实现思路

1. 想要画出完整的字母,需要继承view,重写ondraw方法. canvas.drawText(String text , float x , float y , Paint p),就是专门在特定位置画单个子的。我们只需要获取到当前              用户配置的高度,循环26次,在特定地方画出text就可以完整的把A~Z的文字列表画出来。

        2. 想要知道用户点击了那个字母,只需要在onTouchEvent()方法里获取到当前y坐标,通过它值在整个高度里占的百分比,就可以知道它点击了那个字母。

        3. 封装一个字母点击回调,用户点击了那个就会回调发出了。

四:关键代码

       1. 字母主类LetterListView 的实现

        package com.lyg.letterlist.view;


import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Toast;


/**
 * @author luyg 
 * @function: 字母列表的组件,目前测绘还有点问题。支持指定大小和fill_parent两种,wrap_context有点问题
 */
@SuppressLint("NewApi")
public class LetterListView extends View {

private String[] letters = {
"A" ,"B" ,"C" ,"D" ,"E" ,"F" ,"G" ,"H" ,"I" ,"G" ,"K" ,"L" ,"M" ,"N" ,"O" ,"P" ,
"Q" ,"R" ,"S" ,"T" ,"U" ,"V" ,"W" ,"X" ,"Y" ,"Z" 
};
private int deafaultSize =50;
private LetterTouchLister letterTouchLister ;
private int selectIndex = -1 ;
private Paint paint ;
private Rect bounds ;
private int blockHeight ;

public LetterListView(Context context) {
super(context);
}


public LetterListView(Context context, AttributeSet attrs) {
super(context, attrs);
}

public LetterListView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}


/**
* @info: 测绘组件大小的
*/
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
float width = MeasureSpec.getSize(widthMeasureSpec);
float height = MeasureSpec.getSize(heightMeasureSpec);
int widthModel = MeasureSpec.getMode(widthMeasureSpec);
int widthResult = 0;
//根据用户的配置属性,合理设置属性值,高是用户定义的。宽合理设置
if (widthModel ==MeasureSpec.AT_MOST) {
//适配模式 配置为 wrap_context, 值完全和父组件的宽度一样大

widthResult = (int) Math.min(deafaultSize, width);
}else if (widthModel==MeasureSpec.EXACTLY) {
//精确模式 指定大小,配置为fill_parent/match_parent/给定具体大小
widthResult = (int) width ;
}else if (widthModel==MeasureSpec.UNSPECIFIED) {
//未指定模式
widthResult = deafaultSize ;
}
setMeasuredDimension((int)widthResult, (int)height);
}


@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
}

@Override
protected void onDraw(Canvas canvas) {
for (int i = 0; i < letters.length; i++) {
paint = new Paint();
paint.setTextSize(30);
paint.setStyle(Paint.Style.FILL);  
paint.setColor(Color.BLACK);
blockHeight = letters.length!=0? getMeasuredHeight()/letters.length : 0;
bounds = new Rect(); 
paint.getTextBounds(letters[i], 0, letters[i].length(), bounds);  
//文字居中 ,画文字是从传入的x是第一个字距离左边的距离,y是第一个字的地步距离y的距离。
if (i==selectIndex) {
paint.setColor(Color.RED);
}else {
paint.setColor(Color.BLACK);
}
canvas.drawText(letters[i], getMeasuredWidth()/2 - bounds.width()/2, (blockHeight*i +blockHeight/2) + bounds.height()/2, paint);  
}
}

public void setLetterTouchLister(LetterTouchLister letterTouchLister) {
this.letterTouchLister = letterTouchLister;
}




@Override
public boolean onTouchEvent(MotionEvent event) {
float x= event.getX();
float y= event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:

break;
case MotionEvent.ACTION_MOVE:

break;
case MotionEvent.ACTION_UP:
int index = getTouchIndex(y);
if (letterTouchLister!=null) {
letterTouchLister.onSelect(letters[index], index);
}
Toast.makeText(getContext(),letters[index] , 10000).show();
selectIndex = index ;
invalidate();
break;


default:
break;
}
//自己处理记得返回true
return true;
}


private int getTouchIndex(float curY){
int height= getMeasuredHeight()/letters.length ;
int value = (int)curY/height ;
return value;
}


public interface LetterTouchLister{
/**
* @param letter : 选中的字母
* @param index : 下标值
*/
void onSelect(String letter , int index);
}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值