Android如何实现自定义字母选择侧边栏
发表于:2025-11-07 作者:千家信息网编辑
千家信息网最后更新 2025年11月07日,这篇文章将为大家详细讲解有关Android如何实现自定义字母选择侧边栏,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。具体内容如下LetterSideBar.java
千家信息网最后更新 2025年11月07日Android如何实现自定义字母选择侧边栏
这篇文章将为大家详细讲解有关Android如何实现自定义字母选择侧边栏,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。
具体内容如下
LetterSideBar.java
package com.zb.customview.widgets; import android.content.Context;import android.content.res.TypedArray;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.Rect;import android.text.TextUtils;import android.util.AttributeSet;import android.view.MotionEvent;import android.view.View; import androidx.annotation.Nullable; import com.zb.customview.R; public class LetterSideBar extends View { private Paint mPaint; private int color, selectedColor; private float textSize, spacing; private String mChoosing = "Z"; private OnLetterSelectedListener listener; private int width, height; private String[] LETTERS = new String[] {"#", "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 interface OnLetterSelectedListener { //空表示取消选中 void onSelected(String letter); } public void setOnLetterSelectedListener(OnLetterSelectedListener listener) { this.listener = listener; } public LetterSideBar(Context context) { this(context, null); } public LetterSideBar(Context context, @Nullable AttributeSet attrs) { super(context, attrs); if(null != attrs) { TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.LetterSideBar); color = ta.getColor(R.styleable.LetterSideBar_LetterSideBar_textColor, Color.BLACK); selectedColor = ta.getColor(R.styleable.LetterSideBar_LetterSideBar_textSelectedColor, Color.RED); textSize = ta.getDimensionPixelSize(R.styleable.LetterSideBar_LetterSideBar_textSize, sp2px(12)); spacing = ta.getDimensionPixelSize(R.styleable.LetterSideBar_LetterSideBar_spacing, dp2px(5)); ta.recycle(); } init(); } private void init() { mPaint = new Paint(); mPaint.setAntiAlias(true); mPaint.setColor(color); mPaint.setTextSize(textSize); } @Override protected void onDraw(Canvas canvas) { drawText(canvas); drawSelectedText(canvas, mChoosing); } private void drawText(Canvas canvas) { mPaint.setColor(color); for (int i=0; i= LETTERS.length) return; drawLetterAt(canvas, position, selected); } @Override public boolean onTouchEvent(MotionEvent event) { int action = event.getAction(); switch (action) { case MotionEvent.ACTION_DOWN: case MotionEvent.ACTION_MOVE: float x = event.getX(); float y = event.getY(); if(isTouchInsideView(x, y)) { //触摸在控件内 int position = caculatePosition(y); if(position >= 0 && position < LETTERS.length) { //合规位置 String letter = LETTERS[position]; if(!letter.equals(mChoosing)) { //与选中的不符 去刷新控件 mChoosing = letter; performListener(mChoosing); invalidate(); } } else { //不合规位置 if(null != mChoosing) { mChoosing = null; performListener(mChoosing); invalidate(); } } } else if(null != mChoosing) { //点击事件不在view内部 mChoosing = null; performListener(mChoosing); invalidate();//触摸在view之外 取消选中 } return true; default: if(mChoosing != null) { mChoosing = null; performListener(mChoosing); invalidate(); } break; } return super.onTouchEvent(event); } private void performListener(String letter) { if(null != listener) listener.onSelected(letter); } private boolean isTouchInsideView(float x, float y) { //左右可以适当判断在控件内 if(x >= 0 && x <= width && y >= getPaddingTop() && y < height) return true; return false; } /** * 计算触摸的位置 * @param y * @return */ private int caculatePosition(float y) { float heightWithOutPadding = height - getPaddingTop() - getPaddingBottom(); float eachElementHeight = heightWithOutPadding / LETTERS.length; y -= getPaddingTop(); int position = (int) (y / eachElementHeight); return position; } private void drawLetterAt(Canvas canvas, int position, String letter) { float heightForEach = ((height * 1f - getPaddingTop() - getPaddingBottom()) - (LETTERS.length - 1) * spacing) / LETTERS.length; float spacingInUp = spacing * (position - 1); if(spacingInUp < 0) spacingInUp = 0; float currentTop = getPaddingTop() + (heightForEach * position) + spacingInUp; float currentBottom = currentTop + heightForEach; Paint.FontMetrics fmi = mPaint.getFontMetrics(); float x = (width - getPaddingLeft() - getPaddingRight() - mPaint.measureText(letter)) / 2f + getPaddingLeft(); float baseLine = (fmi.descent + Math.abs(fmi.ascent)) / 2f - fmi.descent; float y = (currentBottom + currentTop) / 2f + baseLine; canvas.drawText(letter, 0, 1, x, y, mPaint); } @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); if(changed) { width = getWidth(); height = getHeight(); } } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); int textWidth = (int) (getPaddingLeft() + getPaddingRight() + mPaint.measureText("A")); Rect textBounds = new Rect(); mPaint.getTextBounds("A", 0, 1, textBounds); int singleTextHeight = textBounds.height(); int totalHeight = (int) (27f * singleTextHeight + 26f * spacing) + getPaddingBottom() + getPaddingTop();//26个字母+1个# int widthMode = MeasureSpec.getMode(widthMeasureSpec); int heightMode = MeasureSpec.getMode(widthMeasureSpec); int specWidth = MeasureSpec.getSize(widthMeasureSpec); int specHeight = MeasureSpec.getSize(widthMeasureSpec); int realWidth, realHeight; if(widthMode == MeasureSpec.EXACTLY) { realWidth = specWidth; } else { realWidth = textWidth; } if(heightMode == MeasureSpec.EXACTLY) { realHeight = specHeight; } else { realHeight = totalHeight; } setMeasuredDimension(realWidth, realHeight); } protected int dp2px(int dp) { return (int) (getContext().getResources().getDisplayMetrics().density * dp + 0.5); } protected int sp2px(int sp) { return (int) (getContext().getResources().getDisplayMetrics().scaledDensity * sp + 0.5); }} attrs.xml
layout.xml
代码中使用
sideBar.setOnLetterSelectedListener(new LetterSideBar.OnLetterSelectedListener() { @Override public void onSelected(String letter) { if(TextUtils.isEmpty(letter)) { P.p("取消选中"); letterTxt.setVisibility(View.GONE); } else { P.p("选中" + letter); letterTxt.setText(letter); letterTxt.setVisibility(View.VISIBLE); } } });关于"Android如何实现自定义字母选择侧边栏"这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。
字母
篇文章
侧边
选择
内容
更多
P.p
不错
实用
代码
位置
控件
文章
知识
参考
帮助
有关
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
青浦区市场软件开发销售价格
2018广东网络安全宣传
kv数据库用处
室内装潢设计软件开发
福建万云网络技术
中医药网络技术平台
mysql创建数据库语句
学校开展网络安全周教育
禁服务器超级管理员权限
ajax直接访问数据库
想学软件开发 看什么书
福建戴尔服务器诚信为本云空间
网络安全应该几年进行一次评估
吴江区便宜服务器新报价
服务器怎么显示正在使用的用户
什么是计算机网络技术大赛
手语翻译软件开发
超级服务器 联想
数据库原理 新浪
工业控制用什么软件开发
请验证虚拟机管理服务器
网络安全法实施条例第七十二条
龙岗软件开发找健亚网络科技
eve人物和数据库
r710服务器安装
数据库链接失败请检查配置信息
如何进入穿越火线服务器
如何给数据库插入图片
关于网络安全对孩子的重要性
网络安全题材的美剧