一、ListView的侧边字母滑动索引

一、最终效果

二、功能分析与实现

1.LisetView布局

分析:同样的字母开头,第一个上方有该字母的标志

实现:在item布局中除了TextView再在其上方加一个TextView等布局(用于显示数据的首字母),然后在适配器的getView中判断该布局是否显示。默认设置该布局的Visibility为VISIBLE,当该布局的的文字内容首字母与上一个不同时说明该item是新的首字母开头,设置为VISIBLE,否则设置为GONE。

部分代码:

// 默认显示 为了显示第一个布局以及布局复用出现的问题

vh.cd_lable.setVisibility(View.VISIBLE);

String now_city = Cheeses.sCheeseStrings[position];

vh.tv_city.setText(now_city);

String now_letter = now_city.substring(0, 1).toUpperCase();

vh.tv_label.setText(now_letter);

if (position != 0) {

// 与上一个比较 如果不同说明为该字母段的第一个

String pre_letter = Cheeses.sCheeseStrings[position - 1]

.substring(0, 1).toUpperCase();

if (!pre_letter.equals(now_letter)) {

vh.cd_lable.setVisibility(View.VISIBLE);

} else {

vh.cd_lable.setVisibility(View.GONE);

}

}

2.自定义控件字母索引

1.新建一个类继承View,重写两个参数的构造方法,为了获取AttributeSet。重写onDraw方法。

2.画文字A-Z

1)调用canvas的drawText(String text, float x, float y, Paint paint)方法用来画A-Z,这里的参数分别代表需要画的文字,起始位置坐标(x,y),画笔。我们先在构造方法里new Paint(Paint.ANTI_ALIAS_FLAG),这里的参数是为了抗锯齿。

2)画笔有了还需要坐标和文字大小,构造方法里的AttributeSet参数就有作用了。我们在res/values目录下建一个attrs.xml文件,为了放一些我们自定义控件所需要的属性。如下:

<resources>

<declare-styleable name="LetterSlideView">

<attr name="textsize" format = "dimension|reference"  />

<attr name="backcolor" format = "color|reference"  />

<attr name="frontcolor" format = "color|reference"  />

</declare-styleable>

</resources>

name一般为你自定义控件的类名,下面属性意思就是名字不多说了,format是为了限定你输入的内容格式,dimension|reference就是只能sp dp或者资源文件之类的。然后再自定义控件类的构造方法中获取这些属性的值:

TypedArray typedArray = context.obtainStyledAttributes(attrs,

R.styleable.LetterSlideView);

text_size = typedArray.getDimension(

R.styleable.LetterSlideView_textsize, 26);

back_color = typedArray.getColor(R.styleable.LetterSlideView_backcolor,

Color.BLACK);

front_color = typedArray.getColor(

R.styleable.LetterSlideView_frontcolor, Color.RED);

typedArray.recycle();

这时有了文字的大小我们就可以计算我们要画的坐标了,使用paint.measureText(letter);方法可以计算传入文字letter的宽度,x轴的坐标即为

float letter_w = paint.measureText(letter);

letter_x = (int) ((getWidth() - letter_w) / 2);

getWidth()方法获得控件的总宽度,(总宽度-文字宽度)/2作为起点的x坐标可以让该文字画在控件的正中间。因为我们需要从A画到Z所以写个26大小的for循环,每次y轴+一个文字的高度就可以了,为了让26个字母平均在整个空间的高度则用控件总高度getHeight()/26作为文字的高度。代码如下:

String letter = (char) (‘A‘ + i) + "";

letter_h = getHeight() / 26;

float letter_w = paint.measureText(letter);

letter_x = (int) ((getWidth() - letter_w) / 2);

canvas.drawText(letter, letter_x, letter_h * (i + 1), paint);

3.动画效果,按下控件有半透明背景以及点击的文字变色。

1)重写onTouchEvent方法获得触摸事件,按下的时候,文字变色,出现背景。松开的时候回归原状。

2)文字变色实现:调用event.getY()方法获取触摸事件的高度除以文字的高度这可以获得是第几个字母为成员变量index赋值,松开的时候设为-1。然后再画字的循环中判断是否是该字母并调用paint的setColor方法。

3)出现背景:当按下的时候为成员变量isPressed赋值原理同上,调用canvas.drawColor方法设置背景。

4)触摸事件结束时调用invalidate()方法,系统为执行onDraw()方法,注意最后要return ture;表示该事件由我们处理了。

4.自定义控件控制ListvView的显示。

1)自定义接口为了实现回调,类似于其他控件的setOnclick机制,写一个public的方法用来获取接口,在触摸事件中调用接口的方法(判断非空)暴露该空间的index值。

接口:

public interface OnLSVTouchListener {

public void getState(int index);

}

方法:

public void setOnLSVTouchListener(OnLSVTouchListener listener) {

this.listener = listener;

}

暴露控件的index:

if (listener != null) {

listener.getState(index);

}

2)在activity中find该控件并实现该接口,这时候我们就获取到了index也就是第几个英文字母,这时候就需要知道我们的数据中那些数据是同样首字母的第一个。

letter_list.add(0);

for (int i = 0; i < Cheeses.sCheeseStrings.length; i++) {

if (i + 1 < Cheeses.sCheeseStrings.length) {

if (!Cheeses.sCheeseStrings[i].substring(0,1)

.equals(Cheeses.sCheeseStrings[i + 1].substring(0,1))) {

letter_list.add(i + 1);

}

}

}

第一个数据肯定符合要求,然后就是把当前的数据首字母与后一个比较不一样则保存后一个数据进我们的new的容器中(代码没优化)。

