能夠漢字排序的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就製做完成了 碼雲地址

相關文章
相關標籤/搜索