能够汉字排序的view

前言

带有拼音排序的列表仍是比较经常使用到的。好比手机通信录、好友列表等等这些均可以使用这种view来进行展现。具体的效果就像下面的同样。java

1.对数据源进行汉字排序

对汉字的排序咱们可使用集合里面的Collections.sort(List,Comparator)进行排序,固然,这个Comparator咱们须要重写一遍,以知足咱们的须要。具体代码能够参考下面的。android

/**
* 对集合进行中文拼音排序,排序依据是传入的字段名称
* @param <T> 泛型,泛指传入的对象类型
* @param list 集合,即将要排序的集合
* @param file 排序的依据字段
* @return 返回排序好的集合
*/
public static <T> List<T> sortForCn(List<T> list, final String file) {

		try {
			//对集合进行排序
			Collections.sort(list,new Comparator<T>() {
						@Override
						public int compare(T o1,T o2) {
							try {
								// 经过属性获取对象的属性
								Field field = o1.getClass().getDeclaredField(file);
								// 对象的属性的访问权限设置为可访问
								field.setAccessible(true);
								// 获取属性的对应的值
								String value = field.get(o1).toString();


								// 经过属性获取对象的属性
								Field fieldTwo = o2.getClass().getDeclaredField(file);
								// 对象的属性的访问权限设置为可访问
								fieldTwo.setAccessible(true);
								// 获取属性的对应的值
								String valueTwo = fieldTwo.get(o2).toString();
								// TODO Auto-generated method stub
								Comparator<Object> com = Collator.getInstance(java.util.Locale.SIMPLIFIED_CHINESE);
								return com.compare(value, valueTwo);
							}catch(Exception e) {
								System.out.println("排序失败,具体失败缘由为:"+e.getLocalizedMessage());
								return 0;
							}
						}
					}
			);

		} catch (Exception e) {
			System.out.println("排序失败,缘由:"+e.getLocalizedMessage());
			return null;
		}
		return list;
	}
复制代码

上面的排序方法我是放到了一个SortUtils的工具类里面,方便使用。由于在调用时才清楚具体要依据类里面的那个属性值来进行排序,故属性值的获取我直接使用映射的方式来获取了。须要排序时直接传入一个集合和须要排序的属性名称就能够了,放回结果是排序好的集合。git

2.自定义一个view来存放要展现的内容

