Android 字母排序通讯录

效果图:

代码部门:

Activity

class ContactViewActivity: AppCompatActivity(){    private var mAdater: ContactSortAdapter? = null    private var mDataList: MutableList? = null    override fun onCreate(savedInstanceState: Bundle?) {        super.onCreate(savedInstanceState)        setContentView(R.layout.activity_sort_recycler)        initView()        initData()    }    fun initView(){        ed_search?.addTextChangedListener(object : TextWatcher {            override fun onTextChanged(s: CharSequence, start: Int, before: Int,                                       count: Int) {                if (TextUtils.isEmpty(s.toString().trim())){                    contact_view?.initData(mDataList)                    mAdater?.initData(mDataList)                }else{                    mAdater?.initData(contact_view?.updateData(s.toString()))                }            }            override fun beforeTextChanged(s: CharSequence, start: Int,                                           before: Int, count: Int) {            }            override fun afterTextChanged(arg0: Editable) {            }        })    }    fun initData(){        val arrayData = arrayOf("a", "bd", "ced", "de", "as", "东皇太一","宫本武藏","王昭君","李元芳","刘禅","后裔","许爱明","无名","流海"                ,"亚瑟","吕布", "秋雅", "夏洛", "公孙离", "张良", "孙尚香", "我", "你", "啊", "哈哈", "嘿"                ,"无名","流海","亚瑟","吕布", "夏洛", "公孙离", "张良", "孙尚香","无名","流海","亚瑟","吕布", "刘备", "夏洛", "公孙离", "张良", "孙尚香"                ,"无名","流海","亚瑟","吕布", "秋雅", "夏洛", "公孙离", "张良", "孙尚香","无名","流海","亚瑟","吕布", "秋雅", "夏洛", "公孙离", "张良", "孙尚香")        var data = mutableListOf()        for (i in arrayData){            data.add(i)        }        mAdater = ContactSortAdapter()        RecyclerViewUtil.initNoDecoration(this,contact_view?.getRecycler(),mAdater)        mDataList = contact_view?.sortData(data)        contact_view?.initData(mDataList)        mAdater?.initData(mDataList)    }}

布局

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:background="@color/white"    android:orientation="vertical" >    <LinearLayout        android:id="@+id/ll_top_search"        android:layout_width="match_parent"        android:layout_height="56dp"        android:gravity="center"        android:background="@color/color_0">        <EditText            android:id="@+id/ed_search"            android:layout_width="match_parent"            android:layout_height="40dp"            android:background="@drawable/radius_bg"            android:drawableLeft="@mipmap/iv_search_normal"            android:drawablePadding="4dp"            android:paddingLeft="4dp"            android:hint="请输入关键字"            android:textSize="14dp"            android:layout_marginLeft="16dp"            android:layout_marginRight="16dp"/>    LinearLayout>    <com.zs.various.view.ContactRecyclerView        android:id="@+id/contact_view"        android:layout_width="match_parent"        android:layout_height="match_parent"        android:layout_below="@+id/ll_top_search"/>RelativeLayout>

Activity 页面部分整体是一个RecyclerView,上面是搜索的EditText,主要的逻辑都在自定义的控件里面处理,activity主要是获取数据,然后调用排序方法,把数据根据字母顺序重新排序,填充到adapter中。

