Android ChipGroup收起折叠效果实现详解

目录
  • 一、先上效果图
  • 二、ChipGroup和Chip
  • 三、在ChipGroup中动态添加Chip
  • 四、找到每个Chip位于的行数
  • 五、实现思路
  • 六、需要注意的问题
    • 1、Chip的复用问题
    • 2、Chip的ID设置
    • 3、点击同一个Chip返回的ID为-1的问题

一、先上效果图

借用某东App的效果,如下。

折叠时的效果:

展开时的效果:

二、ChipGroup和Chip

chipGroup和chip之前写过博客,可移步Android Material 常用组件,看关于chip和chipGroup的部分,建议一定要看,因为里面还挺多坑的。这里简单贴下chip和chipGroup的代码:

ChipGroup:

<com.google.android.material.chip.ChipGroup
    android:id="@+id/chip_group"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginTop="@dimen/size_15dp"
    app:chipSpacingHorizontal="@dimen/size_9dp"
    app:chipSpacingVertical="@dimen/size_8dp"
    app:singleSelection="true" />

Chip: 需要定义三种Chip的布局:箭头朝上的、箭头朝下的、普通展示文字的,如果能复用定义一种也行,这里简单贴一种:

<?xml version="1.0" encoding="utf-8"?>
<com.google.android.material.chip.Chip xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/chip"
    style="@style/Widget.MaterialComponents.Chip.Filter"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:textColor="@color/login_model"
    android:textSize="@dimen/font_12sp"
    android:theme="@style/Theme.MaterialComponents"
    app:checkedIconVisible="false"
    app:chipBackgroundColor="@color/printer_unused_reason"
    app:chipMinHeight="@dimen/size_24dp"
    app:chipMinTouchTargetSize="0dp" />

三、在ChipGroup中动态添加Chip

这个比较简单,inflate后add即可,如下:

//添加Chip
for (index in 0 until size) {
    val chip = layoutInflater.inflate(
            R.layout.common_chip_end,
            mViewBind.chipGroup,
            false) as Chip
    chip.text = mWordList[index]
    //动态添加ID
    chip.id = index
    mViewBind.chipGroup.addView(chip)
}

四、找到每个Chip位于的行数

这个需求一般会要求显示固定的行数(比如效果图中某东App的二行),然后显示有向下箭头的Chip,点击后可以展开,那么如何找到固定行数最后一行的最后一个Chip呢? 不用担心ChipGruop(的父类)有给我们提供Api:

/** Gets the row index of the child, primarily for accessibility.   */
public int getRowIndex(@NonNull View child) {
  Object index = child.getTag(R.id.row_index_key);
  if (!(index instanceof Integer)) {
    return -1;
  }
  return (int) index;
}

于是当我们将添加到ChipGroup的Chip调用该Api后就知道每个Chip位于哪一行了。

五、实现思路

我们已经找到每个Chip位于第几行,自然我们就知道固定行数的最后一行的最后一个Chip是谁,我们替换该Chip为向下箭头的Chip就可以完成折叠的效果。

展开的效果就很简单了,加上向上箭头的Chip即可。

六、需要注意的问题

1、Chip的复用问题

很遗憾,chip不能复用,每次展开和折叠都会先清除ChipGroup中的Chip然后再添加,如果边清除边添加同一个Chip就会报错,所以清除所有Chip后还是要用inflate重新创建新的Chip。

//清除
mViewBind.chipGroup.removeAllViews()
//重新inflate
val chip = layoutInflater.inflate(
            R.layout.common_chip_end,
            mViewBind.chipGroup,
            false) as Chip
//添加
mViewBind.chipGroup.addView(endChip)

2、Chip的ID设置

如果在for循环中添加chip,可以直接用Chip的数据源的索引(要展示的文本集合的索引),这样我们获取Chip的内容就很简单。如果是一些特殊的Chip,我们可以单独inflate单独添加,单独设置ID,比如向上向下箭头的Chip。

//设置箭头的ID
arrowUpChip.id = ARROW_UP_CHIP_ID
arrowDownChip.id = ARROW_DOWN_CHIP_ID
//处理Chip的点击事件
mViewBind.chipGroup.setOnCheckedChangeListener { group, checkedId ->
    //记录点击的ID
    mClickChipId = if (checkedId > -1) checkedId else mClickChipId
    when (mClickChipId) {
        ARROW_DOWN_CHIP_ID -> {  //箭头向下的Chip的点击
            enlargeChipList(true)
        }
        ARROW_UP_CHIP_ID -> {    //箭头向上的Chip的点击
            enlargeChipList(false)
        }
        else -> {   //其他
            val text = mWordList[mClickChipId]
        }
    }
}

3、点击同一个Chip返回的ID为-1的问题

