首先需要下载pinyin4j-2.5.0.jar包,这是下载链接https://sourceforge.net/projects/pinyin4j/,下载完成之后在lib文件夹下面能够找到该jar包。

1,先自定义一个IndexView:


import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.Typeface;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
/*
* 1,绘制26个字母。分为以下几步:1,把26个字母放入数组中,2,itemView和Wordtext的宽度和高度
* itemViewWidth=viewWith;
* itemViewHeight=viewHeight/26;
* wordWidth=(自定义一个矩形).getWidth();
* wordHeight=(自定义一个矩形).getHeight();
* 自定义矩形Rect rect=new Rect();
*
*按下手指变色
* */public class IndexView extends View {private String[] words={"A","B","C","D","E","F","G","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 itemWidth;private int itemHeight;private Paint paint;private int touchIndex=-1;public IndexView(Context context,AttributeSet attrs) {super(context, attrs);paint=new Paint();paint.setColor(Color.WHITE);//设置画笔的颜色为白色paint.setTextSize(30);paint.setAntiAlias(true);//这只抗锯齿paint.setTypeface(Typeface.DEFAULT_BOLD);//设置粗体字}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);itemWidth=getMeasuredWidth();itemHeight=getMeasuredHeight()/words.length;}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);for (int i=0;i<words.length;i++){//字母变色if (touchIndex==i){//让当前字母变色paint.setColor(Color.GRAY);}else {//其他字母不变色paint.setColor(Color.WHITE);}String word=words[i];Rect rect=new Rect();paint.getTextBounds(word,0,1,rect);int wordWidth=rect.width();int wordHeight=rect.height();//计算每个字母在视图上的坐标位置float wordX=itemWidth/2-wordWidth/2;float wordY=itemHeight/2+wordHeight/2+i*itemHeight;canvas.drawText(word,wordX,wordY,paint);}}/** 点击变色* 1,在down  move中得到点击那个字母height/itemHeight* 2,up的时候再次绘制* */@Overridepublic boolean onTouchEvent(MotionEvent event) {super.onTouchEvent(event);switch (event.getAction()){case MotionEvent.ACTION_DOWN:case MotionEvent.ACTION_MOVE:float Y=event.getY();int index= (int) (Y/itemHeight);//字母的索引if (index!=touchIndex){touchIndex=index;//点击设置中间字母if (onClickShowWord!=null&&touchIndex<words.length){onClickShowWord.OnIndexChange(words[touchIndex]);}invalidate();}break;case MotionEvent.ACTION_UP:touchIndex=-1;invalidate();break;}return true;}private OnIndexChangeListener onClickShowWord;public void setOnIndexChangeListener(OnIndexChangeListener l){onClickShowWord=l;}//定义一个借口,实现点击字母,就再屏幕中央出现相应字母public interface OnIndexChangeListener{void OnIndexChange(String word);}
}

MAinActivity代码:


import android.os.Bundle;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.TextView;import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;public class MainActivity extends AppCompatActivity {private Handler handler=new Handler();private List<Person> personList;private TextView textView_center;private IndexView indexView;private ListView listView;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);textView_center=findViewById(R.id.tv_word);indexView=findViewById(R.id.iv_words);listView=findViewById(R.id.lv_main);personList=new ArrayList<>();initData();//点击字母回调实现屏幕中间显示字体indexView.setOnIndexChangeListener(new IndexView.OnIndexChangeListener() {@Overridepublic void OnIndexChange(String word) {textView_center.setVisibility(View.VISIBLE);textView_center.setText(word);handler.postDelayed(new Runnable() {@Overridepublic void run() {textView_center.setVisibility(View.GONE);}}, 1000);//点击右边字母进行定位,但是这是定位到最后一个for (int i=0;i<personList.size();i++){if (word.equals(personList.get(i).getPinyin().substring(0,1))){listView.setSelection(i);return;//return表示一旦满足这个条件就不再往下循环了,也就是定位到了最后一个}}}});listView.setAdapter(new MyAdapter());}class MyAdapter extends BaseAdapter{@Overridepublic int getCount() {return personList.size();}@Overridepublic Object getItem(int position) {return personList.get(position);}@Overridepublic long getItemId(int position) {return 0;}@Overridepublic View getView(int position, View convertView, ViewGroup parent) {ViewHloder viewHloder;if (convertView==null){convertView=View.inflate(MainActivity.this,R.layout.per_item,null);viewHloder=new ViewHloder();viewHloder.tv_content=convertView.findViewById(R.id.tv_content);viewHloder.tv_title=convertView.findViewById(R.id.tv_title);convertView.setTag(viewHloder);}else {viewHloder= (ViewHloder) convertView.getTag();}Person person=personList.get(position);String name=person.getName();String word=person.getPinyin().substring(0,1);if (position==0){viewHloder.tv_title.setVisibility(View.VISIBLE);viewHloder.tv_title.setText(word);}else {if (position>0&&word.equals(personList.get(position-1).getPinyin().substring(0,1))){viewHloder.tv_title.setVisibility(View.GONE);}else {viewHloder.tv_title.setVisibility(View.VISIBLE);viewHloder.tv_title.setText(word);}}viewHloder.tv_content.setText(name);return convertView;}}class ViewHloder{private TextView tv_title;private TextView tv_content;}@Overridepublic boolean dispatchTouchEvent(MotionEvent ev) {switch (ev.getAction()){case MotionEvent.ACTION_DOWN:Log.e("cylog","MainActivity dispatchTouchEvent down");break;case MotionEvent.ACTION_MOVE:Log.e("cylog","MainActivity dispatchTouchEvent move");break;case MotionEvent.ACTION_UP:Log.e("cylog","MainActivity dispatchTouchEvent up");break;}       return super.dispatchTouchEvent(ev);}@Overridepublic boolean onTouchEvent(MotionEvent event) {switch (event.getAction()){case MotionEvent.ACTION_DOWN:Log.e("cylog","MainActivity onTouchEvent down");break;case MotionEvent.ACTION_MOVE:Log.e("cylog","MainActivity onTouchEvent move");break;case MotionEvent.ACTION_UP:Log.e("cylog","MainActivity onTouchEvent up");break;}return super.onTouchEvent(event);}private void initData(){personList.add(new Person("白居易"));personList.add(new Person("尚小碗"));personList.add(new Person("岳飞"));personList.add(new Person("金兀术"));personList.add(new Person("钱钟书"));personList.add(new Person("陈寅恪"));personList.add(new Person("唐僧僧"));personList.add(new Person("孙物控"));personList.add(new Person("沙和尚"));personList.add(new Person("猪刚鬣"));personList.add(new Person("赵构"));personList.add(new Person("李世民"));personList.add(new Person("周文王"));personList.add(new Person("吴法克"));personList.add(new Person("马克龙"));personList.add(new Person("特奥朗"));personList.add(new Person("郎平"));personList.add(new Person("溥仪"));personList.add(new Person("曾国藩"));personList.add(new Person("周恩来"));personList.add(new Person("毛泽东"));personList.add(new Person("刘少奇"));personList.add(new Person("张之洞"));personList.add(new Person("杨绛"));personList.add(new Person("商客云"));personList.add(new Person("张壁画"));personList.add(new Person("王晓敏"));personList.add(new Person("王强"));personList.add(new Person("商丘人"));personList.add(new Person("李隆基"));Collections.sort(personList, new Comparator<Person>() {@Overridepublic int compare(Person o1, Person o2) {return o1.getPinyin().compareTo(o2.getPinyin());}});}
}

