做个简单的Android列表字母索引控件
作者:互联网
⚠️ 注意:本文撰写日期为 2016-08-02
相信大家在许多App中都见到过带字母索引的界面,比如我最近看到的这个开源控件:
很酷是不是?!!!如果加在例如联系人列表界面上,大大提升了用户体验。
那么这个索引控件要怎么做呢,说到底就是自定义一个view,因为自身能力原因我并不能做出这样的效果,当然各位大神们可以自行去研究这类开源索引控件的源码。
以我的能力,现在只能做这样的:
虽然简单,但是对于新手来说学习一番还是不错的。 下面我们开始一步步写一个字母索引控件 SimpleSideBar
准备一些知识
这里推荐博主guolin的一系列文章
第一步,创建类SimpleSideBar继承View
public class SimpleSideBar extends View {
public SimpleSideBar(Context context) {
super(context);
}
public SimpleSideBar(Context context, AttributeSet attrs) {
super(context, attrs);
}
public SimpleSideBar(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
}
第二步,声明所需要的变量
// 索引字母数组
private String[] alphabet = {
"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 int currentChoosenAlphabetIndex=-1;
// 画笔
private Paint mPaint=new Paint();
// 索引字母绘制大小
private int alphabetTextSize=20;
第三步,重写onDraw函数
该函数是绘制函数,通过它将控件内容显现出来
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// 获得控件高度
int viewHeight=getHeight();
// 获得控件宽度
int viewWidth=getWidth();
// 控件高度除以索引字母个数得到每个索引字母的高度
int heightPerAlphabet=viewHeight/alphabet.length;
//通过循环每个索引字母,并绘制出来
for (int i=0;i<alphabet.length;i++){
// 设置画笔颜色、画笔绘制文字粗细和大小,设置抗锯齿
mPaint.setColor(Color.BLACK);
mPaint.setTypeface(Typeface.DEFAULT_BOLD);
mPaint.setTextSize(alphabetTextSize);
mPaint.setAntiAlias(true);
// 如果当前选择的索引字母下标和循环到的索引字母下标相同
if(currentChoosenAlphabetIndex==i){
// 设置画笔颜色,绘制文字大小和加粗
mPaint.setColor(Color.YELLOW);
mPaint.setTextSize(alphabetTextSize);
mPaint.setFakeBoldText(true);
}
// 索引字母的相对于控件的x坐标,此处算法结果为居中
float xPos=viewWidth/2-mPaint.measureText(alphabet[i])/2;
// 索引字母的相对于控件的y坐标,索引字母的高度乘以索引字母下标+1即为y坐标
float yPos=heightPerAlphabet*i+heightPerAlphabet;
// 绘制索引字母
canvas.drawText(alphabet[i],xPos,yPos,mPaint);
// 重置画笔,为绘制下一个索引字母做准备
mPaint.reset();
}
}
到这里,我们直接把该控件加入layout中已经可以显示出来,只是没有触摸到索引字母使ListView/RecyclerView滚动到相应位置的功能。
如果要实现这个功能,我们需要重写dispatchTouchEvent函数来处理控件触摸事件,并且要对外提供一个接口来实现列表滚动到相应位置。
下面我们继续实现它。
第四步,提供一个接口
首先定义一个接口
public interface OnLetterTouchedChangeListener{
void onTouchedLetterChange(String letterTouched);
}
接着声明一个接口变量,提供set方法
OnLetterTouchedChangeListener onLetterTouchedChangeListener;
public void setOnLetterTouchedChangeListener(OnLetterTouchedChangeListener onLetterTouchedChangeListener) {
this.onLetterTouchedChangeListener = onLetterTouchedChangeListener;
}
第五步,重写dispatchTouchEvent函数
该函数是控件触摸事件分发函数,当返回值为true时表示处理完毕不分发到下一级处理。
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
// 获得触摸后的动作
int action = event.getAction();
// 获得触摸点的Y轴坐标
float touchYPos=event.getY();
// 控件高度除以索引字母的个数得到每个索引字母的高度(这里进行int强转),触摸点的Y轴坐标除以每个索引字母的高度就得到触摸到的索引字母的下标
int currentTouchIndex= (int) (touchYPos/getHeight()*alphabet.length);
switch (action){
// 当触摸的动作为按下或者按下移动时
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_MOVE:
// 设置背景颜色
setBackgroundResource(R.color.grey_600);
// 设置当前选的索引字母的下标值为当前选择的值
currentChoosenAlphabetIndex=currentTouchIndex;
// 如果接口存在和索引下标值合法,执行接口方法,传入当前触摸的索引字母,供外部调用接收
if(onLetterTouchedChangeListener!=null&¤tTouchIndex<alphabet.length&¤tTouchIndex>-1){
onLetterTouchedChangeListener.onTouchedLetterChange(alphabet[currentTouchIndex]);
}
// 重新绘制控件,即重新执行onDraw函数
invalidate();
break;
case MotionEvent.ACTION_UP:
setBackgroundResource(R.color.grey_50);
// 当停止触摸控件的时候,将当前选择的索引字母下标值设为-1
currentChoosenAlphabetIndex=-1;
invalidate();
break;
default:break;
}
// 返回true表明该触摸事件处理完毕不分发出去
return true;
}
第六步,使用自定义的SimpleSideBar控件
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/root"
android:orientation="horizontal" android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
<me.pwcong.simplesidebar.view.SimpleSideBar
android:id="@+id/sideBar"
android:layout_width="30dp"
android:layout_height="wrap_content" />
</LinearLayout>
MainActivity.java
...
sideBar= (SimpleSideBar) findViewById(R.id.sideBar);
// 这里使用前面定义的接口
sideBar.setOnLetterTouchedChangeListener(new SimpleSideBar.OnLetterTouchedChangeListener() {
@Override
public void onTouchedLetterChange(String letterTouched) {
// 获得触摸到的索引字母,再通过索引字母获取相应item的下标,执行列表滚动方法
int pos=simpleAdapter.getLetterPosition(letterTouched);
if(pos!=-1){
recyclerView.scrollToPosition(pos);
* * *
**到这里我们的简单索引字母控件完成了,SimpleSideBar 的 Demo 可以在这里下载**
[github.com/pwcong/Simp…](https://link.juejin.cn/?target=https%3A%2F%2Fgithub.com%2Fpwcong%2FSimpleSideBar "https://github.com/pwcong/SimpleSideBar")
到这里我们的简单索引字母控件完成了,SimpleSideBar 的 Demo 可以在这里下载
最后
有小伙伴私信问Compose的问题,好不好用啊,现在要不要学啊?
其实答案很简单,自从谷歌2019年公布了声明式UI框架Jetpack Compose后,两年多的时间,各种大力宣传,和大量资源的倾斜,API功能都趋于稳定了。
至于好不好用,各种用过的同行都是持肯定态度的。优势大概就是这四点:
强大的工具和直观的Kotlin API
简化并加速了Android上的UI开发
可以帮助开发者用更少更直观的代码创建View
有更强大的功能,以及还能提高开发速度
这么大的优势,毋庸置疑,肯定是要学的嘛,而且越快掌握越好。别等刀架到脖子上了,才去练金钟罩。
至于怎么快速上手,可以给大家免费分享一份**《Jetpack Compose 完全开发手册》**,手把手教大家从入门到精通。
第一章 初识 Jetpack Compose
-
为什么我们需要一个新的UI 工具?
-
Jetpack Compose的着重点
加速开发
强大的UI工具
直观的Kotlin API
- API 设计
- Compose API 的原则
一切都是函数
顶层函数(Top-level function)
组合优于继承
信任单一来源
- 深入了解Compose
Core
Foundation
Material
- 插槽API
第二章 Jetpack Compose构建Android UI
- Android Jetpack Compose 最全上手指南
Jetpack Compose 环境准备和Hello World
布局
使用Material design 设计
Compose 布局实时预览
……
- 深入详解 Jetpack Compose | 优化 UI 构建
Compose 所解决的问题
Composable 函数剖析
声明式 UI
组合 vs 继承
封装
重组
……
- 深入详解 Jetpack Compose | 实现原理
@Composable 注解意味着什么?
执行模式
Positional Memoization (位置记忆化)
存储参数
重组
……
第三章 Jetpack Compose 项目实战演练(附Demo)
- Jetpack Compose应用1
开始前的准备
创建DEMO
遇到的问题
- Jetpack Compose应用2
- Jetpack Compose应用做一个倒计时器
数据结构
倒计时功能
状态模式
Compose 布局
绘制时钟
- 用Jetpack Compose写一个玩安卓App
准备工作
引入依赖
新建 Activity
创建 Compose
PlayTheme
画页面
底部导航栏
管理状态
添加页面
- 用Compose Android 写一个天气应用
开篇
画页面
画背景
画内容
……
- 用Compose快速打造一个“电影App”
成品
实现方案
实战
不足
……
由于篇幅限制,文档的详解资料太全面,细节内容太多,所以只把部分知识点截图出来粗略的介绍,每个小节点里面都有更细化的内容!
有需要的话可以点下面二维码免费领取↓↓↓
标签:控件,Compose,Jetpack,字母,索引,Android,SimpleSideBar 来源: https://blog.csdn.net/Androiddddd/article/details/123140425