多层ExpandableListView

发布于 2024-12-18 06:16:07 字数 1875 浏览 5 评论 0原文

我目前正在开发一个项目,其中我需要类似以下内容:

- MainGroup 1 (Expandable)
  - SubGroup 1 (Expandable)
    - SubSubGroup 1 (Expandable)
      - Child View
      - Child View
      - ...
    - SubSubGroup 2 (Expandable)
      - Child View
      - Child View
      - ...
  - SubGroup 2 (Expandable)
    - SubSubGroup 3 (Expandable)
      - Child View
      - ...
    - SubSubGroup 4 (Expandable)
      - Child View
      - ...
  - SubGroup 3 (Expandable)
    - Child View
    - ...
- MainGroup 2 (Expandable)
  - ...

最多它是 ExpandableListView 内的 ExpandableListView 内的 ExpandableListView > - 因此 3 层 ExpandableListView

  • MainGroup 只能容纳其他 ExpandableListView
  • SubGroup 将保存除最后两个之外的其他 ExpandableListView,它们始终只是 ChildViews。 (我认为这两个可以用 SubSubGroup 中的一个代替)
  • SubSubGroup 将始终保存 ChildViews

我的问题是,我认为我无法理解 ExpandableListView 如何布局其子项的基本原则。我看过这个之类的示例,但无法理解围绕功能。

我尝试简单地添加一个 ExpandableListView 作为另一个中的子项 - 但有些东西不起作用,因为如果您展开其中一个,则只有内部 ExpandableListView 的第一项可见外层群体。不过,我可以通过手动设置外部组容器的高度,使其足够大以显示内部 ExpandableListView 中的所有项目。为了达到最佳效果,高度的计算当然应该即时完成。

因此,为了解决一些更扎实的问题:

  • 有人可以给我解释一下 ExpandableListView “生命周期”(我指的是实例化、视图重用、展开/折叠侦听器),包括:
    • ExpandableListView 如何以及何时通知子项展开/折叠?
    • ExpandableListView 如何知道需要为所有子项留出多少空间才能放入组容器?
  • 与仅使用一些 LinearLayouts 和一些 OnClickListeners 将我自己的解决方案混合在一起相比,使用 ExpandableListView 创建上述内容有多少好处?

编辑

对于我的最后一个问题,我可能会注意到可以有 1 到 20 多个 MainGroups

I'm currently working on a project in which I need something like the following:

- MainGroup 1 (Expandable)
  - SubGroup 1 (Expandable)
    - SubSubGroup 1 (Expandable)
      - Child View
      - Child View
      - ...
    - SubSubGroup 2 (Expandable)
      - Child View
      - Child View
      - ...
  - SubGroup 2 (Expandable)
    - SubSubGroup 3 (Expandable)
      - Child View
      - ...
    - SubSubGroup 4 (Expandable)
      - Child View
      - ...
  - SubGroup 3 (Expandable)
    - Child View
    - ...
- MainGroup 2 (Expandable)
  - ...

