Android中的展开/折叠按钮(用于显示/隐藏可选视图)

3

我需要一个UI元素,允许用户展开/折叠(显示/隐藏)包含可选/高级信息的视图。

我设想这是一个文本标签(例如“高级选项”,“更多/更少”),加上一个在打开和关闭之间切换的图标。我有一些可用的图标,该元素的功能与ToggleButton非常相似,因此我尝试使用样式化的ToggleButton解决此问题。

从维护的角度来看,这个解决方案非常丑陋。我会在下面添加它作为答案。

我希望有人能提出更好的解决方案,或者指出我的解决方案如何简化。

顺便说一句,在this SO Q/A中很好地解决了展开/折叠视图的动画效果。


1
我已经为此创建了一个库:https://github.com/salmaanahmed/SAExpandableButton - Salmaan
4个回答

5

谢天谢地,我找到了一种更简单的方法。

不再使用ToggleButton(需要11个资源文件来样式化),我只是用一个TextView和CompoundDrawable,然后自己管理状态。

这种方式需要写入一些代码,但可以节省大量的资源文件混乱。另外,它也使得更容易处理多个主题,例如在这里,我根据主题设置所需图标的资源ID:

final MainActivity ma = (MainActivity) getActivity();
if  (ma.isDarkTheme()) {
    icon_expand = getResources().getIdentifier( "ic_action_expand","drawable", ma.getPackageName() );       
    icon_collapse = getResources().getIdentifier( "ic_action_collapse","drawable", ma.getPackageName() );       
} else {
    icon_expand = getResources().getIdentifier( "ic_action_expand_light","drawable", ma.getPackageName() );     
    icon_collapse = getResources().getIdentifier( "ic_action_collapse_light","drawable", ma.getPackageName() );     
}

我会在我的 fragment 的 onCreate 方法中这样实现。很遗憾,我必须在运行时解析图标 ID,但似乎这就是做法。
我不知道为什么在这种情况下我的图标以正常大小显示,而在我将它们指定为 ToggleButton 背景的图层时则以双倍大小显示(这就需要为所有图标提供 ScaledDrawable 资源)。
这是我的 TextView 的 onClickListener:
protected OnClickListener expandCtrlListener = new OnClickListener() {
    public void onClick(View v) {
        assertTrue( v == expandCtrl );
        isExpanded = !isExpanded;
        advancedView.setVisibility( isExpanded ?  View.VISIBLE : View.GONE );
        expandCtrl.setCompoundDrawablesWithIntrinsicBounds( isExpanded ? icon_collapse : icon_expand, 0, 0, 0 );
    }
};

请注意,这些内容中没有展开/折叠的动画。在我在问题结尾提到的文章中有解决方法。

1

如我在问题中所述,按钮的功能与ToggleButton非常相似,因此我开始使用一种布局,该布局显示了一个样式化的ToggleButton和一些文本:

<RelativeLayout
    android:id="@+id/expandLayout"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="right"
    android:layout_marginRight="12dp" >
    <ToggleButton
        android:id="@+id/expcollButton"
        style="@style/expCollToggleBtn"
        android:layout_centerVertical="true"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:checked="false"/>
    <TextView
        android:id="@+id/expandText"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
        android:layout_marginLeft="8dp"
        android:layout_toRightOf="@id/expcollButton"
        android:text="Show Options" />
</RelativeLayout>

样式(在styles.xml文件中)看起来像这样。这会将按钮文本设置为空,并指向背景可绘制对象。
<style name="expCollToggleBtn">
    <item name="android:background">@drawable/expcoll_btn_toggle_bg_light</item>
    <item name="android:textOn"></item>
    <item name="android:textOff"></item>
    <item name="android:disabledAlpha">?android:attr/disabledAlpha</item>
</style>

背景可绘制对象是一个 layer-list 的 xml 文件,它指向另一个可绘制对象(也许有一些方法可以摆脱这个文件并直接指向下面的选择器?)
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@+android:id/background" android:drawable="@android:color/transparent" />
    <item android:id="@+android:id/toggle" android:drawable="@drawable/expcoll_btn_toggle" />
</layer-list>

该选择器列出了打开/关闭的图像:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_checked="false" android:drawable="@drawable/ic_action_expand" />
    <item android:state_checked="true" android:drawable="@drawable/ic_action_collapse" />
</selector>

现在,第一个麻烦是这会导致一个非常过大的按钮/图片。我已经为所有像素密度提供了合适的图片,所以我不确定为什么会发生这种情况,但解决方法是缩放这些图片。
不幸的是,这似乎需要针对每个图片使用ScaledDrawable。我实际上有四张图片,因为我愚蠢地决定支持我的应用程序中的浅色和深色主题。所以我需要四个这样的图片。
<scale xmlns:android="http://schemas.android.com/apk/res/android"
    android:drawable="@drawable/ic_action_expand"
    android:scaleGravity="center"
    android:scaleHeight="50%"
    android:scaleWidth="50%" 
/>

此外,请注意在ScaledDrawables中存在一个错误如此描述,因此需要考虑这一点。
最后,由于我正在尝试支持两个主题,我需要多个选择器和图层列表文件,并需要向attrs.xml文件添加属性。到目前为止,我涉及了11个XML文件(加上所有密度的10个图像文件),而这只是为了创建一个相当普通的按钮。
这不可能是正确的!

0

一个简单的展开/折叠代码

   //show/hide boxes panel
    var expansion: Boolean = false

    expand_up.setOnClickListener {
        if (!expansion) {
            expand_up.setImageResource(R.drawable.collapse)
            boxes_panel.visibility = View.VISIBLE
            expansion = true
        }
        else{
            expand_up.setImageResource(R.drawable.expand)
            boxes_panel.visibility = View.GONE
            expansion = false
        }
    } 

-2

有一个针对此功能的库。
它叫做SAExpandableButton,你可以在这里找到它。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接