安卓-手风琴小部件

25

我正在寻找创建类似于此页面上所示的手风琴式小部件的最佳方法。 是否有使用标准Android工具包实现相同效果的方法,或者我需要构建自定义小部件?如果需要 - 如果有的话,您推荐扩展哪个小部件?


1
我有一个很好的解决方案,使用视图类型“隐藏”和“可见”。这是链接:http://android-puremvc-ormlite.blogspot.com/2011/07/android-simple-accordion-panel.html。 - Surojit
为什么这不是本地小部件? - mitsest
4个回答

30

如果你还在疑惑,这可以通过线性布局内堆叠的一对按钮/布局来实现。以下是伪代码

<LinearLayout android:orientation="vertical">
    <Button android:text="Panel 1"/>
    <SomeKindOfLayout android:id="@+id/panel1">
            <!-- widgets in first panel go here -->
    </SomeKindOfLayout>
    <Button android:text="Panel 2"/>
    <SomeKindOfLayout android:id="@+id/panel2" android:visibility="gone">
            <!-- widgets in second panel go here -->
    </SomeKindOfLayout>
    <Button android:text="Panel 3"/>
    <SomeKindOfLayout android:id="@+id/panel3" android:visibility="gone">
            <!-- widgets in third panel go here -->
    </SomeKindOfLayout>
    <Button android:text="Panel 4"/>
    <SomeKindOfLayout android:id="@+id/panel4" android:visibility="gone">
            <!-- widgets in fourth panel go here -->
    </SomeKindOfLayout></LinearLayout>

另一个可能尝试的方法是将可扩展列表视图(ExpandableListView)相互叠放在一起


5
我得与世界分享 :) 记录一下 - 这是@commonsguy在maillist(android.developers)上给我的片段。 - Bostone
你好,我正在动态创建手风琴按钮,因为列表中的按钮数量不确定。对于每个按钮,我都有一个LinearLayout,并在其中放置一些视图。请问有人知道如何获取相应手风琴按钮的onclicklistner,以便我可以在相应的LinearLayout之间切换可见性和隐藏性。 - Vinayak Bevinakatti
如果您将ListView放置在SomeKindOfLayout中,这是否有效?我似乎记得Android只允许每个布局有一个ListView。 - Karim Varela
1
您可以在一个布局中拥有尽可能多的ListView。只是如果您想在ListActivity(或ListFragment)中使用布局,则应该只有一个带有android:id="@android:id/list"的ListView。 - Alex Semeniuk

22

我在Github上推出了Android手风琴视图项目。我们为客户使用它,在2.2、2.3.x、3.2和4.0.3上进行了测试。对我们来说效果非常不错。

接下来,我们将在展开/折叠时添加动画效果。

这里是一个小截图:

输入图像描述


嗨,Maciej,我成功地运行了你的手风琴应用程序,它看起来非常不错。我想将其移植到我的应用程序中,我该怎么做?我尝试复制文件,但是我遇到了ic_resource找不到的问题。我这样做对吗?应该将所有文件都复制出来吗? - Nicholas TJ
1
@NicholasTJ 我认为你应该在Github上询问...但既然你在这里问了:该项目是Android库项目,请在此处阅读更多信息http://developer.android.com/tools/projects/index.html#LibraryProjects。您可以使用Maven构建并获取apklib-请参见此处https://code.google.com/p/maven-android-plugin/wiki/ApkLib - Maciej Łopaciński
谢谢你的建议,我很感激。我会阅读你提供的链接。 - Nicholas TJ
1
但是我无法添加自己的对象(TextView、按钮等)初始化。我该怎么做? - user3213851
1
无法让它正常工作...没有任何文档..我的问题与上面的评论相同,我们如何在其中添加自己的对象?我们使用布局作为容器并在其中添加所有内容吗? - SudoPlz

8
我不得不冒险说 @Bostone 的答案是最合适的。我会在下面给出我的代码,这样你就可以看到。感谢 Maciej Łopaciński 的 GitHub,但正如评论中 @SudoPlz 所说,根本没有文档。我不知道该从哪里开始。我试图用 Eclipse 和 Android Studio 来做,在任何一个软件中都无法运行项目以开始弄清楚它的工作原理。此外,该项目的最后一次提交是大约一年前,这让我非常担心,如果出了什么问题,我就会陷入死胡同。所以,不再拖延,这是基于 @Bostone 的解决方案:
1.- 首先,您需要在 ScrollView 中创建一个 Button 和一个 Layout:
    <ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".TasksListActivity">


            <Button
                android:id="@+id/magic_btn"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="Magic Btn"/>
            <LinearLayout
                android:id="@+id/magic_layout"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical"
                android:visibility="gone">

        </LinearLayout>