3.main_activity:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"><ListViewandroid:id="@+id/lv_main"android:layout_width="match_parent"android:layout_height="match_parent"/><TextViewandroid:id="@+id/tv_word"android:layout_width="80dp"android:layout_height="80dp"android:background="#44000000"android:gravity="center"android:layout_centerInParent="true"android:text="A"android:textSize="30sp"android:textColor="#000"android:visibility="gone"/><com.example.didi.pull_downproject.IndexViewandroid:id="@+id/iv_words"android:layout_width="30dp"android:layout_height="match_parent"android:layout_alignParentRight="true"android:background="#f00"/></RelativeLayout>

4,Person代码:


public class Person {private String name;private String pinyin;public Person(String name) {this.name = name;this.pinyin=PinYinUtils.getPinYin(this.name);}public void setName(String name) {this.name = name;}public void setPinyin(String pinyin) {this.pinyin = pinyin;}public String getName() {return name;}public String getPinyin() {return pinyin;}
}

5,PinYinUtils类:


import net.sourceforge.pinyin4j.PinyinHelper;
import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType;
import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat;
import net.sourceforge.pinyin4j.format.HanyuPinyinToneType;
import net.sourceforge.pinyin4j.format.exception.BadHanyuPinyinOutputFormatCombination;public class PinYinUtils {/** 得到指定汉字的拼音,注意此类不能被频繁使用,消耗内存*/public static String getPinYin(String hanzi){String pinyin="";HanyuPinyinOutputFormat format=new HanyuPinyinOutputFormat();format.setCaseType(HanyuPinyinCaseType.UPPERCASE);format.setToneType(HanyuPinyinToneType.WITHOUT_TONE);//把多个汉字转换成数组形式char[] arry=hanzi.toCharArray();for (int i=0;i<arry.length;i++){if (Character.isWhitespace(arry[i])){continue;}//汉字是两个字节存储,长度肯定大于127,所以长度大于127就可以转换成汉字if (arry[i]>127){//由于有多音字的存在,如"单shan  单dan"try {String[] pinyinArr=PinyinHelper.toHanyuPinyinStringArray(arry[i],format);if (pinyinArr!=null){pinyin += pinyinArr[0];}else {pinyin += arry[i];}} catch (BadHanyuPinyinOutputFormatCombination badHanyuPinyinOutputFormatCombination) {badHanyuPinyinOutputFormatCombination.printStackTrace();pinyin += arry[i];}}else {//不是汉字pinyin += arry[i];}}return pinyin;}
}

6,per_item.xml:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="wrap_content"android:paddingLeft="5dp"><TextViewandroid:id="@+id/tv_title"android:layout_width="match_parent"android:layout_height="35dp"android:layout_alignParentTop="true"android:layout_alignParentLeft="true"android:background="#44000000"android:textSize="20sp"android:visibility="gone"android:gravity="center_vertical"android:text="N"/><TextViewandroid:id="@+id/tv_content"android:layout_width="match_parent"android:layout_height="40dp"android:gravity="center_vertical"android:layout_below="@+id/tv_title"android:text="春花秋月"android:textSize="25sp"android:textColor="#000000"android:layout_marginTop="2dp"/></RelativeLayout>

7,使用到的pinyin4j-2.5.0.jar包:

Android开发制作带有侧边栏的联系人列表相关推荐

  1. android手机电话号码,Android开发:实现添加系统联系人(手机号码,姓名)

    之前遇到了一些知识没有总结的习惯,今天来回顾一下一个简单的小功能:Android开发中调起系统的联系人列表. 在网上收到了好多这方面的知识,自己在写代码的时候总结了一个最简化的方法,希望可以给大家提供 ...

  2. android列表项点击事件,Android 开发 tips(2):监听 Listview 列表项点击事件

    Android 开发 tips(2):监听 Listview 列表项点击事件 (这篇和上篇本来是应该一起写的,但是太过冗长,附链接:[SimpleAdapter 在 Listview 中的应用] ht ...

  3. Android开发笔记(一百)折叠式列表

    更多动态视图MoreNewsView 经常看朋友圈的动态,有的动态内容较多就只展示前面一段,如果用户想看完整的再点击展开,这样整个页面的动态列表比较均衡,不会出现个别动态占用大片屏幕的情况.同样,查看 ...

  4. Android使用RecyclerView实现仿微信联系人列表

    现在联系人列表基本都是按照字母或者拼音来进行分类,右边有一排字母供用户快速定位到指定的字母位置,效果图如下: OK,输入的联系人类型可能有很多种,比如汉字.英文.数字.特殊符号等等,其中汉字会转化成拼 ...

  5. Android开发丶带有类型的列表功能实现

    标题乍看起来有点不知所云,话不多说,效果图附上 每个大标签分为数个小标签,顶部有个类型title,点击每个小item会触发相应位置的点击事件,欧了,流程走起来~~~ 1.首先当然还是画UI啦,分析界面 ...

  6. ANDROID 开发一个新闻阅读器之新闻列表

    1.          功能描述 这一讲中我们将对如何实现新闻列表做一个详细的介绍,新闻列表会把所有我们从网上获取的新闻的标题显示给用户,用户通过阅读标题,选择自己想要查看的新闻,进入具体的新闻显示页 ...

  7. android su 程序,android 开发 制作自己的su

    所需材料: ①.su.c ②.Android.mk 以上玩意可以从源码中获取,或者从网上下载! 如果是从android源码中提取的su,请自行注释掉权限检查部分哈~~~ /// 1. Ubuntu l ...

  8. android仿微信点击好友,安卓开发仿微信联系人列表-机器人列表视图仿微通道聊天多久最底部滑动...

    楼主你好!根据你的描述,让我给你答案! :新内容加进来,列表视图重新为setSelection后,定位结束后,拉起一个页面放. . 希望你能有所帮助,如果满意,请记得采纳像下拉条为微信好友如何实现 简 ...

  9. Android开发笔记(序)写在前面的目录

    知识点分类 一方面写写自己走过的弯路掉进去的坑,避免以后再犯:另一方面希望通过分享自己的经验教训,与网友互相切磋,从而去芜存菁进一步提升自己的水平.因此博主就想,入门的东西咱就不写了,人不能老停留在入 ...

最新文章

  1. HTML5学习笔记简明版(3):新元素之hgroup,header,footer,address,nav
  2. 下列哪个可以选中矩形文字块_AI制作字母块文字效果
  3. 启明云端分享:产品应用上,怎么选型ESP-12F\ESP-12E\ESP-12S\ESP-07S这四个模块
  4. HDU - 4348 To the moon(主席树区间更新-标记永久化)
  5. Java异常处理原则与技巧总结
  6. 反爬虫机制和破解方法汇总
  7. 解决selenium连接driver报错Message: Can not connect to the Service chromedrive
  8. java语言c语言基础_新手入门选什么:有些人说C语言要比Java更难!你应该怎么办?...
  9. Android-- SharedPreferences数据存储XML文件的方法
  10. CSS样式(三) - div盒子
  11. 单目深度估计--深度学习篇
  12. 7.用户登陆,用户退出,记住用户名和密码
  13. qt绘画事件-设置背景图片
  14. 网站换服务器ip会降权不,频繁更换IP会导致网站降权
  15. [ARCGIS]带黑边的IMG格式影像如何消除黑边?
  16. 25,UC(04) .
  17. python数据可视化学习
  18. public class A implements B{} --java
  19. 一般业务系统的数据字典表结构
  20. 【web搜索】学习笔记-层次汇合聚类HAC算法

热门文章

  1. EXCEL打开文件显示“文件已损坏,无法打开。”
  2. 手把手教你安装 Fedora
  3. 谷歌浏览器翻译英文网页功能消失解决方案
  4. 超低功耗LCD液晶显示驱动芯片(IC)-VKL128-稳定性好,超低工作电流,低休眠电流-技术开发资料
  5. 关于狄利克雷分布的理解
  6. DIT和DIF的基2FFT算法
  7. MySQL面试:为什么用自增列作为主键
  8. 从原先部分得到新字符串
  9. 从哈佛退休!顶尖学者丘成桐全职任教清华
  10. 以太坊区块链浏览器(一)拿来就用主义