At most it would be an ExpandableListView inside an ExpandableListView inside an ExpandableListView - so 3 layers of ExpandableListView:

  • MainGroup would only hold other ExpandableListView.
  • SubGroup would hold other ExpandableListView except for the last two, which will allways just be ChildViews. (I'm thinking those two could just be substituted with the one for SubSubGroup)
  • SubSubGroup would allways hold ChildViews.

My problem is that I think I fail to understand the basic principles of how the ExpandableListView layouts it's children. I've looked at examples like this, but can't get my head around the functionality.

I've tried simply adding an ExpandableListView as a child in another - but something doesn't work as only the first item of the inner ExpandableListView is visible if you expand one of the outer groups. I can however by setting the height of the outer groups container manually make it big enough to show all items in the inner ExpandableListView. To be optimal, calculation of height should of course be done on the fly.

So, to get to some more solid questions:

  • Can someone give me an explanation of the ExpandableListView "lifecycle" (by this I mean instantation, re-use of views, expand/collapse listeners) including:
    • How and when is an ExpandableListView notified that a child is expanded/collapsed?
    • How does the ExpandableListView know how much space to make for all children to fit into a group container?
  • How much benefit is there in using the ExpandableListView to create the above, compared to just mixing together my own solution using some LinearLayouts and some OnClickListeners?

Edit

For my last question I might note that there can be anywhere from 1 to 20+ MainGroups.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

睡美人的小仙女 2024-12-25 06:16:08

您可能想查看项目。我还没有尝试过,但我想值得一试。默认的 ExpanadableListView 非常有限,最初设计为仅支持 2 个级别。您可以对其进行修改以使其支持更多级别,但它会变得混乱。

You might want to check this project out. I haven't tried it, but I guess it's worth a try. The default ExpanadableListView is quite limited, designed originally to support only 2 levels. You can hack around with it to get it to support more levels than that, but it'll get messy.

深海蓝天 2024-12-25 06:16:08

尽管这不是完整的解决方案,但它仍然是一个 3 层可扩展列表。因此,如何设计它取决于您。

这是类

package com.custom.nagee;

import android.app.ExpandableListActivity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import android.widget.ExpandableListView;
import android.widget.LinearLayout;

public class CustomemExpandible extends ExpandableListActivity{
    LayoutInflater inflator;
    boolean flag = true;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        inflator = LayoutInflater.from(getApplicationContext());
        setListAdapter(new MyAdapter());
    }

    @Override
    public boolean onChildClick(ExpandableListView parent, View v,
            int groupPosition, int childPosition, long id) {
        if(flag){
            v.findViewById(childPosition).setVisibility(View.VISIBLE);
            flag = false;
            return true;
        }
        v.findViewById(childPosition).setVisibility(View.GONE);
        flag = true;
        return true;
    }
    class MyAdapter extends BaseExpandableListAdapter{

        @Override
        public Object getChild(int groupPosition, int childPosition) {
            return null;
        }

        @Override
        public long getChildId(int groupPosition, int childPosition) {
            return 0;
        }

        @Override
        public View getChildView(int groupPosition, int childPosition,
                boolean isLastChild, View convertView, ViewGroup parent) {
            LinearLayout linearLayout = (LinearLayout)inflator.inflate(R.layout.group, null);
            linearLayout.getChildAt(1).setId(childPosition);
            return linearLayout;
        }

        @Override
        public int getChildrenCount(int groupPosition) {
            return 2;
        }

        @Override
        public Object getGroup(int groupPosition) {
            return null;
        }

        @Override
        public int getGroupCount() {
            return 2;
        }

        @Override
        public long getGroupId(int groupPosition) {
            return 0;
        }

        @Override
        public View getGroupView(int groupPosition, boolean isExpanded,
                View convertView, ViewGroup parent) {
            return ((LinearLayout)inflator.inflate(R.layout.group, null));
        }

        @Override
        public boolean hasStableIds() {
            // TODO Auto-generated method stub
            return false;
        }

        @Override
        public boolean isChildSelectable(int groupPosition, int childPosition) {
            return true;
        }

    }
}

,这是 xml 文件

group.xml

<?xml version="1.0" encoding="utf-8"?>

<TextView
    android:id="@+id/editText1"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:textColor="@color/back"
    android:layout_marginLeft="30dip" 
    android:text="DONE" >
</TextView>

<LinearLayout
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:layout_marginLeft="30dip" 
    android:visibility="gone" >

    <TextView
        android:id="@+id/editText2"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" 
        android:text="DONE">
    </TextView>

    <TextView
        android:id="@+id/editText3"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="DONE" />

    <TextView
        android:id="@+id/editText4"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="DONE" />
</LinearLayout>

这是在颜色文件夹下用于更改文本颜色的,它留给您,您甚至可以更改背景以获得更好的外观。

back.xml

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_enabled="false" android:color="#808080"/>
    <item android:state_window_focused="false" android:color="#808080"/>
    <item android:state_pressed="true" android:color="#808080"/>
    <item android:state_selected="true" android:color="#000000"/>
    <item android:color="#FF0000"/> <!-- not selected -->
</selector>

希望它能起作用......

Even though this is not the complete solution still its a 3 layered Expandable List. So its left to you how you style it.

here is the class

package com.custom.nagee;

import android.app.ExpandableListActivity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import android.widget.ExpandableListView;
import android.widget.LinearLayout;

public class CustomemExpandible extends ExpandableListActivity{
    LayoutInflater inflator;
    boolean flag = true;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        inflator = LayoutInflater.from(getApplicationContext());
        setListAdapter(new MyAdapter());
    }

    @Override
    public boolean onChildClick(ExpandableListView parent, View v,
            int groupPosition, int childPosition, long id) {
        if(flag){
            v.findViewById(childPosition).setVisibility(View.VISIBLE);
            flag = false;
            return true;
        }
        v.findViewById(childPosition).setVisibility(View.GONE);
        flag = true;
        return true;
    }
    class MyAdapter extends BaseExpandableListAdapter{

        @Override
        public Object getChild(int groupPosition, int childPosition) {
            return null;
        }

        @Override
        public long getChildId(int groupPosition, int childPosition) {
            return 0;
        }

        @Override
        public View getChildView(int groupPosition, int childPosition,
                boolean isLastChild, View convertView, ViewGroup parent) {
            LinearLayout linearLayout = (LinearLayout)inflator.inflate(R.layout.group, null);
            linearLayout.getChildAt(1).setId(childPosition);
            return linearLayout;
        }

        @Override
        public int getChildrenCount(int groupPosition) {
            return 2;
        }

        @Override
        public Object getGroup(int groupPosition) {
            return null;
        }

        @Override
        public int getGroupCount() {
            return 2;
        }

        @Override
        public long getGroupId(int groupPosition) {
            return 0;
        }

        @Override
        public View getGroupView(int groupPosition, boolean isExpanded,
                View convertView, ViewGroup parent) {
            return ((LinearLayout)inflator.inflate(R.layout.group, null));
        }

        @Override
        public boolean hasStableIds() {
            // TODO Auto-generated method stub
            return false;
        }

        @Override
        public boolean isChildSelectable(int groupPosition, int childPosition) {
            return true;
        }

    }
}