</ScrollView>

2.- 然后去找到对应的JAVA文件,找到按钮并设置一个onClick监听器,在监听器内部你会找到布局。

Button findMagicBtn = (Button) findViewById(R.id.magic_btn);
        findMagicBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

            }
        });

3.- 现在,在onClickListner中我们需要找到这个布局。正如您在第一步中看到的,该布局默认设置为GONE,但现在我们需要将其设置为可见。问题是,我如何再次隐藏它并相反呢?因此,我们将添加一个条件来获取布局的可见性,并基于此来隐藏或显示:

Button findMagicBtn = (Button) findViewById(R.id.magic_btn);
        findMagicBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                LinearLayout findMagicLl = (LinearLayout) findViewById(R.id.magic_layout);
                if (findMagicLl.getVisibility() == View.VISIBLE) {
                    findMagicLl.setVisibility(View.GONE);
                } else {
                    findMagicLl.setVisibility(View.VISIBLE);
                }
            }
        });

这可以重复叠放多次。
所以,如果你真的想让它看起来像手风琴,你可以美化按钮。你可以在右侧加上箭头,例如:
findMagicBtn.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.right_arrow, 0);

您应该在onClick方法内执行此操作,并使用条件来更改箭头的方向,通过更改可绘制对象(如果是gone,则为下箭头,如果是visible则为上箭头)。

此外,您可以通过添加动画使其看起来更自然,如下所示:

ScaleAnimation animation = new ScaleAnimation(1f, 1f, 1f, 0f, Animation.RELATIVE_TO_SELF, 0f, Animation.RELATIVE_TO_SELF, 0f);
animation.setDuration(180);
animation.setFillAfter(true);
findMagicLl.startAnimation(animation);

您需要考虑到上述动画必须在视图可见的情况下完成。请注意,setFillAfter(true)会永久地改变容器的大小,因此如果使用了该属性,可能就不再需要使用VIEW.GONE了。这个问题有一个关于缩放动画的很好的解释。


我使用了您的方法来模拟手风琴,但是内部LinearLayout不会根据其子控件进行扩展。在该布局中,我放置了一个带有一些元素的ListView。当我运行它时,效果是只显示第一个元素,但我可以滚动listview以逐个查看其他项目。整个手风琴都是通过编程方式创建的。您能否给我一些提示,如何解决这个问题并显示整个列表视图而无需滚动? - jstuardo
@jstuardo 很抱歉,我认为你的问题与列表视图有关,列表视图总是加载足够的元素以适应屏幕上可用的大小。那么,如果没有可用的大小...在列表视图中,只有当用户需要查看时,才会创建视野之外的下一个元素,这是因为它可以节省内存。 如果我的修复方法有这个问题,我会很难过,但我认为你可以通过更改线性布局高度属性来解决它。尝试匹配父级。另外,请查看默认情况下不使用可见性 gone 会发生什么。 也许你可以覆盖列表视图的行为。让我知道。 - cutiko
@jstuardo 有类似的问题,你可能想阅读这些内容: https://dev59.com/J2Ml5IYBdhLWcg3wbGh1 https://dev59.com/ilwY5IYBdhLWcg3wNFdY#32881309 https://dev59.com/Ml0Z5IYBdhLWcg3w3DQW#31818632 - cutiko
1
我们应该使用动画来实现上述功能,而不是使用库。 - Raja Jawahar

3
在我的应用程序中,我使用了Riya Gayasen的手风琴视图。它很容易上手并且运行良好。以下是我的步骤:
  1. https://github.com/riyagayasen/Android_accordion_view下载源代码zip文件。
  2. 解压缩并将'easyaccordion'文件夹复制到您的项目根目录(包含'app'文件夹的目录)。
  3. 在您的项目根目录settings.gradle文件中添加: easyaccordion。我的文件看起来像这样:include':app',':easyaccordion'
  4. 在您的App/build.gradle文件的dependencies块中添加以下行:implementation 'com.riyagayasen.android:easyaccordion:1.0.3'
  5. 就这样了!您可以开始在布局中使用该组件。

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