listview实现的tree树结构

时间:2021-06-18 12:55:45

转自:http://www.eoeandroid.com/thread-309141-1-1.html 会更新版本
代码分享
代码名称: myTreeViewDemo
代码描述: 使用listView实现的树状结构
代码托管地址: -
代码作者: 阿富

效果图:
listview实现的tree树结构

写在前面:
首先说明一下,这个只是最基本的树状组织结构的展现,我自己ps的连接线o(∩_∩)o ,至于实际使用中,可以对+、-号以及节点图标和文本加入点击事件;也可以在节点前加入checkbox等。
在做这个之前,网上也找了很久,找到的比较多的就是这个例子:http://www.apkbus.com/android-83520-1-1.html,但是这个不好看,所以基于这个才有了本例子。上代码:

TreeElement.Java
package com.ccl.util.tree;

import java.util.ArrayList;
import java.util.List;

import android.view.View.OnClickListener;

public class TreeElement {
private int img_tree_space_n = R.drawable.tree_space_n;
private int img_tree_space_y = R.drawable.tree_space_y;

    private String id;// 节点id
private String caption;// 节点标题
private String value;// 节点的值
private int level;// 层级
private TreeElement parent;// 该节点的父节点
private boolean isHasChild;// 是否有子节点
private boolean isExpanded;// 是否处于展开
private ArrayList<TreeElement> childList;// 子节点数组
private boolean isLastSibling;// 是否是同级节点的最后一个
private ArrayList<Integer> spaceList;// 组织结构线条数组
private int position;// 在listview中所处的位置
private OnClickListener captionOnClickListener;// 节点文本点击事件

public TreeElement() {
super();
}

public TreeElement(String id, String caption, String value,
Boolean isHasChild, OnClickListener captionOnClickListener) {
this.id = id;
this.caption = caption;
this.value = value;
this.parent = null;
this.level = 0;
this.isHasChild = isHasChild;
this.isExpanded = false;
if (isHasChild) {
this.childList = new ArrayList<TreeElement>();
}
this.isLastSibling = false;
this.setSpaceList(new ArrayList<Integer>());
this.position = 0;
this.setCaptionOnClickListener(captionOnClickListener);
}

// 添加子节点
public void addChild(TreeElement treeElement) {
treeElement.parent = this;
if (treeElement.getParent() != null
&& treeElement.getParent().getChildList().size() > 0) {// 将之前的同级节点的置为非最后一个节点
List<TreeElement> siblingList = treeElement.getParent()
.getChildList();
treeElement.getParent().getChildList().get(siblingList.size() - 1)
.setLastSibling(false);
}
this.childList.add(treeElement);
this.isHasChild = true;
treeElement.level = this.level + 1;
treeElement.isLastSibling = true;
if (this.level > 0) {
treeElement.getSpaceList().addAll(this.getSpaceList());
if (this.isLastSibling()) {
treeElement.getSpaceList().add(img_tree_space_n);
} else {
treeElement.getSpaceList().add(img_tree_space_y);
}
}
}

public String getId() {
return id;
}

public void setId(String id) {
this.id = id;
}

public String getCaption() {
return caption;
}

public void setCaption(String caption) {
this.caption = caption;
}

public String getValue() {
return value;
}

public void setValue(String value) {
this.value = value;
}

public TreeElement getParent() {
return parent;
}

public void setParent(TreeElement parent) {
this.parent = parent;
}

public boolean isHasChild() {
return isHasChild;
}

public void setHasChild(boolean isHasChild) {
this.isHasChild = isHasChild;
}

public boolean isExpanded() {
return isExpanded;
}

public void setExpanded(boolean isExpanded) {
this.isExpanded = isExpanded;
}

public ArrayList<TreeElement> getChildList() {
return childList;
}

public void setChildList(ArrayList<TreeElement> childList) {
this.childList = childList;
}

public int getLevel() {
return level;
}

public void setLevel(int level) {
this.level = level;
}

public boolean isLastSibling() {
return isLastSibling;
}

public void setLastSibling(boolean isLastSibling) {
this.isLastSibling = isLastSibling;
}

public ArrayList<Integer> getSpaceList() {
return spaceList;
}

public void setSpaceList(ArrayList<Integer> spaceList) {
this.spaceList = spaceList;
}

public int getPosition() {
return position;
}

public void setPosition(int position) {
this.position = position;
}

public OnClickListener getCaptionOnClickListener() {
return captionOnClickListener;
}

public void setCaptionOnClickListener(OnClickListener captionOnClickListener) {
this.captionOnClickListener = captionOnClickListener;
}

}
TreeViewAdapter.java

