Android如何实现自定义字母选择侧边栏
发表于:2025-02-01 作者:千家信息网编辑
千家信息网最后更新 2025年02月01日,这篇文章将为大家详细讲解有关Android如何实现自定义字母选择侧边栏,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。具体内容如下LetterSideBar.java
千家信息网最后更新 2025年02月01日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安全错误
数据库的锁怎样保障安全
湖南网络安全大赛
职业生涯规划书网络技术
面试时被问软件开发规划
软件开发行业程序文件
网络安全审查办法自 起施行
福山区安卓软件开发公司有哪些
voip服务器搭建打电话
数据库系统安全及防范措施
js如何存入数据库
网络安全手抄报网站
吉林省公安厅网络安全总队黄威
性能超老牌数据库
北京软件开发公司哪
引用tcga数据库的原始文献
服务器内存条是ecc吗
公安信息网络安全部门
数据库技术与应用冯博琴答案
论文软件开发的过程
网络安全漫画的手抄报
郑州蜜房网络技术有限公司
消费品安全数据库的争议漩涡
张掖市网络安全知识竞赛
论文编数据库
用数据库查询1986年出生的人
学校网络安全台帐
浙江惠普服务器维修维保多少钱
地下城堡2查看服务器
四川iptv服务器费用
互联网服务器哪家最多
pb 删除修改数据库连接