关于字母索引问题浅析(利用Pinyin4j工具包)


Pinyin4j的作用:

支持同一汉字有多个发音

还支持拼音的格式化输出,比如第几声之类的

同时支持简体中文、繁体中文转换为拼音

引用步骤:

1. 首先引入pinyin4j-2.5.0.jar的工具包将其放入libs下;

2. 引入工具类StringHelper

作用:获取联系人拼音及首字母

3. 建立联系人布局,其中ListView中的联系人显示样式可以根据不同需求进行更改:

<FrameLayout

        android:layout_width="match_parent"

        android:layout_height="match_parent"

        android:background="#ffffff">

        <ListView  显示联系人样式

            android:id="@+id/listView"

            android:layout_width="match_parent"

           android:layout_height="match_parent">

        </ListView>

        <TextView   点击索引弹出的字母

            android:id="@+id/tv"

            android:layout_width="60dp"

            android:layout_height="60dp"

            android:layout_gravity="center"

            android:gravity="center"

            android:text="A"

           android:textColor="#ffffff"

            android:textSize="30sp"/>

        <LinearLayout   索引列表

            android:id="@+id/layout"

            android:layout_width="wrap_content"

            android:layout_height="match_parent"

            android:layout_gravity="right"

            android:gravity="center_horizontal"

            android:orientation="vertical">

        </LinearLayout>

    </FrameLayout>

4. 在代码中完成:

l  设置联系人实体类

private String image;

private String num;

以下两项属性为必填属性,其他属性可根据需要进行添加

private String name;

privateString pinYinName;

l  在Activity代码中实现:

private Map<String, Integer> selector = newHashMap<String, Integer>();

// 存放含有索引字母的位置

private LinearLayout layoutIndex;//索引列表布局

private ListView listView;//联系人列表

private TextView tv_show;//索引对话框

private ListViewAdapter adapter;//联系人适配器

private String[] indexStr = { " ", "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 List<Person> persons = null;//旧联系人

private List<Person> newPersons = newArrayList<Person>();//根据索引已排序的新联系人

private int height;// 字体高度

l  绘制索引列表

publicvoidonWindowFocusChanged(boolean hasFocus) {

// oncreate里面执行下面的代码没反应,因为oncreate里面得到的getHeight=0

height= layoutIndex.getMeasuredHeight()/indexStr.length;

      getIndexView();//绘制索引 }

public voidgetIndexView() {

LinearLayout.LayoutParams params = new LayoutParams(

                   LayoutParams.WRAP_CONTENT, height);

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

    final TextView tv = new TextView(this);

     tv.setLayoutParams(params);

     tv.setText(indexStr[i]);

     layoutIndex.addView(tv);

layoutIndex.setOnTouchListener(new         OnTouchListener() {

public boolean onTouch(View v,MotionEvent event){

      float y = event.getY();

      int index = (int) (y / height);

      if (index > -1&& index < indexStr.length){// 防止越界

       String key = indexStr[index];

      if (selector.containsKey(key)) {

        int pos = selector.get(key);

        if (listView.getHeaderViewsCount()> 0) {// 防止ListView有标题栏,本例中没有。

listView.setSelectionFromTop(pos + listView.getHeaderViewsCount(),0);

   } else {

listView.setSelectionFromTop(pos,0);// 滑动到第一项}

tv_show.setVisibility(View.VISIBLE);

tv_show.setText(indexStr[index]);}}

switch (event.getAction()) {

case MotionEvent.ACTION_DOWN:

layoutIndex.setBackgroundColor(Color.parseColor("#606060"));

   break;

case MotionEvent.ACTION_MOVE:

   break;

case MotionEvent.ACTION_UP:

layoutIndex.setBackgroundColor(Color.parseColor("#00ffffff"));

   tv_show.setVisibility(View.GONE);

   break;}

return true;}});}}

l  获取数据源persons

l  String[] allNames =sortIndex(persons);

 * 获取排序后的新数据

public String[] sortIndex(List<Person> persons) {    TreeSet<String> set = newTreeSet<String>();

// 获取初始化数据源中的首字母,添加到set

for (Person person :persons) {

set.add(StringHelper.getPinYinHeadChar(person.getName()).substring(0,1));}

// 新数组的长度为原数据加上set的大小

String[]allNameString=new String[persons.size()+ set.size()];

inti = 0;

for(Stringstring:set){allNameString[i]=string;i++;}

String[] pinYinNames = new String[persons.size()];

    for (intj = 0; j < persons.size(); j++) {

persons.get(j).setPinYinName(StringHelper.getPingYin(persons.get(j).getName().toString());

pinYinNames[j]=StringHelper.getPingYin(persons.get(j).getName().toString());  }

   // 将原数据拷贝到新数据中

System.arraycopy(pinYinNames,0,allNameString,set.size(),pinYinNames.length);

   // 自动按照首字母排序

Arrays.sort(allNameString,String.CASE_INSENSITIVE_ORDER);

List<String> allNameList = newArrayList<String>();

for (int k = 0; k <allNameString.length;k++) {      if(!allNameList.contains(allNameString[k])){

      allNameList.add(allNameString[k]);} }

String[] names = (String[])

allNameList.toArray(new String[allNameList

.size()]);

   return names; }

l  sortList(allNames);

  *重新排序获得一个新的List集合

private voidsortList(String[]allNames) {

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

if (allNames[i].length()> 1 || (byte)allNames[i].charAt(0) > 96 && (byte) allNames[i].charAt(0) < 123) {

for (int j = 0; j < persons.size(); j++) {

if(allNames[i].equals(persons.get(j).getPinYinName())){

注意:如果增加了新的属性值需要在此步骤中往新数据源添加,如果不进行添加则不会有数据:

    Personp = newPerson();

    Stringname = persons.get(j).getName();

    p.setName(name);                 p.setImage(persons.get(j).getImage());

    p.setNum(persons.get(j).getNum());

p.setPinYinName(persons.get(j).getPinYinName());

    newPersons.add(p);}}

} else {

    Person p = new Person();

    p.setName(allNames[i]);

    newPersons.add(p);    }}}

l  循环字母表,查找索引

for (int j = 0; j < indexStr.length; j++) {// 循环字母表,找出newPersons中对应字母的位置

   for (int i = 0; i < newPersons.size(); i++) {

   if(newPersons.get(i).getName().equals(indexStr[j]){

              selector.put(indexStr[j], i);}}}

   adapter = new ListViewAdapter(this, newPersons);

   listView.setAdapter(adapter);

l  数据适配adapter

*继承BaseAdapter重写isEnabled方法

publicbooleanisEnabled(int position) {

if (list.get(position).getName().length()== 1)// 如果是字母索引

   return false;// 表示不能点击

   return super.isEnabled(position);}

   *在getView的方法中首先要获取对象的名字,根据名字获取拼音数,如果拼音的首字母是大写字母的话就是索引值,小写字母的话就是姓名。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值