美文网首页
android recycleView自定义字母检索A-Z排序滑

android recycleView自定义字母检索A-Z排序滑

作者: SmallWalnutBG | 来源:发表于2020-11-26 16:57 被阅读0次

    image
    核心类:
    package com.example.test29api.slider_contact
    
    import android.content.Context
    import android.graphics.Canvas
    import android.graphics.Color
    import android.graphics.Paint
    import android.graphics.Rect
    import android.graphics.drawable.Drawable
    import android.text.TextPaint
    import android.text.TextUtils
    import android.util.ArrayMap
    import android.util.AttributeSet
    import android.util.TypedValue
    import android.view.MotionEvent
    import android.view.View
    import androidx.annotation.VisibleForTesting
    import com.example.test29api.R
    import java.util.*
    import java.util.Collections.sort as sort1
    
    class NewSideBar @JvmOverloads constructor(
        context: Context,
        attrs: AttributeSet? = null,
        defStyleAttr: Int = 0
    ) : View(context, attrs, defStyleAttr) {
        var indexes: Array<String?> = arrayOf(
            "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 val normalTextColor //未选中字体颜色
                : Int
        private val selectedTextColor //选中字体颜色
                : Int
        private val selectedBackground //选中背景色
                : Drawable?
        private var selectedIndex = 0
        private val indexPaint: TextPaint
        private val indexBounds //索引大小
                : Rect
        private val backGroundBound //背景绘制区域
                : Rect
        private var listener: OnSelectIndexChangedListener? = null
        override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
            val widthMode = MeasureSpec.getMode(widthMeasureSpec)
            val heightMode = MeasureSpec.getMode(heightMeasureSpec)
            val sizeWidth = MeasureSpec.getSize(widthMeasureSpec)
            val sizeHeight = MeasureSpec.getSize(heightMeasureSpec)
            val wrapHeight =
                indexes.size * (indexBounds.height() + indexBounds.height() / 2) + indexBounds.height() / 2
            val warpWidth = indexBounds.width() * 2
            setMeasuredDimension(
                if (widthMode == MeasureSpec.EXACTLY) sizeWidth else warpWidth
                , if (heightMode == MeasureSpec.EXACTLY) sizeHeight else wrapHeight
            )
        }
    
        override fun onDraw(canvas: Canvas) {
            indexBounds.offsetTo(indexBounds.width() / 2, indexBounds.height() / 2)
            backGroundBound.offsetTo(indexBounds.width() / 4, indexBounds.height() / 4)
            for (i in indexes.indices) {
                if (selectedIndex == i) { //绘制index背景
                    if (selectedBackground != null) {
                        selectedBackground.bounds = backGroundBound
                        selectedBackground.draw(canvas)
                    }
                    indexPaint.color = selectedTextColor
                } else {
                    indexPaint.color = normalTextColor
                }
                indexes[i]?.let {
                    canvas.drawText(
                        it,
                        indexBounds.left + indexBounds.width() / 2.toFloat(),
                        indexBounds.top + baseLineOffset.toFloat(),
                        indexPaint
                    )
                }
                indexBounds.offset(0, 3 * indexBounds.height() / 2)
                backGroundBound.offset(0, 3 * indexBounds.height() / 2)
            }
        }
    
        override fun dispatchTouchEvent(event: MotionEvent): Boolean {
            var selectedIndex = getSelectedIndex(event.y)
            if (selectedIndex < 0) {
                selectedIndex = 0
            }
            if (selectedIndex >= indexes.size) {
                selectedIndex = indexes.size - 1
            }
            when (event.action) {
                MotionEvent.ACTION_DOWN -> {
                    isHovered = true
                    if (listener != null && selectedIndex != -1 && selectedIndex != this.selectedIndex) {
                        this.selectedIndex = selectedIndex
                        listener!!.onIndexHovered(indexes[selectedIndex])
                    }
                    invalidate()
                }
                MotionEvent.ACTION_MOVE -> {
                    if (listener != null && selectedIndex != -1 && selectedIndex != this.selectedIndex) {
                        this.selectedIndex = selectedIndex
                        listener!!.onIndexHovered(indexes[selectedIndex])
                    }
                    invalidate()
                }
                MotionEvent.ACTION_UP -> {
                    isHovered = false
                    if (listener != null && selectedIndex >= 0 && selectedIndex < indexes.size) {
                        this.selectedIndex = selectedIndex
                        listener!!.onIndexSelected(indexes[selectedIndex])
                    }
                }
            }
            return true
        }
    
        private fun getSelectedIndex(pointY: Float): Int {
            return ((pointY - indexBounds.height() / 4) / (indexBounds.height() * 3 / 2)).toInt()
        }
    
        private val baseLineOffset: Int
            get() {
                val fontMetrics = indexPaint.fontMetricsInt
                val dy = (fontMetrics.bottom - fontMetrics.top) / 2 - fontMetrics.bottom
                return indexBounds.height() / 2 + dy
            }
    
        fun setListener(listener: OnSelectIndexChangedListener?) {
            this.listener = listener
        }
    
        fun setSections(sections: Array<String?>) {
            indexes = sections
            requestLayout()
        }
    
        fun setSelectedIndex(selectedIndex: String?) {
            if (isHovered) {
                return
            }
            for (i in indexes.indices) {
                val index = indexes[i]
                if (TextUtils.equals(selectedIndex, index)) {
                    this.selectedIndex = i
                    invalidate()
                    break
                }
            }
        }
    
        @VisibleForTesting
        fun getSelectedIndex(): String? {
            return if (selectedIndex >= 0 && selectedIndex < indexes.size) indexes[selectedIndex] else null
        }
    
        interface OnSelectIndexChangedListener {
            fun onIndexHovered(index: String?)
            fun onIndexSelected(index: String?)
        }
    
        interface SectionIndexer<T> {
            val sections: Array<T>
            fun getPositionForSection(section: T): Int
            fun getSectionForPosition(position: Int): T
        }
    
        class PinyinSectionIndexer :
            SectionIndexer<String?> {
            private var indexables: MutableList<Indexable<String>>? = null
            private var mapSections: ArrayMap<Indexable<String>, String>? = null
            private var skipCount = 0
            fun <T : Indexable<String>> handleIndexableList(indexableList: MutableList<T>): List<T> {
                return handleIndexableList(indexableList, 0)
            }
    
            /**
             * @param indexableList 数据源
             * @param skipCount 1-置顶第一个item不参与abc...排序
             * 0-全部参与abc...排序
             */
            fun <T : Indexable<String>> handleIndexableList(
                indexableList: MutableList<T>,
                skipCount: Int
            ): List<T> {
                if (mapSections == null) {
                    mapSections = ArrayMap()
                }
                mapSections!!.clear()
                if (indexables == null) {
                    indexables = ArrayList()
                }
                indexables!!.clear()
                this.skipCount = skipCount
                if (indexableList.size == 0 || indexableList.size < skipCount) {
                    return indexableList
                }
                val sortList: List<T> =
                    ArrayList(indexableList.subList(skipCount, indexableList.size)).also {
                        //通过拼音首字母排序
                        it.sortWith(Comparator { o1, o2 ->
                            var index1 = getSection(o1)
                            if (TextUtils.equals(index1, "#")) {
                                index1 = "a"
                            }
                            var index2 = getSection(o2)
                            if (TextUtils.equals(index2, "#")) {
                                index2 = "a"
                            }
                            index1!!.compareTo(index2!!)
                        })
                    }
                indexables!!.addAll(sortList)
                val dest: MutableList<T> = indexableList.subList(0, skipCount)
                dest.addAll(sortList)
                return dest
    
            }
    
            /**
             * @return 返回数据源所有拼音首字母String[]集合
             */
    
            override
            val sections: Array<String?>
                get() {
                    val sections =
                        ArrayList<String?>()
                    var i = 0
                    val len = indexables!!.size
                    while (i < len) {
                        val section = getSection(indexables!![i])
                        if (!sections.contains(section)) {
                            sections.add(section)
                        }
                        i++
                    }
                    return sections.toTypedArray()
                }
    
            /**
             * @return 返回首字母对应数据的第一个position
             */
            override fun getPositionForSection(section: String?): Int {
                var i = 0
                val len = indexables!!.size
                while (i < len) {
                    if (TextUtils.equals(section, getSection(indexables!![i]))) {
                        return i + skipCount
                    }
                    i++
                }
                return -1
            }
    
            /**
             * @return 通过数据的position返回首字母
             */
            override fun getSectionForPosition(position: Int): String? {
                return if (indexables != null && position >= 0 && position < indexables!!.size) {
                    getSection(indexables!![Math.max(position - skipCount, 0)])
                } else {
                    ""
                }
            }
    
            /**
             * @return 获取indexable.getIndexable()的拼音大写首字母(空则返回#),同时更新#sections
             */
            fun getSection(indexable: Indexable<String>): String? {
                var section = mapSections!![indexable]
                if (TextUtils.isEmpty(section)) {
                    val indexableString = indexable.indexable
                    val instance = CharacterParser.instance
                    if (TextUtils.isEmpty(indexableString)) {
                        section = "#"
                    } else { //获取首字的拼音
                        val c = instance.convert(indexableString.substring(0, 1))
                        //首字母转大写
                        section =
                            if (TextUtils.isEmpty(c)) "0" else c?.substring(0, 1)?.toUpperCase(
                                Locale.ROOT
                            )
                        if (!section.isNullOrEmpty() && (section[0] < 'A' || section[0] > 'Z')) {
                            section = "#"
                        }
                    }
                    mapSections!![indexable] = section
                }
                return section
            }
        }
    
        interface Indexable<T> {
            val indexable: T
        }
    
        init {
            val ta = context.obtainStyledAttributes(attrs, R.styleable.NewSideBar)
            normalTextColor =
                ta.getColor(R.styleable.NewSideBar_normalTextColor, Color.GRAY)
            selectedTextColor =
                ta.getColor(R.styleable.NewSideBar_selectedTextColor, Color.BLACK)
            selectedBackground = ta.getDrawable(R.styleable.NewSideBar_selectedBackground)
            val textSize = ta.getDimension(
                R.styleable.NewSideBar_indexTextSize, TypedValue
                    .applyDimension(
                        TypedValue.COMPLEX_UNIT_SP, 12f,
                        resources.displayMetrics
                    )
            )
            ta.recycle()
            indexBounds = Rect()
            indexPaint = TextPaint(Paint.ANTI_ALIAS_FLAG)
            indexPaint.textSize = textSize
            indexPaint.textAlign = Paint.Align.CENTER
            indexPaint.getTextBounds("W", 0, 1, indexBounds)
            val larger = Math.max(indexBounds.width(), indexBounds.height())
            indexBounds[0, 0, larger] = larger
            backGroundBound = Rect(
                0,
                0,
                indexBounds.right + indexBounds.right / 2,
                indexBounds.bottom + indexBounds.bottom / 2
            )
        }
    }
    

    attrs:

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
        <declare-styleable name="NewSideBar">
            <attr name="normalTextColor" format="color" />
            <attr name="selectedTextColor" format="color" />
            <attr name="selectedBackground" format="reference" />
            <attr name="indexTextSize" format="dimension" />
        </declare-styleable>
    </resources>
    

    以上类基本逻辑为:通过传入数据绘制字母及其背景,再通过接口和recycleView联动;

    调用方式:

    activity:

    import android.os.Bundle
    import android.util.Log
    import android.view.View
    import android.view.ViewGroup
    import androidx.appcompat.app.AppCompatActivity
    import androidx.recyclerview.widget.LinearLayoutManager
    import androidx.recyclerview.widget.RecyclerView
    import androidx.recyclerview.widget.RecyclerView.Adapter
    import com.example.test29api.R
    import kotlinx.android.extensions.LayoutContainer
    import kotlinx.android.synthetic.main.activity_contact_slider.*
    import kotlinx.android.synthetic.main.item_base.view.*
    import kotlinx.coroutines.*
    
    class ContactSliderActivity : AppCompatActivity() {
        private val indexer by lazy {
            NewSideBar.PinyinSectionIndexer()
        }
        private val testContactBeans by lazy {
            mutableListOf(
                TestContactBean("张三", "18888888888"),
                TestContactBean("李四", "19999999999"),
                TestContactBean("王五", "13333333333"),
                TestContactBean("科比", "13444444444"),
                TestContactBean("布鲁斯", "18213333333"),
                TestContactBean("朱厚照", "18888888888"),
                TestContactBean("朱祐樘", "17777777777"),
                TestContactBean("朱高炽", "18888888888"),
                TestContactBean("唐寅", "18888888855"),
                TestContactBean("朱厚聪", "18888888866"),
                TestContactBean("朱载厚", "18888888877"),
                TestContactBean("刘瑾", "18215333333"),
                TestContactBean("Alibaba", "15775757575"),
                TestContactBean("Bruce", "15775757575"),
                TestContactBean("富兰克林", "18215333333")
            )
        }
    
        open class DefaultViewHolder(override val containerView: View) :
            RecyclerView.ViewHolder(containerView), LayoutContainer
    
    
        private val defaultAdapter by lazy {
            object : Adapter<DefaultViewHolder>() {
                override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): DefaultViewHolder {
                    return DefaultViewHolder(
                        layoutInflater.inflate(
                            R.layout.item_base,
                            parent,
                            false
                        )
                    )
                }
    
                override fun getItemCount(): Int {
                    return testContactBeans.size
                }
    
                override fun onBindViewHolder(holder: DefaultViewHolder, position: Int) {
                    holder.itemView.run {
                        txtName.text = testContactBeans[position].name
                        txtPhone.text = testContactBeans[position].phone
                    }
                }
            }
        }
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_contact_slider)
            initView()
        }
    
        private fun initView() {
            recyclerView.apply {
                layoutManager = LinearLayoutManager(this@ContactSliderActivity)
                adapter = defaultAdapter
                addOnScrollListener(object : RecyclerView.OnScrollListener() {
                    override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
                        val position =
                            (recyclerView.layoutManager as LinearLayoutManager).findFirstVisibleItemPosition()
                        if (defaultAdapter.itemCount != 0 && position in 0 until testContactBeans.size) {
                            sideBar.setSelectedIndex(indexer.getSectionForPosition(position))
                        }
                    }
                })
            }
    
            sideBar.apply {
                visibility = View.GONE
                setListener(object : NewSideBar.OnSelectIndexChangedListener {
                    override fun onIndexHovered(index: String?) {
                        (recyclerView.layoutManager as LinearLayoutManager).scrollToPositionWithOffset(
                            indexer.getPositionForSection(index),
                            0
                        )
                    }
    
                    override fun onIndexSelected(index: String?) {
                        val manager = recyclerView.layoutManager as LinearLayoutManager
                        if (manager.findLastVisibleItemPosition() == (recyclerView.adapter?.itemCount
                                ?: 0) - 1
                        ) {
                            sideBar.setSelectedIndex(indexer.getSectionForPosition(manager.findFirstVisibleItemPosition()))
                        }
                    }
                })
            }
    
            //设置排序后的数据源
            val mutableListOf = mutableListOf<TestContactBean>()
            mutableListOf.addAll(testContactBeans)
    
            indexer.handleIndexableList(mutableListOf, 0).let { list ->
                defaultAdapter.notifyItemRangeRemoved(0, testContactBeans.size - 1)
                testContactBeans.clear()
                testContactBeans.addAll(list)
                defaultAdapter.notifyItemRangeChanged(0, testContactBeans.size - 1)
            }
    
    
            sideBar.setSections(indexer.sections)
            sideBar.visibility = View.VISIBLE
        }
       
    }
    

    activity_contact_slider:

    <?xml version="1.0" encoding="utf-8"?>
    <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        xmlns:app="http://schemas.android.com/apk/res-auto">
    
        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/recyclerView"
            android:layout_width="0dp"
            android:layout_height="0dp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
             />
    
    
        <com.example.test29api.slider_contact.NewSideBar
            android:id="@+id/sideBar"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginEnd="8dp"
            app:indexTextSize="12sp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:normalTextColor="@android:color/darker_gray"
            app:selectedBackground="@drawable/side_bar_choose_background"
            app:selectedTextColor="@android:color/white" />
    
    </androidx.constraintlayout.widget.ConstraintLayout>
    

    side_bar_choose_background:

    <?xml version="1.0" encoding="utf-8"?>
    <shape xmlns:android="http://schemas.android.com/apk/res/android"
        android:shape="oval">
        <solid android:color="@color/colorPrimary"/>
    </shape>
    

    item_base:

    <?xml version="1.0" encoding="utf-8"?>
    <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="70dp"
        android:background="@android:color/white"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools">
        <TextView
            android:id="@+id/txtName"
            android:layout_width="0dp"
            android:layout_height="48dp"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintEnd_toStartOf="@id/txtPhone"
            app:layout_constraintVertical_chainStyle="packed"
            android:layout_marginStart="16dp"
            android:layout_marginEnd="14dp"
            android:textSize="16sp"
            tools:text="项目成员"
            android:gravity="center_vertical"
            android:singleLine="true"/>
    
        <TextView
            android:id="@+id/txtPhone"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            app:layout_constraintStart_toEndOf="@id/txtName"
            app:layout_constraintBottom_toBottomOf="@id/txtName"
            app:layout_constraintTop_toTopOf="@id/txtName"
            app:layout_constraintEnd_toEndOf="parent"
            android:layout_marginStart="16dp"
            android:layout_marginTop="8dp"
            android:layout_marginEnd="14dp"
            tools:text="1888888888"
            android:singleLine="true"/>
    
    </androidx.constraintlayout.widget.ConstraintLayout>
    

    CharacterParser

    package com.example.test29api.slider_contact
    
    /**
     * Created by PengCangXu on 2017/5/7.
     */
    class CharacterParser {
        private var buffer: StringBuilder? = null
        var resource: String? = null
    
        /**
         * 汉字转成ASCII码 * * @param chs * @return
         */
        private fun getChsAscii(chs: String): Int {
            var asc = 0
            try {
                val bytes = chs.toByteArray(charset("gb2312"))
                if (bytes.size > 2 || bytes.size <= 0) {
                    throw RuntimeException("illegal resource string")
                }
                if (bytes.size == 1) {
                    asc = bytes[0].toInt()
                }
                if (bytes.size == 2) {
                    val hightByte = 256 + bytes[0]
                    val lowByte = 256 + bytes[1]
                    asc = 256 * hightByte + lowByte - 256 * 256
                }
            } catch (e: Exception) {
                println("ERROR:ChineseSpelling.class-getChsAscii(String chs)$e")
            }
            return asc
        }
    
        /**
         * 单字解析 * * @param str * @return
         */
        fun convert(str: String): String? {
            var result: String? = null
            val ascii = getChsAscii(str)
            if (ascii in 1..159) {
                result = ascii.toString()
            } else {
                for (i in pyvalue.size - 1 downTo 0) {
                    if (pyvalue[i] <= ascii) {
                        result = pystr[i]
                        break
                    }
                }
            }
            return result
        }
    
        /***词组解析 * * @param chs * @return  */
        fun parse(chs: String?): String {
            var key: String
            var value: String?
            buffer = StringBuilder()
            for (i in chs!!.indices) {
                key = chs.substring(i, i + 1)
                if (key.toByteArray().size >= 2) {
                    value = convert(key)
                    if (value == null) {
                        value = "unknown"
                    }
                } else {
                    value = key
                }
                buffer!!.append(value)
            }
            return buffer.toString()
        }
    
        val spelling: String
            get() = parse(resource)
    
        companion object {
            private val pyvalue = intArrayOf(
                -20319,
                -20317,
                -20304,
                -20295,
                -20292,
                -20283,
                -20265,
                -20257,
                -20242,
                -20230,
                -20051,
                -20036,
                -20032,
                -20026,
                -20002,
                -19990,
                -19986,
                -19982,
                -19976,
                -19805,
                -19784,
                -19775,
                -19774,
                -19763,
                -19756,
                -19751,
                -19746,
                -19741,
                -19739,
                -19728,
                -19725,
                -19715,
                -19540,
                -19531,
                -19525,
                -19515,
                -19500,
                -19484,
                -19479,
                -19467,
                -19289,
                -19288,
                -19281,
                -19275,
                -19270,
                -19263,
                -19261,
                -19249,
                -19243,
                -19242,
                -19238,
                -19235,
                -19227,
                -19224,
                -19218,
                -19212,
                -19038,
                -19023,
                -19018,
                -19006,
                -19003,
                -18996,
                -18977,
                -18961,
                -18952,
                -18783,
                -18774,
                -18773,
                -18763,
                -18756,
                -18741,
                -18735,
                -18731,
                -18722,
                -18710,
                -18697,
                -18696,
                -18526,
                -18518,
                -18501,
                -18490,
                -18478,
                -18463,
                -18448,
                -18447,
                -18446,
                -18239,
                -18237,
                -18231,
                -18220,
                -18211,
                -18201,
                -18184,
                -18183,
                -18181,
                -18012,
                -17997,
                -17988,
                -17970,
                -17964,
                -17961,
                -17950,
                -17947,
                -17931,
                -17928,
                -17922,
                -17759,
                -17752,
                -17733,
                -17730,
                -17721,
                -17703,
                -17701,
                -17697,
                -17692,
                -17683,
                -17676,
                -17496,
                -17487,
                -17482,
                -17468,
                -17454,
                -17433,
                -17427,
                -17417,
                -17202,
                -17185,
                -16983,
                -16970,
                -16942,
                -16915,
                -16733,
                -16708,
                -16706,
                -16689,
                -16664,
                -16657,
                -16647,
                -16474,
                -16470,
                -16465,
                -16459,
                -16452,
                -16448,
                -16433,
                -16429,
                -16427,
                -16423,
                -16419,
                -16412,
                -16407,
                -16403,
                -16401,
                -16393,
                -16220,
                -16216,
                -16212,
                -16205,
                -16202,
                -16187,
                -16180,
                -16171,
                -16169,
                -16158,
                -16155,
                -15959,
                -15958,
                -15944,
                -15933,
                -15920,
                -15915,
                -15903,
                -15889,
                -15878,
                -15707,
                -15701,
                -15681,
                -15667,
                -15661,
                -15659,
                -15652,
                -15640,
                -15631,
                -15625,
                -15454,
                -15448,
                -15436,
                -15435,
                -15419,
                -15416,
                -15408,
                -15394,
                -15385,
                -15377,
                -15375,
                -15369,
                -15363,
                -15362,
                -15183,
                -15180,
                -15165,
                -15158,
                -15153,
                -15150,
                -15149,
                -15144,
                -15143,
                -15141,
                -15140,
                -15139,
                -15128,
                -15121,
                -15119,
                -15117,
                -15110,
                -15109,
                -14941,
                -14937,
                -14933,
                -14930,
                -14929,
                -14928,
                -14926,
                -14922,
                -14921,
                -14914,
                -14908,
                -14902,
                -14894,
                -14889,
                -14882,
                -14873,
                -14871,
                -14857,
                -14678,
                -14674,
                -14670,
                -14668,
                -14663,
                -14654,
                -14645,
                -14630,
                -14594,
                -14429,
                -14407,
                -14399,
                -14384,
                -14379,
                -14368,
                -14355,
                -14353,
                -14345,
                -14170,
                -14159,
                -14151,
                -14149,
                -14145,
                -14140,
                -14137,
                -14135,
                -14125,
                -14123,
                -14122,
                -14112,
                -14109,
                -14099,
                -14097,
                -14094,
                -14092,
                -14090,
                -14087,
                -14083,
                -13917,
                -13914,
                -13910,
                -13907,
                -13906,
                -13905,
                -13896,
                -13894,
                -13878,
                -13870,
                -13859,
                -13847,
                -13831,
                -13658,
                -13611,
                -13601,
                -13406,
                -13404,
                -13400,
                -13398,
                -13395,
                -13391,
                -13387,
                -13383,
                -13367,
                -13359,
                -13356,
                -13343,
                -13340,
                -13329,
                -13326,
                -13318,
                -13147,
                -13138,
                -13120,
                -13107,
                -13096,
                -13095,
                -13091,
                -13076,
                -13068,
                -13063,
                -13060,
                -12888,
                -12875,
                -12871,
                -12860,
                -12858,
                -12852,
                -12849,
                -12838,
                -12831,
                -12829,
                -12812,
                -12802,
                -12607,
                -12597,
                -12594,
                -12585,
                -12556,
                -12359,
                -12346,
                -12320,
                -12300,
                -12120,
                -12099,
                -12089,
                -12074,
                -12067,
                -12058,
                -12039,
                -11867,
                -11861,
                -11847,
                -11831,
                -11798,
                -11781,
                -11604,
                -11589,
                -11536,
                -11358,
                -11340,
                -11339,
                -11324,
                -11303,
                -11097,
                -11077,
                -11067,
                -11055,
                -11052,
                -11045,
                -11041,
                -11038,
                -11024,
                -11020,
                -11019,
                -11018,
                -11014,
                -10838,
                -10832,
                -10815,
                -10800,
                -10790,
                -10780,
                -10764,
                -10587,
                -10544,
                -10533,
                -10519,
                -10331,
                -10329,
                -10328,
                -10322,
                -10315,
                -10309,
                -10307,
                -10296,
                -10281,
                -10274,
                -10270,
                -10262,
                -10260,
                -10256,
                -10254
            )
            var pystr = arrayOf(
                "a",
                "ai",
                "an",
                "ang",
                "ao",
                "ba",
                "bai",
                "ban",
                "bang",
                "bao",
                "bei",
                "ben",
                "beng",
                "bi",
                "bian",
                "biao",
                "bie",
                "bin",
                "bing",
                "bo",
                "bu",
                "ca",
                "cai",
                "can",
                "cang",
                "cao",
                "ce",
                "ceng",
                "cha",
                "chai",
                "chan",
                "chang",
                "chao",
                "che",
                "chen",
                "cheng",
                "chi",
                "chong",
                "chou",
                "chu",
                "chuai",
                "chuan",
                "chuang",
                "chui",
                "chun",
                "chuo",
                "ci",
                "cong",
                "cou",
                "cu",
                "cuan",
                "cui",
                "cun",
                "cuo",
                "da",
                "dai",
                "dan",
                "dang",
                "dao",
                "de",
                "deng",
                "di",
                "dian",
                "diao",
                "die",
                "ding",
                "diu",
                "dong",
                "dou",
                "du",
                "duan",
                "dui",
                "dun",
                "duo",
                "e",
                "en",
                "er",
                "fa",
                "fan",
                "fang",
                "fei",
                "fen",
                "feng",
                "fo",
                "fou",
                "fu",
                "ga",
                "gai",
                "gan",
                "gang",
                "gao",
                "ge",
                "gei",
                "gen",
                "geng",
                "gong",
                "gou",
                "gu",
                "gua",
                "guai",
                "guan",
                "guang",
                "gui",
                "gun",
                "guo",
                "ha",
                "hai",
                "han",
                "hang",
                "hao",
                "he",
                "hei",
                "hen",
                "heng",
                "hong",
                "hou",
                "hu",
                "hua",
                "huai",
                "huan",
                "huang",
                "hui",
                "hun",
                "huo",
                "ji",
                "jia",
                "jian",
                "jiang",
                "jiao",
                "jie",
                "jin",
                "jing",
                "jiong",
                "jiu",
                "ju",
                "juan",
                "jue",
                "jun",
                "ka",
                "kai",
                "kan",
                "kang",
                "kao",
                "ke",
                "ken",
                "keng",
                "kong",
                "kou",
                "ku",
                "kua",
                "kuai",
                "kuan",
                "kuang",
                "kui",
                "kun",
                "kuo",
                "la",
                "lai",
                "lan",
                "lang",
                "lao",
                "le",
                "lei",
                "leng",
                "li",
                "lia",
                "lian",
                "liang",
                "liao",
                "lie",
                "lin",
                "ling",
                "liu",
                "long",
                "lou",
                "lu",
                "lv",
                "luan",
                "lue",
                "lun",
                "luo",
                "ma",
                "mai",
                "man",
                "mang",
                "mao",
                "me",
                "mei",
                "men",
                "meng",
                "mi",
                "mian",
                "miao",
                "mie",
                "min",
                "ming",
                "miu",
                "mo",
                "mou",
                "mu",
                "na",
                "nai",
                "nan",
                "nang",
                "nao",
                "ne",
                "nei",
                "nen",
                "neng",
                "ni",
                "nian",
                "niang",
                "niao",
                "nie",
                "nin",
                "ning",
                "niu",
                "nong",
                "nu",
                "nv",
                "nuan",
                "nue",
                "nuo",
                "o",
                "ou",
                "pa",
                "pai",
                "pan",
                "pang",
                "pao",
                "pei",
                "pen",
                "peng",
                "pi",
                "pian",
                "piao",
                "pie",
                "pin",
                "ping",
                "po",
                "pu",
                "qi",
                "qia",
                "qian",
                "qiang",
                "qiao",
                "qie",
                "qin",
                "qing",
                "qiong",
                "qiu",
                "qu",
                "quan",
                "que",
                "qun",
                "ran",
                "rang",
                "rao",
                "re",
                "ren",
                "reng",
                "ri",
                "rong",
                "rou",
                "ru",
                "ruan",
                "rui",
                "run",
                "ruo",
                "sa",
                "sai",
                "san",
                "sang",
                "sao",
                "se",
                "sen",
                "seng",
                "sha",
                "shai",
                "shan",
                "shang",
                "shao",
                "she",
                "shen",
                "sheng",
                "shi",
                "shou",
                "shu",
                "shua",
                "shuai",
                "shuan",
                "shuang",
                "shui",
                "shun",
                "shuo",
                "si",
                "song",
                "sou",
                "su",
                "suan",
                "sui",
                "sun",
                "suo",
                "ta",
                "tai",
                "tan",
                "tang",
                "tao",
                "te",
                "teng",
                "ti",
                "tian",
                "tiao",
                "tie",
                "ting",
                "tong",
                "tou",
                "tu",
                "tuan",
                "tui",
                "tun",
                "tuo",
                "wa",
                "wai",
                "wan",
                "wang",
                "wei",
                "wen",
                "weng",
                "wo",
                "wu",
                "xi",
                "xia",
                "xian",
                "xiang",
                "xiao",
                "xie",
                "xin",
                "xing",
                "xiong",
                "xiu",
                "xu",
                "xuan",
                "xue",
                "xun",
                "ya",
                "yan",
                "yang",
                "yao",
                "ye",
                "yi",
                "yin",
                "ying",
                "yo",
                "yong",
                "you",
                "yu",
                "yuan",
                "yue",
                "yun",
                "za",
                "zai",
                "zan",
                "zang",
                "zao",
                "ze",
                "zei",
                "zen",
                "zeng",
                "zha",
                "zhai",
                "zhan",
                "zhang",
                "zhao",
                "zhe",
                "zhen",
                "zheng",
                "zhi",
                "zhong",
                "zhou",
                "zhu",
                "zhua",
                "zhuai",
                "zhuan",
                "zhuang",
                "zhui",
                "zhun",
                "zhuo",
                "zi",
                "zong",
                "zou",
                "zu",
                "zuan",
                "zui",
                "zun",
                "zuo"
            )
            val instance = CharacterParser()
        }
    }
    

    以上的类主要做一些汉字ascii转拼音的操作;
    TestContactBean:

    package com.example.test29api.slider_contact
    
    class TestContactBean(val name: String = "", val phone: String = "") : NewSideBar.Indexable<String> {
        override val indexable: String
            get() {
                return name
            }
    }
    

    这里不要忘了继承NewSideBar的Indexable接口,便于获取需要排序的词组;

    相关文章

      网友评论

          本文标题:android recycleView自定义字母检索A-Z排序滑

          本文链接:https://www.haomeiwen.com/subject/zjrvbktx.html