class ContactSortAdapter : RecyclerView.Adapter<ContactSortAdapter.ContactHolder>() {    var mData: MutableList<SortModel>? = null    override fun onCreateViewHolder(parent: ViewGroup?, viewType: Int): ContactHolder {        var view = View.inflate(parent?.context, R.layout.adapter_sort,null)        return ContactHolder(view)    }    override fun getItemCount(): Int {        return if (mData == null) 0 else mData!!.size    }    fun initData(data: MutableList<SortModel>?){        this.mData = data        notifyDataSetChanged()    }    override fun onBindViewHolder(holder: ContactHolder?, position: Int) {        holder?.bindData(position)    }    inner class ContactHolder(itemView: View) : RecyclerView.ViewHolder(itemView){        fun bindData(position: Int) = with(itemView) {            var sortModel = mData!![position]            name?.text = sortModel.name            if (!compareSection(position)){                tv_letter?.visibility = View.VISIBLE                tv_letter?.text = sortModel.letter                line_view?.visibility = View.GONE            }else{                tv_letter?.visibility = View.GONE                line_view?.visibility = View.VISIBLE            }        }    }    fun compareSection(position: Int): Boolean {        return if (position == 0) {            false        } else {            val current = getSectionForPosition(position)            val previous = getSectionForPosition(position - 1)            current == previous        }    }    // 获取当前位置的首字母(int表示ascii码)    fun getSectionForPosition(position: Int): Int {        return mData!![position].letter[0].toInt()    }    // 获取字母首次出现的位置    fun getPositionForSection(section: Int): Int {        for (i in 0 until itemCount) {            val s = mData!![i].letter            val firstChar = s.toUpperCase()[0]            if (firstChar.toInt() == section) {                return i            }        }        return -1    }}

每个条目都有显示字母的title,adapter中控制显示,主要的判断逻辑是,判断上一个数据中名字的首字母是否和本条目的首字母相同,不相同显示title,否则不显示。

自定义 ContactRecyclerView

布局

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent">    <RelativeLayout        android:id="@+id/rl_container_layout"        android:layout_width="match_parent"        android:layout_height="match_parent"        android:layout_alignParentTop="true">        <android.support.v7.widget.RecyclerView            android:id="@+id/recycler_view"            android:layout_width="match_parent"            android:layout_height="match_parent"            android:divider="@null"/>        <TextView            android:layout_width="wrap_content"            android:layout_height="match_parent"            />        <TextView            android:id="@+id/tv_letter_show"            android:layout_width="80dp"            android:layout_height="80dp"            android:layout_centerInParent="true"            android:background="@color/hint_color"            android:gravity="center"            android:textColor="@color/white"            android:textSize="40dp"            android:visibility="gone" />        <include layout="@layout/item_letter_layout"/>        <com.zs.various.view.SideBarView            android:id="@+id/view_sidebar"            android:layout_width="30dp"            android:layout_height="match_parent"            android:layout_alignParentRight="true"            android:layout_marginBottom="20dp"            android:layout_marginTop="20dp">        com.zs.various.view.SideBarView>    RelativeLayout>RelativeLayout>
/**     * 数据排序     */    fun sortData(data: MutableList): MutableList {        val list = mutableListOf()        for (i in data.indices) {            val sm = SortModel()            sm.name = data[i]            val pinyin = mParser.getSelling(data[i])            val sortString = pinyin.substring(0, 1).toUpperCase()            if (sortString.matches("[A-Z]".toRegex())) {                sm.letter = sortString            } else {                sm.letter = "#"            }            list.add(sm)        }        Collections.sort(list, PinyinComparator())        return list    }

把数据进行字母排序

init {        LayoutInflater.from(context).inflate(R.layout.contact_list_layout, this)        ll_top_title = findViewById(R.id.ll_top_title)        tv_letter = findViewById(R.id.tv_letter)        view_sidebar?.setLetterTouchListener(this)        recycler_view?.addOnScrollListener(object : RecyclerView.OnScrollListener() {            override fun onScrollStateChanged(recyclerView: RecyclerView?, newState: Int) {                super.onScrollStateChanged(recyclerView, newState)                mLetterHeight = ll_top_title?.height!!            }            override fun onScrolled(recyclerView: RecyclerView?, dx: Int, dy: Int) {                super.onScrolled(recyclerView, dx, dy)                mLayoutManager = recyclerView?.layoutManager as LinearLayoutManager                //找到列表下一个可见的View                var view = mLayoutManager?.findViewByPosition(mCurrentPosition + 1)                // 检查列表中的letter布局是否显示                if (view != null && view.top <= mLetterHeight && view?.findViewById(R.id.tv_letter)?.visibility == View.VISIBLE){                    //被顶掉的效果                    ll_top_title?.y = (-(mLetterHeight - view.top)).toFloat()                }else{                    ll_top_title?.y = 0f                }                //判断是否需要更新悬浮条                if (mCurrentPosition != mLayoutManager?.findFirstVisibleItemPosition()){                    ll_top_title?.y = 0f                    updateLetter()                }            }        })    }

RecyclerView添加滑动监听事件,处理title顶出的效果,在RecycerView外层添加一层title,recyclerview滑动过程中计算adapter中item的滑动位置,当到达外层title的高度时,动态改变外层title的位置,直到外层title被全部顶出,再把它复位,刷新外层title的字母。
右侧的SideBarView控件控制列表的快速滑动,在ContactRecyclerView中添加触摸监听,处理点击字母和滑动字母时的回调事件。

override fun setLetterVisibility(visibility: Int) {        tv_letter_show?.visibility = visibility    }    override fun setLetter(letter: String?) {        if (TextUtils.isEmpty(letter) || letter!!.isEmpty()){            return        }        tv_letter_show?.text = letter        var position = getPositionForSection(letter!![0].toInt())        if (position != -1) {            updateLetter()            mLetterHeight = ll_top_title?.height!!            mLayoutManager?.scrollToPositionWithOffset(position,0) // 使当前位置处于最顶端        }    }

源码地址

github源码地址

更多相关文章

  1. Android的RelativeLayout的layout_height属性设置为wrap_content
  2. android LinearLayout布局子空间没有填充父控件的问题
  3. android TextView xml中设置最大行数
  4. Android(安卓)透明度对应16进制值
  5. Android(安卓)透明度对应16进制值
  6. Edittext android:inputType 输入的限制
  7. android 设置EditText只能输入大写字母,Fragment的软键盘输入模
  8. Android(安卓)EditText 限制输入数字和字母设置
  9. EditView某些属性说明

随机推荐

  1. android缓存数据 分析
  2. 关于安转android studio 在选择JDK找不到
  3. Android之路——走进Android(工程结构剖
  4. Android实训案例(六)——四大组件之一Broad
  5. Android(安卓)扫描二维码(Scan Kit)
  6. Android(安卓)Studio配置问题总结
  7. 谈谈android 布局 的优化
  8. Android 使用富文本显示web上的内容
  9. Android(安卓)操作数据库Sqlite,数据写入
  10. Android调用系统分享和指定app分享-微信