package com.ccl.util.tree;

import java.util.ArrayList;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

public class TreeViewAdapter extends ArrayAdapter<TreeElement> {
private int img_leaf = R.drawable.icon_user;// 没有子节点的节点图标
private int img_expand = R.drawable.outline_list_expand;// 展开的图标
private int img_collapse = R.drawable.outline_list_collapse;// 收缩的图标
private int img_tree_space_1 = R.drawable.tree_space_1;// 连接线
private int img_tree_space_2 = R.drawable.tree_space_2;

private Context context;
private LayoutInflater mInflater;
private ArrayList<TreeElement> treeElementList;
private int viewResourceId;

public TreeViewAdapter(Context context, int viewResourceId,
ArrayList<TreeElement> objects) {
super(context, viewResourceId, objects);
this.context = context;
this.mInflater = LayoutInflater.from(context);
this.treeElementList = objects;
this.viewResourceId = viewResourceId;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
convertView = mInflater.inflate(viewResourceId, null);
holder = new ViewHolder();
holder.caption = (TextView) convertView.findViewById(R.id.caption);
holder.icon = (ImageView) convertView.findViewById(R.id.icon);
holder.space = (LinearLayout) convertView.findViewById(R.id.space);
convertView.setTag(holder);
TreeElement treeElement = treeElementList.get(position);

int level = treeElement.getLevel();
if (level == 0) {// 根节点

} else {
ArrayList<Integer> spaceList = treeElement.getSpaceList();

// 绘制前面的组织架构线条
for (int i = 0; i < spaceList.size(); i++) {
ImageView img = new ImageView(context);
img.setImageResource(spaceList.get(i));
holder.space.addView(img);
}
ImageView img = new ImageView(context);
// 节点图标
if (treeElement.isLastSibling()) {
img.setImageResource(img_tree_space_2);
} else {
img.setImageResource(img_tree_space_1);
}

holder.space.addView(img);
}
if (treeElement.isHasChild()) {
if (treeElement.isExpanded()) {
holder.icon.setImageResource(img_expand);
} else {
holder.icon.setImageResource(img_collapse);
}
holder.icon.setOnClickListener(new TreeElementIconClickListener(
context, treeElementList, this, treeElement.getPosition()));
} else {
holder.icon.setImageResource(img_leaf);
}
holder.caption.setText(treeElement.getCaption());// 设置标题
if (treeElement.getCaptionOnClickListener() != null) {// 设置文字的点击事件
holder.caption.setTag(treeElement.getValue());
holder.caption.setOnClickListener(treeElement
.getCaptionOnClickListener());

}
return convertView;
}

class ViewHolder {
LinearLayout space;
TextView caption;
ImageView icon;
}

public static class TreeElementIconClickListener implements OnClickListener {
private Context context;
private ArrayList<TreeElement> treeElementList;
private TreeViewAdapter treeViewAdapter;
private int position;

public TreeElementIconClickListener(Context mContext,
ArrayList<TreeElement> mTreeElementList,
TreeViewAdapter mTreeViewAdapter, int position) {
this.context = mContext;
this.treeElementList = mTreeElementList;
this.treeViewAdapter = mTreeViewAdapter;
this.position = position;
}

@Override
public void onClick(View v) {
System.out.println("点击的position:" + position);
if (!treeElementList.get(position).isHasChild()) {
Toast.makeText(context,
treeElementList.get(position).getCaption(),
Toast.LENGTH_SHORT).show();
return;
}

if (treeElementList.get(position).isExpanded()) {
treeElementList.get(position).setExpanded(false);
TreeElement element = treeElementList.get(position);
ArrayList<TreeElement> temp = new ArrayList<TreeElement>();

for (int i = position + 1; i < treeElementList.size(); i++) {
if (element.getLevel() >= treeElementList.get(i).getLevel()) {
break;
}
temp.add(treeElementList.get(i));
}

treeElementList.removeAll(temp);
for (int i = position + 1; i < treeElementList.size(); i++) {
System.out.println(treeElementList.get(i).getCaption()
+ "@@@" + i);
treeElementList.get(i).setPosition(i);
}

treeViewAdapter.notifyDataSetChanged();
} else {
TreeElement obj = treeElementList.get(position);
obj.setExpanded(true);
int level = obj.getLevel();
int nextLevel = level + 1;

ArrayList<TreeElement> tempList = obj.getChildList();

for (int i = 0; i < tempList.size(); i++) {
TreeElement element = tempList.get(i);
element.setLevel(nextLevel);
element.setExpanded(false);
treeElementList.add(position + i + 1, element);
}
for (int i = position + 1; i < treeElementList.size(); i++) {
System.out.println(treeElementList.get(i).getCaption()
+ "@@@" + i);
treeElementList.get(i).setPosition(i);
}
treeViewAdapter.notifyDataSetChanged();
}

}
}
}

