tree view android,Android Treeview

本文探讨了在Android中如何超越ExpandableListView的限制,实现5级及以上深度的真正树形垂直列表。作者分享了自定义适配器、使用HTML+WebView展示、开源库和自定义组件等多种实现方法,并给出了相关代码示例和建议。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题

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

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.

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

回答1:

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

Its N-level tree.

Custom style for nodes

Save state after rotation

b84cd8297ced6d6ba9f63393971cb424.png

回答2:

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/

5f4f56bd685c374da9f69dbeba229932.png

回答3:

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

other thread

99798eb3b2acdd2f2f5e22261284a975.png

回答4:

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

Our implementation in an open-source proejct.

回答5:

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

Here's the trick: use a WebView and 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

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

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

回答6:

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/

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.

回答7:

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/

edc24209a09d6ed783e2c51c5fe9f2fa.png

回答8:

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.

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).

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.

回答9:

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;

}

}

}

回答10:

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;

}

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.

来源:https://stackoverflow.com/questions/3271772/android-treeview

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值