Java 安卓树视图

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3271772/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 19:14:05  来源:igfitidea点击:

Android Treeview

javaandroidtreeview

提问by Daniel Sloof

I know there is the ExpandableListViewbut it only supports up to 2 levels. I need a true treeview vertical list with at least up to ~5 levels (more is better).

我知道有ExpandableListView但它最多只支持 2 个级别。我需要一个真正的树视图垂直列表,至少有 ~5 级(越多越好)。

Any suggestions?

有什么建议?

edit:

编辑:

I see talk about using a Custom Adapter and setting the padding based on the items level.

我看到谈论使用自定义适配器并根据项目级别设置填充。

I have an unsorted ArrayList of objects that have an ID and parent ID, and I dynamically add items to this array as well.

我有一个未排序的 ArrayList 对象,它有一个 ID 和父 ID,我也动态地将项目添加到这个数组中。

Can anyone give me some examples of how I can go about doing this?

谁能给我一些例子来说明我如何做到这一点?

采纳答案by Daniel Sloof

Answering my own question, since we implemented this many months ago.

回答我自己的问题,因为我们在几个月前实施了这个。

Our implementationin an open-source proejct.

我们在开源项目中的实现。

回答by Ginger McMurray

I'd start by making the data structure more representative of what it's meant to contain. Since you have an array of items and each child can have it's own array of items, each with its own array, etc. I'd consider using a class with two members: an object that represents the data for this particular item and an array that holds the item's children. Each child would itself be an instance of the class so that it, too, could have children.

我首先让数据结构更能代表它要包含的内容。由于您有一个项目数组,并且每个子项都可以拥有自己的项目数组,每个项目都有自己的数组等。我会考虑使用一个具有两个成员的类:一个表示此特定项目数据的对象和一个数组包含项目的子项。每个孩子本身都是类的一个实例,这样它也可以有孩子。

private class ParentAndKids { Object parent; Array kids; }

私有类ParentAndKids { 对象父;数组孩子;}

Your adapter would then have an array of ParentAndKids objects which represents the top layer. You'd add and remove list items based on which parents were expanded.

然后,您的适配器将拥有一个代表顶层的 ParentAndKids 对象数组。您可以根据展开的父项添加和删除列表项。

回答by Arun

package com.expand.search;

import android.app.ExpandableListActivity;
import android.os.Bundle;
import android.view.ContextMenu;
import android.view.Gravity;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.ContextMenu.ContextMenuInfo;
import android.widget.AbsListView;
import android.widget.BaseExpandableListAdapter;
import android.widget.ExpandableListAdapter;
import android.widget.ExpandableListView;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.ExpandableListView.ExpandableListContextMenuInfo;

   /** Demonstrates expandable lists using a custom {@link ExpandableListAdapter}
    * from {@link BaseExpandableListAdapter}.
   */
public class expands extends ExpandableListActivity {

ExpandableListAdapter mAdapter;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    // Set up our adapter
    mAdapter = new MyExpandableListAdapter();
    setListAdapter(mAdapter);
    registerForContextMenu(getExpandableListView());
}

@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
    menu.setHeaderTitle("Sample menu");
    menu.add(0, 0, 0, R.string.expandable_list_sample_action);
}

@Override
public boolean onContextItemSelected(MenuItem item) {
    ExpandableListContextMenuInfo info = (ExpandableListContextMenuInfo) item.getMenuInfo();

    String title = ((TextView) info.targetView).getText().toString();

    int type = ExpandableListView.getPackedPositionType(info.packedPosition);
    if (type == ExpandableListView.PACKED_POSITION_TYPE_CHILD) {
        int groupPos = ExpandableListView.getPackedPositionGroup(info.packedPosition); 
        int childPos = ExpandableListView.getPackedPositionChild(info.packedPosition); 
        Toast.makeText(this, title + ": Child " + childPos + " clicked in group " + groupPos,   
                Toast.LENGTH_SHORT).show();
        return true;
    } else if (type == ExpandableListView.PACKED_POSITION_TYPE_GROUP) {
        int groupPos = ExpandableListView.getPackedPositionGroup(info.packedPosition); 
        Toast.makeText(this, title + ": Group " + groupPos + " clicked", Toast.LENGTH_SHORT).show();
        return true;
    }

    return false;
}

/** A simple adapter which maintains an ArrayList of photo resource Ids. 
 * Each photo is displayed as an image. This adapter supports clearing the
 * list of photos and adding a new photo.
 */
public class MyExpandableListAdapter extends BaseExpandableListAdapter {
    // Sample data set.  children[i] contains the children (String[]) for groups[i].
    private String[] groups = { "Category1", "Category2", "Category3", "Category4" };
    private String[][] children = {
            { "Charity1", "Charity2", "Charity3", "Charity4" },
            { "Charity5", "Charity6", "Charity7", "Charity8" },
            { "Charity9", "Charity10" },
            { "Charity11", "Charity12" }
    };

    public Object getChild(int groupPosition, int childPosition) {
        return children[groupPosition][childPosition];
    }

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

    public int getChildrenCount(int groupPosition) {
        return children[groupPosition].length;
    }

    public TextView getGenericView() {
        // Layout parameters for the ExpandableListView
        AbsListView.LayoutParams lp = new AbsListView.LayoutParams(
                ViewGroup.LayoutParams.MATCH_PARENT, 64);

        TextView textView = new TextView(expands.this);
        textView.setLayoutParams(lp);
        // Center the text vertically
        textView.setGravity(Gravity.CENTER_VERTICAL | Gravity.LEFT);
        // Set the text starting position
        textView.setPadding(36, 0, 0, 0);
        return textView;
    }

