Android 实现带字母索引的侧边栏功能
程序员文章站
2023-12-13 13:21:40
之前已经用自定义view做出如下这样一个效果了
这两天需要重新拿来使用,发现效果虽然做出来了,不过思路不太对,就重新参考写了一个,用法也更为简单了
首要的自然是需要...
之前已经用自定义view做出如下这样一个效果了
这两天需要重新拿来使用,发现效果虽然做出来了,不过思路不太对,就重新参考写了一个,用法也更为简单了
首要的自然是需要继承view绘制出侧边栏,并向外提供一个监听字母索引变化的方法
/** * 作者:叶应是叶 * 时间:2017/8/20 11:38 * 描述: */ public class letterindexview extends view { public interface ontouchingletterchangedlistener { void onhit(string letter); void oncancel(); } private ontouchingletterchangedlistener touchingletterchangedlistener; private paint paint; private boolean hit; private final string[] letters = {"↑", "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 final int default_width; public letterindexview(context context) { this(context, null); } public letterindexview(context context, @nullable attributeset attrs) { this(context, attrs, 0); } public letterindexview(context context, @nullable attributeset attrs, int defstyleattr) { super(context, attrs, defstyleattr); paint = new paint(); paint.setantialias(true); paint.settextalign(paint.align.center); paint.setcolor(color.parsecolor("#565656")); default_width = dptopx(context, 24); } @override protected void onmeasure(int widthmeasurespec, int heightmeasurespec) { setmeasureddimension(getwidthsize(widthmeasurespec), getdefaultsize(getsuggestedminimumheight(), heightmeasurespec)); } private int getwidthsize(int widthmeasurespec) { int widthmode = measurespec.getmode(widthmeasurespec); int widthsize = measurespec.getsize(widthmeasurespec); switch (widthmode) { case measurespec.at_most: { if (widthsize >= default_width) { return default_width; } else { return widthsize; } } case measurespec.exactly: { return widthsize; } case measurespec.unspecified: default: return default_width; } } @override public boolean dispatchtouchevent(motionevent event) { switch (event.getaction()) { case motionevent.action_down: hit = true; onhit(event.gety()); break; case motionevent.action_move: onhit(event.gety()); break; case motionevent.action_up: case motionevent.action_cancel: hit = false; if (touchingletterchangedlistener != null) { touchingletterchangedlistener.oncancel(); } break; } invalidate(); return true; } @override protected void ondraw(canvas canvas) { if (hit) { //字母索引条背景色 canvas.drawcolor(color.parsecolor("#bababa")); } float letterheight = ((float) getheight()) / letters.length; float width = getwidth(); float textsize = letterheight * 5 / 7; paint.settextsize(textsize); for (int i = 0; i < letters.length; i++) { canvas.drawtext(letters[i], width / 2, letterheight * i + textsize, paint); } } private void onhit(float offset) { if (hit && touchingletterchangedlistener != null) { int index = (int) (offset / getheight() * letters.length); index = math.max(index, 0); index = math.min(index, letters.length - 1); touchingletterchangedlistener.onhit(letters[index]); } } public void setontouchingletterchangedlistener(ontouchingletterchangedlistener ontouchingletterchangedlistener) { this.touchingletterchangedlistener = ontouchingletterchangedlistener; } private int dptopx(context context, float dpvalue) { float scale = context.getresources().getdisplaymetrics().density; return (int) (dpvalue * scale + 0.5f); } }
在侧边栏时,中间会显示当前滑动指向的字母,这其实是一个textview,在主布局文件中添加,通过indexcontrol来控制textview的可见性,并指示listview滑动到指定项
/** * 作者:叶应是叶 * 时间:2017/8/20 11:39 * 描述: */ public class indexcontrol { private final listview listview; private final textview tv_hint; private final map<string, integer> lettermap; public indexcontrol(listview contactslistview, letterindexview letterindexview, textview tv_hint, map<string, integer> lettermap) { this.listview = contactslistview; this.tv_hint = tv_hint; this.lettermap = lettermap; letterindexview.setontouchingletterchangedlistener(new letterchangedlistener()); } private class letterchangedlistener implements letterindexview.ontouchingletterchangedlistener { @override public void onhit(string letter) { tv_hint.setvisibility(view.visible); tv_hint.settext(letter); int index = -1; if ("↑".equals(letter)) { index = 0; } else if (lettermap.containskey(letter)) { index = lettermap.get(letter); } if (index < 0) { return; } index += listview.getheaderviewscount(); if (index >= 0 && index < listview.getcount()) { listview.setselectionfromtop(index, 0); } } @override public void oncancel() { tv_hint.setvisibility(view.invisible); } } }
这里也提供代码下载:letterindexview
总结
以上所述是小编给大家介绍的android 实现带字母索引的侧边栏功能,希望对大家有所帮助
推荐阅读
-
Android实现ListView的A-Z字母排序和过滤搜索功能 实现汉字转成拼音
-
Android 实现带字母索引的侧边栏功能
-
Android实现自定义带删除功能的EditText实例
-
JavaScript实现简单的隐藏式侧边栏功能示例
-
Android实现自定义带删除功能的EditText实例
-
jQuery实现带右侧索引功能的通讯录示例【附源码下载】
-
实现WordPress主题侧边栏切换功能的PHP脚本详解
-
Android实现ListView的A-Z字母排序和过滤搜索功能,实现汉字转成拼音
-
JavaScript实现简单的隐藏式侧边栏功能示例
-
实现WordPress主题侧边栏切换功能的PHP脚本详解_php实例