MainActivity.java

package com.ccl.util.tree;

import java.util.ArrayList;

import com.ccl.util.tree.TreeViewAdapter.TreeElementIconClickListener;

import android.os.Bundle;
import android.app.Activity;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ListView;
import android.widget.Toast;

public class MainActivity extends Activity {
private ListView lv_tree;
private TreeViewAdapter treeViewAdapter;
private ArrayList<TreeElement> mRootList;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
lv_tree = (ListView) findViewById(R.id.lv_tree);
mRootList = new ArrayList<TreeElement>();
treeViewAdapter = new TreeViewAdapter(this, R.layout.atom_tree,
mRootList);
lv_tree.setAdapter(treeViewAdapter);

OnClickListener myOnClickListener = new OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(MainActivity.this, "--" + v.getTag(),
Toast.LENGTH_LONG).show();
}
};

TreeElement rootElement = new TreeElement("root", "root", "1", true,
null);

TreeElement treeElement1 = new TreeElement("node1", "节点1", "1", true,
null);
TreeElement treeElement2 = new TreeElement("node2", "节点2", "2", false,
myOnClickListener);
TreeElement treeElement3 = new TreeElement("node3", "节点3", "1", false,
myOnClickListener);
TreeElement treeElement4 = new TreeElement("node3", "节点4", "1", true,
myOnClickListener);

TreeElement treeElement1_1 = new TreeElement("node14", "节点1_1", "1",
true, myOnClickListener);
TreeElement treeElement1_2 = new TreeElement("node14", "节点1_2", "1",
false, myOnClickListener);
TreeElement treeElement1_3 = new TreeElement("node14", "节点1_3", "1",
true, myOnClickListener);
TreeElement treeElement1_1_1 = new TreeElement("node14", "节点1_1_1",
"1", false, myOnClickListener);
TreeElement treeElement1_3_1 = new TreeElement("node14", "节点1_3_1",
"1", true, myOnClickListener);
TreeElement treeElement1_3_2 = new TreeElement("node14", "节点1_3_2",
"1", false, myOnClickListener);
TreeElement treeElement1_3_1_1 = new TreeElement("node14", "节点1_3_1_1",
"1", false, myOnClickListener);

TreeElement treeElement4_1 = new TreeElement("node14", "节点4_1", "1",
true, myOnClickListener);
TreeElement treeElement4_2 = new TreeElement("node14", "节点4_2", "1",
false, myOnClickListener);
TreeElement treeElement4_3 = new TreeElement("node14", "节点4_3", "1",
true, myOnClickListener);
TreeElement treeElement4_1_1 = new TreeElement("node14", "节点4_1_1",
"1", false, myOnClickListener);
TreeElement treeElement4_3_1 = new TreeElement("node14", "节点4_3_1",
"1", false, myOnClickListener);
mRootList.add(rootElement);
rootElement.addChild(treeElement1);
rootElement.addChild(treeElement2);
rootElement.addChild(treeElement3);
rootElement.addChild(treeElement4);
treeElement1.addChild(treeElement1_1);
treeElement1.addChild(treeElement1_2);
treeElement1.addChild(treeElement1_3);
treeElement1_1.addChild(treeElement1_1_1);
treeElement1_3.addChild(treeElement1_3_1);
treeElement1_3.addChild(treeElement1_3_2);
treeElement1_3_1.addChild(treeElement1_3_1_1);
treeElement4.addChild(treeElement4_1);
treeElement4.addChild(treeElement4_2);
treeElement4.addChild(treeElement4_3);
treeElement4_1.addChild(treeElement4_1_1);
treeElement4_3.addChild(treeElement4_3_1);

treeViewAdapter.notifyDataSetChanged();
System.out.println(1111);

// 展开根目录
TreeElementIconClickListener mtest = new TreeElementIconClickListener(
MainActivity.this, mRootList, treeViewAdapter, 0);
mtest.onClick(null);

}
}