    public View getChildView(int groupPosition, int childPosition, boolean isLastChild,
            View convertView, ViewGroup parent) {
        TextView textView = getGenericView();
        textView.setText(getChild(groupPosition, childPosition).toString());
        return textView;
    }

    public Object getGroup(int groupPosition) {
        return groups[groupPosition];
    }

    public int getGroupCount() {
        return groups.length;
    }

    public long getGroupId(int groupPosition) {
        return groupPosition;
    }

    public View getGroupView(int groupPosition, boolean isExpanded, View convertView,
            ViewGroup parent) {
        TextView textView = getGenericView();
        textView.setText(getGroup(groupPosition).toString());
        return textView;
    }

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

    public boolean hasStableIds() {
        return true;
    }
}

}

}

回答by Ted Hopp

I agree with pjv, at least for phone-size devices. It would be better to organize the widget to show one group of siblings at a time in a ListView. This could be done in a single activity that keeps track of its position in the tree. It could show a header with breadcrumbs showing the path to the parent of the items currently on display.

我同意 pjv,至少对于手机大小的设备。最好组织小部件以在 ListView 中一次显示一组兄弟姐妹。这可以在跟踪其在树中的位置的单个活动中完成。它可以显示带有面包屑的标题,显示当前显示的项目的父项的路径。

A multi-level tree view may be appropriate for a tablet device, but a phone does not have enough real estate to support the proposed 5 levels (with everything having to be big enough for fingers).

多级树视图可能适用于平板设备,但手机没有足够的空间来支持建议的 5 级(所有东西都必须足够大以供手指使用)。

Nevertheless, if you are set on a tree view, don't look at subclassing ExpandableListView. It operates internally by packing the parent and child indices (each an int) into a single long. This internal representation makes it virtually impossible to extend beyond 2 levels.

不过,如果您设置在树视图上,请不要查看子类化 ExpandableListView。它通过将父索引和子索引(每个都是一个 int)打包成一个 long 来在内部运行。这种内部表示实际上不可能扩展到 2 个级别以上。

回答by dbm

I found the link below very, very useful. It describes alternative ways of storing tree structures in two dimensional data structures (typically a database table).

我发现下面的链接非常非常有用。它描述了在二维数据结构(通常是数据库表)中存储树结构的替代方法。

I think you'll find the paradigm easy to understand and implement.

我想你会发现范式很容易理解和实现。

http://mikehillyer.com/articles/managing-hierarchical-data-in-mysql/

http://mikehillyer.com/articles/managing-hierarchical-data-in-mysql/

As of how to visualize this in Android is another question. I would perhaps write my own widget from scratch if the "padded" list items solution isn't sufficient.

至于如何在 Android 中可视化这一点是另一个问题。如果“填充”列表项解决方案不够用,我可能会从头开始编写自己的小部件。

回答by 2red13

i solved it for me, posting in a similar thread: other thread

我为我解决了,在一个类似的帖子中发帖: 其他帖子

enter image description here

在此处输入图片说明

回答by Jarek Potiuk

Our company also open-sourced a solution for this. It is available as library, so very easy to use: http://code.google.com/p/tree-view-list-android/

我们公司还为此开源了一个解决方案。它可作为库使用,因此非常易于使用:http: //code.google.com/p/tree-view-list-android/

enter image description here

在此处输入图片说明

回答by dotsa

I think if multilevel expandablelist is done properly it actually works and looks great. Here is another example of http://code.google.com/p/tree-view-list-android/

我认为如果多级可扩展列表正确完成,它实际上可以工作并且看起来很棒。这是http://code.google.com/p/tree-view-list-android/ 的另一个示例

enter image description here

在此处输入图片说明

回答by bmelnychuk

I had the same issue. You can check out my implementation AndroidTreeView.

我遇到过同样的问题。您可以查看我的实现AndroidTreeView

  • Its N-level tree.

  • Custom style for nodes

  • Save state after rotation
  • 它的 N 级树。

  • 节点的自定义样式

  • 旋转后保存状态

AndroidTreeView

安卓树视图

回答by Aaron Gillion

I have found an easiersolution to this problem, as I myself am somewhat intermediate in my coding skills. In my situation, I needed a Windows-themedTree View, which after brainstorming ideas, I was able to implement with hardly any coding!

我找到了一个更简单的解决方案,因为我自己的编码技能有点中级。在我的情况下,我需要一个以Windows 为主题的树视图,在集思广益之后,我几乎不用任何编码就可以实现它!

Here's the trick: use a WebViewand an embedded HTML page to display a custom Tree View, and use Android's super handy JavaScript communication interface to receive selections & clicks: Proof of Concept Example on Android-er Blog

诀窍如下:使用WebView和嵌入式 HTML 页面显示自定义树视图,并使用 Android 超级方便的 JavaScript 通信界面接收选择和点击:Android-er 博客上的概念验证示例

With this power we can take advantage of a large collection of JS/CSS control snippets around the web. Themeable Windows7-Style jQuery TreeView control -- jsTree

有了这种能力,我们可以利用网络上大量的 JS/CSS 控件片段。主题化的 Windows7 风格的 jQuery TreeView 控件——jsTree

Lot's of possibilities and power with Android out there, happy coding!

Android 有很多可能性和力量,快乐编码!