ChipGroup有个坑就是重复点击同一个Chip,第一次返回的Chip的ID正常,后面返回的Chip的ID都是-1,所以需要记录首次点击的Chip的ID,如果你发现返回的ID为-1,那么就是用户点击了上次的Chip,这一点要注意。

//记录点击的ID
mClickChipId = if (checkedId &gt; -1) id else mClickChipId

总结: 这个重要的是实现思路,核心代码也贴出来了,理解了实现起来就不难。写这篇文章主要是是记录一下。

以上就是Android ChipGroup收起折叠效果实现详解的详细内容,更多关于Android ChipGroup收起折叠的资料请关注我们其它相关文章!

(0)

相关推荐

  • Android基础控件RadioGroup使用方法详解

    本文为大家分享了Android基础控件RadioGroup的使用,供大家参考,具体内容如下 1.简单介绍 RadioGroup可以提供几个选项供用户选择,但只能选择其中的一个.其下面可以横着或者竖着挂几个RadioButton,也可以挂载其他控件(如TextView).RadioGroup的相应事件一般不由下面的RadioButton响应,而是直接由RadioGroup响应.实现RadioGroup.OnCheckedChangeListener接口即可监听RadioGroup.RadioBut

  • Android RadioGroup多行显示效果 解决单选问题

    导语 如下图所示,这是一个导航选择弹框.进行单项选择,然后会监听回调选择的事件.问题是Android的RadioButton是一般是放在RadioGroup中进行管理的,而RadioGroup又是线性布局,即单行有效,多行无效.如图那种就需要两个RadioGroup来进行合作.那么如果进行合作呢? 分析:RadioGroup多行显示其实就是两个RadioGroup进行切换,使用RadioGroup的clearCheck()方法进行操作. 但是在使用clearCheck()之前,如果RadioGr

  • Android底部菜单栏(RadioGroup+Fragment)美化

    众所周知,android的底部菜单栏太重要,平时项目一般都是需要用到的,但是网上关于这方面的demo做得太丑了,实在惨不忍睹,所以这里便用RadioGroup+Fragment的方式写了一个,顺便美化了一下,需要的可以看下. 效果图: 项目结构 MainActivity.java public class MainActivity extends AppCompatActivity { private FrameLayout frameLayout; private RadioGroup rad

  • Android开发手册Chip监听及ChipGroup监听

    目录 Chip监听 ChipGroup监听 实例 效果展示 Chip监听 选中状态的监听:setOnCheckedChangeListener,该监听只有设置了checkable 属性为true或者使用了[filter/entry/choice]这三个style主题的时候才生效. 点击事件的监听:setOnClickListener 关闭按钮被点击的监听:setOnCloseIconClickListener Java myChip.setOnCloseIconClickListener(Vie

  • Android自定义RadioGroupX实现多行多列布局

    前言 今天在做新需求的时候,活动有多个类型可以选择,UI给的设计图为多行多列排版,且单项选择,细细想来,谷歌并没有为我们提供类似的控件,初步设想使用RecyclerView实现多行多列布局,然后再用代码控制逻辑部分,总感觉不太稳妥,又想到让UI小姐姐重新设计一番?感觉也不太稳妥,这样UI小姐姐就会认为我菜,为了不让別人觉得我菜,干脆自定义RadioGroupX实现多行多列布局. 思考 在工作中,面对一个功能,首先想到的是应该怎样实现完成它,然后再考虑究竟怎样实现才更优雅.正如前面提到,实现这种需

  • Android 自定义View实现任意布局的RadioGroup效果

    前言 RadioGroup是继承LinearLayout,只支持横向或者竖向两种布局.所以在某些情况,比如多行多列布局,RadioGroup就并不适用 . 本篇文章通过继承RelativeLayout实现自定义RadioGroup,实现RadioButton的任意布局.效果图如下: 代码(RelativeRadioGroup) /** * Author : BlackHao * Time : 2018/10/26 10:46 * Description : 自定义 RadioGroup */ p

  • Android ImageView的selector效果实例详解

    Android ImageView的selector效果实例详解 在平时开发中如Button我们给它加上selector分别呈现pressed以及normal效果能给我们的用户体验上大大增色不少,可是我们当我们是用ImageView来"当作"一个一个"Button"的时候发现直接设置selector却不起作用,当然此时我们的应用就表现的暗淡了.那我们就只能找到方法来解决这种情况. 首先定义一个selector文件: <selector xmlns:androi

  • Android 通过自定义view实现水波纹效果案例详解

    在实际的开发中,很多时候还会遇到相对比较复杂的需求,比如产品妹纸或UI妹纸在哪看了个让人兴奋的效果,兴致高昂的来找你,看了之后目的很明确,当然就是希望你能给她: 在这样的关键时候,身子板就一定得硬了,可千万别说不行,爷们儿怎么能说不行呢: 好了,为了让大家都能给妹纸们想要的,后面会逐渐分享一些比较比较不错的效果,目的只有一个,通过自定义view实现我们所能实现的动效: 今天主要分享水波纹效果: 标准正余弦水波纹: 非标准圆形液柱水波纹: 虽说都是水波纹,但两者在实现上差异是比较大的,一个通过正余

  • Android Flutter实现3D动画效果示例详解

    目录 前言 AnimatedWidget 简介 3D 旋转动画的实现 总结 前言 上一篇我们介绍了 Animation 和 AnimationController 的使用,这是最基本的动画构建类.但是,如果我们想构建一个可复用的动画组件,通过外部参数来控制其动画效果的时候,上一篇的方法就不太合适了.在 Flutter 中提供了 AnimatedWidget 组件用于构建可复用的动画组件.本篇我们用 AnimatedWidget 来实现组件的3D 旋转效果,如下图所示. AnimatedWidge

  • Android 逐帧动画创建实例详解

    Android 逐帧动画创建实例详解 前言: 我们看早期电影的时候,电影通常是一张一张播放,用我们现在专有名词来说,就是一帧帧来,安卓同样有这样动画效果的编排形式. 那么我们先定义逐帧动画xml文件 <?xml version="1.0" encoding="utf-8"?> <animation-list xmlns:android="http://schemas.android.com/apk/res/android" an

  • Android中XUtils3框架使用方法详解(一)

    xUtils简介 xUtils 包含了很多实用的android工具. xUtils 支持大文件上传,更全面的http请求协议支持(10种谓词),拥有更加灵活的ORM,更多的事件注解支持且不受混淆影响... xUitls 最低兼容android 2.2 (api level 8) 今天给大家带来XUtils3的基本介绍,本文章的案例都是基于XUtils3的API语法进行的演示.相信大家对这个框架也都了解过, 下面简单介绍下XUtils3的一些基本知识. XUtils3一共有4大功能:注解模块,网络

  • Android 属性动画ValueAnimator与插值器详解

    Android 属性动画ValueAnimator与插值器详解 一.ValueAnimator详解: ValueAnimator是整个动画的核心,ObjectAnimator即是继承自ValueAnimator来实现. ValueAnimator更像是一个数值发生器,用来产生具有一定规律的数字,从而让调动者来控制动画的实现过程. 1.ValueAnimator的使用: ValueAnimator valueAnimator = ValueAnimator.ofFloat(0, 100); val

  • Android 中 Tweened animation的实例详解

    Android 中 Tweened animation的实例详解 Tweened animation有四种类型,下面主要介绍Scale类型. 运行效果如下: Android SDK提供了2种方法:直接从XML资源中读取Animation,使用Animation子类的构造函数来初始化Animation对象,第二种方法在看了Android SDK中各个类的说明就知道如何使用了,下面简要说明从XML资源中读取Animation.XML资源中的动画文件animation.xml内容为: <?xml ve

  • Android实现屏幕锁定源码详解

    最近有朋友问屏幕锁定的问题,自己也在学习,网上找了下也没太详细的例子,看的资料书上也没有有关屏幕锁定程序的介绍,下个小决心,自己照着官方文档学习下,现在做好了,废话不多说,先发下截图,看下效果,需要注意的地方会加注释,有问题的朋友可以直接留言,我们共同学习交流,共同提高进步!直接看效果图: 一:未设置密码时进入系统设置的效果图如下: 二:设置密码方式预览: 三:密码解密效果图 四:九宫格解密时的效果图 下面来简单的看下源码吧,此处讲下,这个小DEMO也是临时学习下的,有讲的不明白的地方请朋友直接

  • Android 开发订单流程view实例详解

     Android 开发订单流程view实例详解 先看看最终效果图: 怎么样,效果还是很不错的吧?群里有人说切四张图的.recycleview的.各种的都有啊,但是最简单的就是通过自定义view来实现了-接下来让我们来实现下这个(订单流程view). 首先我们定义好我们的自定义属性: attrs.xml <?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleabl

  • Android Canvas方法总结最全面详解API(小结)

    本篇文章主要介绍了Android Canvas方法总结最全面详解API,分享给大家,具体如下: 常用方法 drawXxx方法族:以一定的坐标值在当前画图区域画图,另外图层会叠加, 即后面绘画的图层会覆盖前面绘画的图层. clipXXX方法族:在当前的画图区域裁剪(clip)出一个新的画图区域,这个 画图区域就是canvas对象的当前画图区域了.比如:clipRect(new Rect()), 那么该矩形区域就是canvas的当前画图区域 getXxx方法族:获得与Canvas相关一些值,比如宽高

随机推荐

其他