3)实现控制Listview,调用listview的setSelection()方法,传来的index相当于就是我们保存的容器的index,获取到position设置就好了。中间显示的TextView同理。

三、布局使用自定义控件

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"

xmlns:tools="http://schemas.android.com/tools"

xmlns:app="http://schemas.android.com/apk/res/com.example.customview"

android:id="@+id/FrameLayout1"

android:layout_width="match_parent"

android:layout_height="match_parent"

tools:context="com.example.ui_day2_city_customview.MainActivity" >

<ListView

android:id="@+id/lv_city"

android:layout_width="match_parent"

android:layout_height="match_parent" >

</ListView>

<TextView

android:id="@+id/tv_city_letter"

android:layout_width="120dp"

android:layout_height="120dp"

android:layout_gravity="center"

android:background="#80000000"

android:textSize="80sp"

android:textColor="#FFFFFF"

android:gravity="center"

android:visibility="gone" />

<com.example.customview.LetterSlideView

android:id="@+id/lsv_city"

android:layout_width="30dp"

android:layout_height="match_parent"

android:layout_gravity="right" >

</com.example.customview.LetterSlideView>

</FrameLayout>

注意自定义命名空间、帧布局的位置用android:layout_gravity调整,自定义控件需要完整的包名

注:比较懒,不要在意细节。

时间: 2024-10-17 13:14:28

一、ListView的侧边字母滑动索引的相关文章

android之ListView分组及字母索引导航(2)重构-接口

上篇文章对listView 分组和字母索引导航的实现思路做了分析,并依照思路一步步实现,到最后已经较好的实现了全部功能.但是仔细研究就会发现其实现不够好,主要问题: 1.               对于一个使用范围比较广泛的布局,以上实现不够通用,尤其是Bo中需加上一些多余的字段,这些字字段本身并没有意义. 2.               代码都糅合在activity中. 针对以上两点做一些代码重构.首先我们把其优化为一个通用的activity.这样做成通用的View就很容易:然后对代码进行

一款很实用的 字母条索引+自定义进度条

代码下载地址 点击打开链接 自己之前写过几个联系人索引条的小demo,但没有在项目中自己体验过,最近项目中有用到,这个功能模块是同事写的,今天抽空摘出来下,以保存,将来可以用到 接下来就一步步简单的说下思路吧:action开始 首先先看下主界面的布局文件吧 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.andro

Android 实现ListView的A-Z字母排序和过滤搜索功能,实现汉字转成拼音

转载请注明出处:http://blog.csdn.net/xiaanming/article/details/12684155 前段时间因为换工作的缘故又恰巧碰到国庆节,所以有段时间自己没有更新博客了,过完国庆到新公司报道,感觉还不错,就是现在住的地方离新公司有点远,地铁20站,伤不起啊,我每天早上7点多就要起床,然后屁颠屁颠的去挤地铁上班,晚上下班还要挤地铁,先不说路程远,车费一天就要10几块,我的银子啊,有坐龙华线去上班的深圳程序员不?听说那条线上班高峰期很挤?我没在上班高峰期坐过那趟车,我

[Android分享] 【转帖】Android ListView的A-Z字母排序和过滤搜索功能

感谢eoe社区的分享 最近看关于Android实现ListView的功能问题,一直都是小伙伴们关心探讨的Android开发问题之一,今天看到有关ListView实现A-Z字母排序和过滤搜索功能并且实现汉字转成拼音的功能,转帖来和eoe的小伙伴们一同分享下! Android 有关ListView实现A-Z字母排序和过滤搜索功能并且实现汉字转成拼音的功能 我们知道一般我们对联系人,城市列表等实现A-Z的排序,因为联系人和城市列表我们可以直接从数据库中获取他的汉字拼音,而对于一般的数据,我们怎么实现A

android 左右滑动+索引图标实现方法与代码

首先自定义Gallery实现一次只能滑动一个页面 代码如下: public class MGalleryView extends Gallery{ public MGalleryView(Context context, AttributeSet attrs) { super(context, attrs); } //一次只能滑动一张图片注:一张图充满全屏 @Override public boolean onFling(MotionEvent e1, MotionEvent e2, float

快速集成android实现listview的字母A-Z排序,界面侧边字母索引

 转载请标明出处 Android手机字母A-Z排序侧边索引是非常常见的功能,在此提供快速集成框架.教你用Android studio工具一分钟搞定这个效果. 实现效果: 以及点击F跳转效果 第一步库包导入实现拼音检索功能 -------拼音检索详细见: compile 'com.github.promeg:tinypinyin:1.0.0'// ~80KB同步后后面会下载80k的文件,就可以使用 -------测试一下: public void go1(View view){//按钮go1点击测

联系人列表字母排序索引(三)

也是忙忙碌碌好几天,今天又有时间了,继续这个文章的编写.今天是这篇文章的最后一部分.主要内容包括以下几点: 1.将中文名字转化成拼音,并提取首字母,进行排序. 2.实现分组列表Adapter模板. 3.将列表与索引结合在一起. pinyin4j是一个将中文转化成拼音的高效工具,我的源码中带了这个依赖包.通过这个工具,可以先获取一个中文的拼音. public static String getLetter(String name) { StringBuilder sb = new StringBu

字母条索引定位

activity_main.xml <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <ListView android:id="@+id/listview" an

Android 自定义ListView控件,滑动删除

1.触摸事件 dispatchTouchEvent 判断是否处理触摸动作 onTouchEvent 处理触摸动作 2.Android对于控制和获取View在屏幕很强大 ListView: pointToPosition 根据触摸点获取item的位置 getChildAt 根据索引获取item的View,注意从第一个可视化的item算起 View: getLocationOnScreen获取View在屏幕的坐标 import android.content.Context; import andr