and here goes the xml file

group.xml

<?xml version="1.0" encoding="utf-8"?>

<TextView
    android:id="@+id/editText1"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:textColor="@color/back"
    android:layout_marginLeft="30dip" 
    android:text="DONE" >
</TextView>

<LinearLayout
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:layout_marginLeft="30dip" 
    android:visibility="gone" >

    <TextView
        android:id="@+id/editText2"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" 
        android:text="DONE">
    </TextView>

    <TextView
        android:id="@+id/editText3"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="DONE" />

    <TextView
        android:id="@+id/editText4"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="DONE" />
</LinearLayout>

and this is under color folder for changing text color, its left you , you can even change the background for getting better looks.

back.xml

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_enabled="false" android:color="#808080"/>
    <item android:state_window_focused="false" android:color="#808080"/>
    <item android:state_pressed="true" android:color="#808080"/>
    <item android:state_selected="true" android:color="#000000"/>
    <item android:color="#FF0000"/> <!-- not selected -->
</selector>

hope it works...

廻憶裏菂餘溫 2024-12-25 06:16:07

首先,让我向您推荐GrepCode 站点。它有 Android SDK 类的来源。感谢他们,我已经找到了 AdapterViews 的基本原理(我给了您 ExpandableListView 的链接,但如果您不仅研究它,而且还研究它的类父级,那就更好了)。

现在,你的问题和我的答案:

ExpandableListView 如何以及何时通知子项已存在
展开/折叠?

请参阅方法 handleItemClick(视图v,int位置,长id)

ExpandableListView 如何知道要为所有内容腾出多少空间
孩子们适合分组容器吗?

这个问题我没有好好研究,但据我所知,它是通过 requestLayout() 方法做出来的。我们还发现一个可滚动视图不能嵌入到另一个可滚动视图中。 (这是一个众所周知的错误:将ListView放入ScrollView或将ListView放入ExpandableListView)。

使用ExpandableListView来创建有多少好处
以上,与仅使用一些将我自己的解决方案混合在一起相比
LinearLayouts 和一些 OnClickListeners?

AdapterView 速度更快。但是即使对于 ExpandableListView 来说,您的构造也太复杂了。您可以使用 2 种解决方案。

  1. 大师解决方案:如果您专业设计自己的解决方案
    从头开始视图/视图组(我的意思是,你了解方法
    requestLayout()、dispatchDraw()等),然后编写自己的
    GrandExpandableListAdapter 有 3 个级别。
  2. 中等解决方案:前 2 级使用 ExpandableListAdapter,并使用 LinearLayouts
    第三级。

First of all, let me recommend you GrepCode site. It has sources of Android SDK classes. Thanks for them, I've found out base principles of AdapterViews (I gave you a link to ExpandableListView, but it's better if you research not only it, but its class-parents as well).

Now, your questions and my answers:

How and when is an ExpandableListView notified that a child is
expanded/collapsed?

See method handleItemClick(View v, int position, long id)

How does the ExpandableListView know how much space to make for all
children to fit into a group container?

I didn't research this question well, but as far as I know, it's made by the method requestLayout(). Also we found out that one scrollable View cannot be embedded into another scrollable View. (It's wide-known mistake: to put ListView into ScrollView or ListView into ExpandableListView).

How much benefit is there in using the ExpandableListView to create
the above, compared to just mixing together my own solution using some
LinearLayouts and some OnClickListeners?

AdapterViews are faster. But your construction is too complex even for ExpandableListView. You may use 2 solutions.

  1. Guru-solution: if you're professional of designing your own
    Views/ViewGroups from the scratch (I mean, you understand methods
    requestLayout(), dispatchDraw() and so on), then write your own
    GrandExpandableListAdapter with 3 levels.
  2. Medium-solution: use ExpandableListAdapter for first 2 levels and use LinearLayouts for
    3rd level.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文