自定义的view我是直接继承自LinearLayout的,固然,其余的也能够,只是为了后面布局里面调用时方便一点。我先贴除这个类里面的布局文件代码github

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_gravity="center"
    android:gravity="center">

    <androidx.recyclerview.widget.RecyclerView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/content"
        android:layout_weight="1"/>

    <RadioGroup
        android:layout_width="25dp"
        android:layout_height="wrap_content"
        android:id="@+id/tab"
        android:orientation="vertical"
        android:layout_gravity="center"
        android:gravity="center"
        android:layout_alignParentRight="true"
        android:layout_centerVertical="true"
        android:clickable="true">
        <RadioButton
            android:layout_width="match_parent"
            android:layout_height="25dp"
            android:text="A"
            android:button="@null"
            android:layout_gravity="center"
            android:gravity="center"
            android:id="@+id/a"
            android:textColor="@drawable/tab_bg"
            android:checked="true"/>

        <RadioButton
            android:layout_width="match_parent"
            android:layout_height="25dp"
            android:text="B"
            android:button="@null"
            android:layout_gravity="center"
            android:gravity="center"
            android:textColor="@drawable/tab_bg"
            android:id="@+id/b"/>

        <RadioButton
            android:layout_width="match_parent"
            android:layout_height="25dp"
            android:text="C"
            android:button="@null"
            android:textColor="@drawable/tab_bg"
            android:layout_gravity="center"
            android:gravity="center"
            android:id="@+id/c"/>

        <RadioButton
            android:layout_width="match_parent"
            android:layout_height="25dp"
            android:text="D"
            android:button="@null"
            android:textColor="@drawable/tab_bg"
            android:layout_gravity="center"
            android:gravity="center"
            android:id="@+id/d"/>

        <RadioButton
            android:layout_width="match_parent"
            android:layout_height="25dp"
            android:text="E"
            android:button="@null"
            android:textColor="@drawable/tab_bg"
            android:layout_gravity="center"
            android:gravity="center"
            android:id="@+id/e"/>

        <RadioButton
            android:layout_width="match_parent"
            android:layout_height="25dp"
            android:text="F"
            android:button="@null"
            android:layout_gravity="center"
            android:textColor="@drawable/tab_bg"
            android:gravity="center"
            android:id="@+id/f"/>

        <RadioButton
            android:layout_width="match_parent"
            android:layout_height="25dp"
            android:text="G"
            android:button="@null"
            android:textColor="@drawable/tab_bg"
            android:layout_gravity="center"
            android:gravity="center"
            android:id="@+id/g"/>

        <RadioButton
            android:layout_width="match_parent"
            android:layout_height="25dp"
            android:text="H"
            android:button="@null"
            android:layout_gravity="center"
            android:textColor="@drawable/tab_bg"
            android:gravity="center"
            android:id="@+id/h"/>

        <RadioButton
            android:layout_width="match_parent"
            android:layout_height="25dp"
            android:text="I"
            android:button="@null"
            android:layout_gravity="center"
            android:textColor="@drawable/tab_bg"
            android:gravity="center"
            android:id="@+id/i"/>

        <RadioButton
            android:layout_width="match_parent"
            android:layout_height="25dp"
            android:text="J"
            android:button="@null"
            android:layout_gravity="center"
            android:textColor="@drawable/tab_bg"
            android:gravity="center"
            android:id="@+id/j"/>

        <RadioButton
            android:layout_width="match_parent"
            android:layout_height="25dp"
            android:text="K"
            android:button="@null"
            android:layout_gravity="center"
            android:textColor="@drawable/tab_bg"
            android:gravity="center"
            android:id="@+id/k"/>

        <RadioButton
            android:layout_width="match_parent"
            android:layout_height="25dp"
            android:text="L"
            android:button="@null"
            android:layout_gravity="center"
            android:textColor="@drawable/tab_bg"
            android:gravity="center"
            android:id="@+id/l"/>

        <RadioButton
            android:layout_width="match_parent"
            android:layout_height="25dp"
            android:text="M"
            android:button="@null"
            android:layout_gravity="center"
            android:textColor="@drawable/tab_bg"
            android:gravity="center"
            android:id="@+id/m"/>

        <RadioButton
            android:layout_width="match_parent"
            android:layout_height="25dp"
            android:text="N"
            android:button="@null"
            android:textColor="@drawable/tab_bg"
            android:layout_gravity="center"
            android:gravity="center"
            android:id="@+id/n"/>

        <RadioButton
            android:layout_width="match_parent"
            android:layout_height="25dp"
            android:text="O"
            android:button="@null"
            android:layout_gravity="center"
            android:textColor="@drawable/tab_bg"
            android:gravity="center"
            android:id="@+id/o"/>

        <RadioButton
            android:layout_width="match_parent"
            android:layout_height="25dp"
            android:text="P"
            android:textColor="@drawable/tab_bg"
            android:button="@null"
            android:layout_gravity="center"
            android:gravity="center"
            android:id="@+id/p"/>

        <RadioButton
            android:layout_width="match_parent"
            android:layout_height="25dp"
            android:text="Q"
            android:textColor="@drawable/tab_bg"
            android:button="@null"
            android:layout_gravity="center"
            android:gravity="center"
            android:id="@+id/q"/>

        <RadioButton
            android:layout_width="match_parent"
            android:layout_height="25dp"
            android:text="R"
            android:button="@null"
            android:layout_gravity="center"
            android:textColor="@drawable/tab_bg"
            android:gravity="center"
            android:id="@+id/r"/>

        <RadioButton
            android:layout_width="match_parent"
            android:layout_height="25dp"
            android:text="S"
            android:button="@null"
            android:textColor="@drawable/tab_bg"
            android:layout_gravity="center"
            android:gravity="center"
            android:id="@+id/s"/>

        <RadioButton
            android:layout_width="match_parent"
            android:layout_height="25dp"
            android:text="T"
            android:button="@null"
            android:layout_gravity="center"
            android:textColor="@drawable/tab_bg"
            android:gravity="center"
            android:id="@+id/t"/>

        <RadioButton
            android:layout_width="match_parent"
            android:layout_height="25dp"
            android:text="U"
            android:textColor="@drawable/tab_bg"
            android:button="@null"
            android:layout_gravity="center"
            android:gravity="center"
            android:id="@+id/u"/>

        <RadioButton
            android:layout_width="match_parent"
            android:layout_height="25dp"
            android:text="V"
            android:textColor="@drawable/tab_bg"
            android:button="@null"
            android:layout_gravity="center"
            android:gravity="center"
            android:id="@+id/v"/>

        <RadioButton
            android:layout_width="match_parent"
            android:layout_height="25dp"
            android:text="W"
            android:textColor="@drawable/tab_bg"
            android:button="@null"
            android:layout_gravity="center"
            android:gravity="center"
            android:id="@+id/w"/>

        <RadioButton
            android:layout_width="match_parent"
            android:layout_height="25dp"
            android:text="Z"
            android:button="@null"
            android:textColor="@drawable/tab_bg"
            android:layout_gravity="center"
            android:gravity="center"
            android:id="@+id/z"/>
    </RadioGroup>

    <TextView
        android:layout_width="80dp"
        android:layout_height="80dp"
        android:layout_centerInParent="true"
        tools:text="G"
        android:visibility="gone"
        android:gravity="center"
        android:background="@drawable/alert_bg"
        android:textSize="30dp"
        android:id="@+id/alert"/>
</RelativeLayout>
复制代码

这个布局文件里面主体包含三部分,分别是数据列表,侧导航栏和点击导航栏时出现的提示,里面并无什么好介绍的,都是一看就懂的。让后咱们在自定义view的构造方法里面加入 LayoutInflater.from(context).inflate(R.layout.custom_recyclerview_classify,this,true);
这行代码就能够正常显示了bash

3.设置recyclerview和radioGroup的监听器

