美文网首页
简单粗暴!教你用kotlin 5分钟怼出一个文本选择器

简单粗暴!教你用kotlin 5分钟怼出一个文本选择器

作者: 杰洛特world | 来源:发表于2021-06-27 23:11 被阅读0次

不知道你是否曾遇到需要选择年龄,城市,日期等列表文本的情况呢?类似下图的效果:


9ns6q-7yj7x.gif

滑动列表时中间位置突出选中,两侧保持一致,如果是你来实现这个功能,会怎么去做呢?

本文带你用最快的速度最小的成本实现一个简单粗暴且稳定的文本选择器,语言我们使用kotlin,当然java也是可以的,这里它们几乎没有什么差异。

首先需要有滚动的功能,RecyclerView和scrollView都能满足需求,我们先尝试使用ScrollView+LinearLayout实现,至于RecyclerView我们后面会提到。

实现大体逻辑是 判断item是否滑到了中间位置,如果滑到了中间位置,那么这个item的字体变大(或者其它效果),否则恢复正常。

所以最核心的问题就是怎么判断item是否滑到了中间,目前我们已知

  • 父布局的宽度:parentWidth (也就是scrollView或者LinearLayout的宽度)
  • 每个孩子的宽度:itemWidth (也就是每个TextView的宽度)
  • 孩子的数量:childCount
  • 总宽度:itemWidth x childCount
    (这里的宽度我们也可以理解为横坐标)

所以我们需要在滑动的时候先找到位于中间的宽度(坐标),再根据这个宽度找到对应的item,从而实现选中效果。

设想一下,最简单的情况,有四个item,ABCD,D暂不可见

每个item宽度都为 100,parentWidth为 300,totalWidth = 400,childCount = 4

现在把C移动到B的位置, 需要移动100,那么 对于C来讲它的中间位置就等于

var currentMiddleWidth = parentSize / 2 + distance --> 150 + 100 = 250

再用这个长度除以总长度就是占总长的一个百分比,最后乘以childCount 就得出索引值了

var selectorItemIndex = currentMiddleWidth / totalWidth * childCount = 2(下标从0开始),

正好对应的item就是C ,也就是说当我滑动 100像素时,这时候位于中间位置的元素就是C。

滑动前:


before_scroll.png

滑动后:

滑动的距离 scrollX = 100

after_scroll.png

那么我们就可以得出根据移动的距离 scrollX算出处于中间位置的 item index的方法:

/**
  * 根据滚动距离获取被选中Item的下标
  */
 
    fun getSelectedIndexByScrollX(scrollX: Int, parentWidth: Int): Int {
 
        var currentMiddleWidth: Float = (parentSize / 2 + scrollX).toFloat()
 
        var childCount: Int = mDataList?.size ?: 0
 
        return (currentMiddleWidth / mTotalSize * childCount).toInt()
 
    }

拿到item后,设置它的选中效果,再将其它的item设置非选中效果即可

这样,我们就用ScrollView实现了一个简单版的文本选择器。

当然,它还存在很多不足,比如

1.只支持单一布局(滑动)

HorizontalScrollView : 横向

ScrollView : 纵向

没法直接使用一个View同时支持横竖向(虽然也可以自定义ScrollView;或者同时使用这两个View,再根据方向去隐藏或者显示)

2.性能问题

滑动的时候是遍历所有的item进行判断,如果item数量过多,那么势必影响性能。而且在首次加载时,是一口气创建所有的子view,存在OOM的风险。

综上2个问题,使用RecyclerView可以避免,首先RecyclerView可以支持横竖布局,其次RecyclerView内置的view缓存机制(view的回收复用)可以避免性能及内存问题,但这里又引发了新的问题,就是当item的width不是固定值,而是wrap_content时,totalSize没法计算,导致我们这套逻辑不适用,这个暂时不在本文讨论(如果讨论的话,标题就不是5分钟了)。

具体实现可以看我的demo。两套实现逻辑均有(默认是ScrollView),各属性均支持代码和XML设置。

https://github.com/jieluote/ItemSelecterBar.git

展望:

“万物皆可选”是我的设计初衷。这也是为什么起名字叫做 ItemSelecterBar而不是 TextSelector或者 NumberSelector的原因。后期不再是只针对Textview设置,可支持任何view的任何效果,这需要用到动画,比如中间位置的view放大(添加动画),两边的缩小(去除动画)。

另外,如果大家有了解过不错的开源库可以推荐下。

相关文章

  • 简单粗暴!教你用kotlin 5分钟怼出一个文本选择器

    不知道你是否曾遇到需要选择年龄,城市,日期等列表文本的情况呢?类似下图的效果: 滑动列表时中间位置突出选中,两侧保...

  • RxJava OnErrorNotImplementedExce

    简单粗暴一点的解决方式: 在Application的onCreate方法中加入以下代码: kotlin写法: ja...

  • iOS基础·小白篇

    1,UISwitch,该控件,选择器代码: 方法: 2,文本及相应知识点: 3,UIAlterView 弹窗的简单...

  • CSS-基础

    选择器样式:背景/大小样式:文本/字体 选择器 样式:背景/大小 样式:文本/字体 样式:边框 样式:内边距 样式...

  • 教你用kotlin撸一个背景透明度联动的banner

    教你用kotlin撸一个背景透明度联动的banner 最近因为接到个需求:banner分成前景和背景2层,背景随着...

  • 如何用Python处理自然语言?(Spacy与Word Embe

    本文教你用简单易学的工业级Python自然语言处理软件包Spacy,对自然语言文本做词性分析、命名实体识别、依赖关...

  • css选择器和文本标签

    1、css选择器 标签选择器 id选择器 类选择器 层级选择器 组选择器 伪类选择器 文本标签 em标签用于表示一...

  • NumberPicker设置字符格式化时第一次不起效

    用了NumberPicker来实现一个选择器的时候发现一个问题,选择器中的文本是可以被自己定制的,然后当选择器第一...

  • CSS选择器

    css选择器 CSS选择器可以简单分为三类:简单选择器、伪元素选择器、组合选择器 简单选择器 标签选择器 标签选择...

  • CSS

    文字相关属性 文本属性 标签选择器 id选择器 类选择器 后代择器 子元素选择器 交集选择器(了解) 并集选择器 ...

网友评论

      本文标题:简单粗暴!教你用kotlin 5分钟怼出一个文本选择器

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