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

时间:2013-09-12 19:38:10

标签: android android-ui

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

我将此设想为文本标签(例如“高级选项”,“更多/更少”)以及在打开和关闭之间切换的图标。我有一些可以达到目的的图标,并且元素的功能与ToggleButton的功能非常匹配,所以我尝试使用样式化的ToggleButton来解决这个问题。

这个解决方案结果证明是非常丑陋的(从维护角度来看)。我将在下面添加它作为答案。

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

BTW,this SO Q/A很好地解决了视图扩展/折叠的问题。

4 个答案:

答案 0 :(得分:5)

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

我没有使用ToggleButton(它涉及11个资源文件来设置样式),而是使用带有CompoundDrawable的TextView,然后自己管理状态。

这种方式涉及更多代码,但可以节省大量资源文件。它还可以更轻松地处理多个主题,例如在这里,我根据主题设置所需图标的资源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() );     
}

我在片段的onCreate中这样做。遗憾的是我必须在运行时解析图标ID,但这似乎就是这样做的。

我不知道为什么我的图标在这种情况下以正常大小显示,并且当我将它们指定为ToggleButton的背景图层时需要双倍大小(这需要我所有图标的ScaledDrawable资源)。

这是我的onClickListener(对于TextView):

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 :(得分: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>

背景drawable是一个层列表xml文件,指向另一个drawable(也许有一些方法可以摆脱这个文件并直接指向下面的选择器?)

<?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中存在一个错误described here,因此需要对此进行说明。

最后,由于我正在尝试支持两个主题,我需要选择器和图层列表文件的多个副本,并且需要向attrs.xml文件添加属性。在这一点上,我有11个XML文件(加上所有密度的10个图像文件)都是一个非常普通的按钮。

这可能不对!

答案 2 :(得分: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
        }
    } 

答案 3 :(得分:-2)

有一个图书馆。
它叫做SAExpandableButton,你可以找到它here