recyclerview的监听器主要目的是在活动时改变radioGroup的选中状态,radioGroup的监听器主要目的是在点击时,时recyclerview跳转到指定的位置。在写监听器以前,咱们须要引入一个依赖: implementation 'com.github.open-android:pinyin4j:2.5.0',在项目的gradle文件中加入maven { url "https://jitpack.io" }。咱们使用这个的目的主要时获取须要排序字段的汉字的首字母。利用这个首字母,咱们能够很精确的改变radioGroup下的radioButton的状态。recyclerview滑动监听代码以下:maven

final HanyuPinyinOutputFormat format = new HanyuPinyinOutputFormat();
 format.setCaseType(HanyuPinyinCaseType.UPPERCASE);
 rec.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
                super.onScrollStateChanged(recyclerView, newState);
                //若是recyclerview中止滑动状态,容许点击tab栏
                if (newState == 0){
                    isRecMove = false;
                }else {
                    isRecMove = true;
                }
            }

            @Override
            public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);
                //滑动时获取屏幕第一条可见数据,并获取到此数据的行字首字母
                int position = llm.findFirstVisibleItemPosition();
                try{
                    //获取汉字首字母
                    String[] args = PinyinHelper.toHanyuPinyinStringArray(testBeams.get(position).getName().charAt(0), format);
                    //indexMap.get(String.valueOf(args[0].charAt(0)))为获取此条数据的汉字首字母在tab中的位置。
                    RadioButton radioButton = ((RadioButton)(tab.getChildAt(indexMap.get(String.valueOf(args[0].charAt(0))))));
                    radioButton.setChecked(true);
                }catch (Exception e){
                    Log.e("日志","错误");
                }

            }
        });
复制代码

上面的indexMap是一个hashmap,存放的是侧栏字母的位置。存放内容是indexMap.put("A",0);这样的,一直put到24,就不贴出代码了。上面的代码中有注释,因该也好理解,**就是获取首条屏幕上出现的数据,从中获取数据中汉字的首字母,拿这个首字母到indexmap中获取到radiobutton在radiogroup中的位置,获取到位置后就能够直接改变状态了。**而后就到点击radiobutton时改变recyclerview位置的代码了,这部分代码都集中在radiogroup的监听器中。代码以下:ide

tab.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(RadioGroup radioGroup, int i) {
                try{
                    //若是是由于滑动recyclerview触发的,无需作任何处理,这里只处理右边tab点击时触发的事件
                    if (!isRecMove){
                        //获取点击位置的字母
                        String pinyin = ((RadioButton)(radioGroup.findViewById(radioGroup.getCheckedRadioButtonId()))).getText().toString();
                        if (recAdapter.getIndexMap().get(pinyin) != null){
                            int index = recAdapter.getIndexMap().get(pinyin);
                            //让recyclerview活动到对应的位置。recAdapter.getIndexMap().get(pinyin)是获取数据集合中第一条出现该字母数据的索引。
                            llm.scrollToPositionWithOffset(index,0);
                            llm.setStackFromEnd(true);
                        }
                        showOrHideAlert(pinyin);
                    }
                }catch (Exception e){
                    Log.e("日志","出现错误:"+e.getLocalizedMessage());
                }
            }
        });
复制代码

上面须要注意的时,若是直接使用recyclerview的scrollToPosition(position)这个方法并很差,因此换成了llm.scrollToPositionWithOffset(position,0)这个方法。recAdapter时recyclerview的adapter。实现原理是:点击radiobutton时,获取到按钮上的字母,经过字母到recAdapter里面的一个hashmap获取出现该字母的第一条数据的位置,而后让recyclerview跳转到此位置便可。showOrHideAlert(pinyin)这个方法主要是显示点击后的提示,代码不贴出了,后面能够到码云上去看。工具

4.recyclerview的adapter的编写

这个adapter编写起来和平时同样,只是在设置数据时多设置了一个hashmap,这个map记录的是集合中相同字母出现的第一条记录,主要用户方便获取跳转地点用的。代码以下:布局

public void setList(List<TestBeam> testBeams){
        this.testBeams = testBeams;
        final HanyuPinyinOutputFormat format = new HanyuPinyinOutputFormat();
        format.setCaseType(HanyuPinyinCaseType.UPPERCASE);
        for (int i=0;i<testBeams.size();i++){
            try{
                String[] args = PinyinHelper.toHanyuPinyinStringArray(testBeams.get(i).getName().charAt(0), format);
                //获取文字的第一个拼音
                String pinyin = String.valueOf(args[0].charAt(0));
                //保存第一条字母的索引位置,目的是后面能够快速跳转到对应的位置
                if (indexMap.get(pinyin) == null){
                    indexMap.put(pinyin,i);
                }else {
                    continue;
                }
            }catch (Exception e){
                Log.e("日志","在第"+i+"个字符时转换失败,缘由:"+e.getLocalizedMessage());
            }
        }
        notifyDataSetChanged();
    }
复制代码

从代码不难看出,主要是遍历集合,保存第一个相同字母出现的位置而已。gradle

总结

到这里一个能够实现汉字排序的view就制做完成了 码云地址

相关文章
相关标签/搜索