我需要一个UI元素,允许用户展开/折叠(显示/隐藏)包含可选/高级信息的视图。
我将此设想为文本标签(例如“高级选项”,“更多/更少”)以及在打开和关闭之间切换的图标。我有一些可以达到目的的图标,并且元素的功能与ToggleButton的功能非常匹配,所以我尝试使用样式化的ToggleButton来解决这个问题。
这个解决方案结果证明是非常丑陋的(从维护角度来看)。我将在下面添加它作为答案。
我希望有人能提出更好的解决方案,或指出我的解决方案如何简化。
BTW,this SO Q/A很好地解决了视图扩展/折叠的问题。
答案 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