本例中目录树的菜单数据是从json数据中获取,首先建立一个菜单实体类  MenuTree

package com.gao.tree;

/**
* 菜单树的各级菜单实体类
*
* @author tjs
*
*/
public class MenuTree {
/** 菜单编号 */
private String id;
/** 菜单内容 */
private String text;
/** 父节点id */
private String parentId;
/** 是否有子节点 */
private boolean hasChild;
/** 层级 */
private int level;
/** 是否展开 */
private boolean expanded; /***
*
* @param id
* 菜单编号
* @param text
* 菜单显示内容
* @param hasParent
* 是否有父节点
* @param parentId
* 父节点id
* @param hasChild
* 是否有子节点
* @param level
* 层级
* @param expanded
* 展开状态
*/
public MenuTree(String id, String text, String parentId, boolean hasChild, int level, boolean expanded) {
super();
this.id = id;
this.text = text;
this.parentId = parentId;
this.hasChild = hasChild;
this.level = level;
this.expanded = expanded;
} /***
*
* @param id
* 菜单编号
* @param text
* 菜单显示内容
* @param hasParent
* 是否有父节点
* @param parentId
* 父节点id
* @param hasChild
* 是否有子节点
* @param level
* 层级
*/
public MenuTree(String id, String text, String parentId, boolean hasChild, int level) {
super();
this.id = id;
this.text = text;
this.parentId = parentId;
this.hasChild = hasChild;
this.level = level;
this.expanded = false;// 初始化为折叠
} public String getId() {
return id;
} public void setId(String id) {
this.id = id;
} public String getText() {
return text;
} public void setText(String text) {
this.text = text;
} public String getParentId() {
return parentId;
} public void setParentId(String parentId) {
this.parentId = parentId;
} public boolean isHasChild() {
return hasChild;
} public void setHasChild(boolean hasChild) {
this.hasChild = hasChild;
} public int getLevel() {
return level;
} public void setLevel(int level) {
this.level = level;
} public boolean isExpanded() {
return expanded;
} public void setExpanded(boolean expanded) {
this.expanded = expanded;
} @Override
public String toString() {
return "MenuTree [id=" + id + ", text=" + text + ", parentId=" + parentId + ", hasChild=" + hasChild + ", level=" + level
+ ", expanded=" + expanded + "]";
} }

获取并解析json目录树数据  ,建立工具类  GetDada

package com.gao.tree;

import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.List; import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject; public class GetData {
/**
* 描述:连接网络,获取Json的byte数组
* */
public static byte[] readParse(String urlPath) throws Exception {
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
byte[] data = new byte[1024];
int len = 0;
URL url = new URL(urlPath);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
InputStream inStream = conn.getInputStream();
while ((len = inStream.read(data)) != -1) {
outStream.write(data, 0, len);
}
inStream.close();
return outStream.toByteArray();
} /**
* 描述:获得模块列表,解析出层级目录
* */
public static List<MenuTree> getAllFolders() {
List<MenuTree> list = new ArrayList<MenuTree>();
try {
byte[] data = readParse("http://192.168.0.205:8080/Jack_wiki/menu!searchAllFolders.action");
String str = new String(data); System.out.println("str = " + str); JSONArray jsonArray = new JSONArray(str);
list = parseJsonArray("", 0, jsonArray); } catch (JSONException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return list;
} public static List<MenuTree> parseJsonArray(String parentId, int level, JSONArray jsonArray) throws JSONException {
List<MenuTree> list = new ArrayList<MenuTree>();
for (int j = 0; j < jsonArray.length(); j++) { JSONObject item = jsonArray.getJSONObject(j);
String id = item.optString("id");
String text = item.optString("text");
JSONArray children = item.getJSONArray("children");
if (children != null && children.length() > 0) {
MenuTree tree = new MenuTree(id, text, parentId, true, level);
List<MenuTree> childList = parseJsonArray(id, level + 1, children);
list.add(tree);
list.addAll(childList);
} else {
MenuTree tree = new MenuTree(id, text, parentId, false, level);
list.add(tree);
}
}
return list;
} }

显示目录树

package com.gao.tree;

import java.util.ArrayList;
import java.util.List; import android.app.ListActivity;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast; public class TreeView extends ListActivity {
private TreeViewAdapter treeViewAdapter = null;
/** 当前所显示的目录列表 */
private List<MenuTree> menuTreeShowList = new ArrayList<MenuTree>();
/** 所有的目录列表 */
private List<MenuTree> menutreeList = new ArrayList<MenuTree>(); @Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); menutreeList = (ArrayList<MenuTree>) GetData.getAllFolders(); for (MenuTree tree : menutreeList) {
// 添加最顶层目录
if (tree.getParentId() == null || "".equals(tree.getParentId())) {
menuTreeShowList.add(tree);
}
} treeViewAdapter = new TreeViewAdapter(this, R.layout.outline, menuTreeShowList);
setListAdapter(treeViewAdapter);
registerForContextMenu(getListView());
} private class TreeViewAdapter extends ArrayAdapter {
private LayoutInflater mInflater;
private List<MenuTree> mfilelist; public TreeViewAdapter(Context context, int textViewResourceId, List list) {
super(context, textViewResourceId, list);
mInflater = LayoutInflater.from(context);
mfilelist = list;
} public int getCount() {
return mfilelist.size();
} public Object getItem(int position) {
return position;
} public long getItemId(int position) {
return position;
} public View getView(int position, View convertView, ViewGroup parent) {
TextView text;
ImageView icon;
RelativeLayout rl_menu;
if (convertView == null) {
convertView = mInflater.inflate(R.layout.outline, null);
}
text = (TextView) convertView.findViewById(R.id.text);
icon = (ImageView) convertView.findViewById(R.id.icon);
rl_menu = (RelativeLayout) convertView.findViewById(R.id.rl_menu); MenuTree mt = mfilelist.get(position);
int level = mt.getLevel(); rl_menu.setPadding(25 * level + 15, icon.getPaddingTop(), 0, icon.getPaddingBottom());
text.setText(mt.getText());
if (mt.isHasChild()) {
if (mt.isExpanded()) {
icon.setImageResource(R.drawable.outline_list_expand);
} else {
icon.setImageResource(R.drawable.outline_list_collapse);
}
} else if (!mt.isHasChild()) {
icon.setImageResource(R.drawable.no_child);
}
return convertView;
}
} @Override
protected void onListItemClick(ListView l, View v, int position, long id) {
super.onListItemClick(l, v, position, id);
if (!menutreeList.get(position).isHasChild()) {// 没有子节点
Toast.makeText(this, menutreeList.get(position).getText(), Toast.LENGTH_LONG).show();
return;
} else if (menuTreeShowList.get(position).isExpanded()) {// 展开状态,点击关闭
menuTreeShowList.get(position).setExpanded(false);
MenuTree tree = menuTreeShowList.get(position); List<MenuTree> temp = new ArrayList<MenuTree>(); for (int i = position + 1; i < menuTreeShowList.size(); i++) {
if (tree.getLevel() >= menuTreeShowList.get(i).getLevel()) {
break;
}
temp.add(menuTreeShowList.get(i));
} menuTreeShowList.removeAll(temp); treeViewAdapter.notifyDataSetChanged();
} else {// 关闭状态,点击打开
menuTreeShowList.get(position).setExpanded(true); int j = 1;
for (MenuTree mt : menutreeList) {
if (mt.getParentId().equals(menuTreeShowList.get(position).getId())) {
menuTreeShowList.add(position + j, mt);
j++;
}
}
treeViewAdapter.notifyDataSetChanged();
}
}
}

布局文件  ouyline.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/rl_menu"
android:layout_width="wrap_content"
android:layout_height="40dp"
android:gravity="center_vertical"
android:orientation="horizontal" > <ImageView
android:id="@+id/icon"
android:layout_width="25dp"
android:layout_height="25dp"
android:layout_centerVertical="true"
android:scaleType="centerInside"
android:background="@android:color/transparent"
android:src="@drawable/outline_list_collapse" /> <TextView
android:id="@+id/text"
android:layout_width="wrap_content"
android:layout_height="40dp"
android:layout_toRightOf="@id/icon"
android:gravity="center_vertical"
android:layout_marginLeft="5dp"
android:singleLine="true"
android:text="text"
android:textSize="20sp"
android:textColor="#ffffff" /> </RelativeLayout>

最终显示结果,在该实例中,目录树的层级数是可以任意添加的

Android多级目录树的更多相关文章

  1. Java生成菜单树(目录树)的几种方式

    本文介绍两种不同生成多级目录树的方式:1. 递归生成,2.  map+list 集合生成.最下方会附上完整代码. 生成树的基本规则:子节点的par_id等于父节点的id. 1. 实体类 import ...

  2. Android原生PDF功能实现:PDF阅读、PDF页面跳转、PDF手势伸缩、PDF目录树、PDF预览缩略图

    1.背景 近期,公司希望实现安卓原生端的PDF功能,要求:高效.实用. 经过两天的调研.编码,实现了一个简单Demo,如上图所示. 关于安卓原生端的PDF功能实现,技术点还是很多的,为了咱们安卓开发的 ...

  3. Android UI目录

    Android UI目录 序:最近一直想进阶android应用开发,虽然对一些相关的android知识都大体熟悉,但是自己的android知识体系,经不起推敲.经不起高手的垂问.经过几个月的努力学习, ...

  4. 更快实现Android多级树形选择列表

    快速实现Android多级树形列表,这个库是在鸿洋多级树形列表demo中修改而来. 解决的问题: 1. 支持ID为int类型和String类型. 2. 支持多级复选框选中,使用只需一行代码. 3. 支 ...

  5. MVC图片上传详解 IIS (安装SSL证书后) 实现 HTTP 自动跳转到 HTTPS C#中Enum用法小结 表达式目录树 “村长”教你测试用例 引用provinces.js的三级联动

    MVC图片上传详解   MVC图片上传--控制器方法 新建一个控制器命名为File,定义一个Img方法 [HttpPost]public ActionResult Img(HttpPostedFile ...

  6. 【.net 深呼吸】将目录树转化为文本

    大伙都知道,文件系统是树形结构的,有时候我们会想到把目录的层次结构变为纯文本形式,就像这样: ├─Windows-universal-samples-master │ ├─Samples │ │ ├─ ...

  7. python 小程序 复制目录树

    1. 将一个目录树完全复制到另外一个目录下面 import os, sys """ 复制目录树 """ maxloadsize = 1024 ...

  8. Windows Azure Storage (22) Azure Storage如何支持多级目录

    <Windows Azure Platform 系列文章目录> 熟悉Azure平台的读者都知道,Azure Blob有三层架构.如下图:(注意blob.core.chinacloudapi ...

  9. php使用递归创建多级目录

    <?php header('Content-type:text/html;charset=utf8'); echo "Loading time:".date('Y-m-d H ...

随机推荐

  1. CSS 之自定义滚动条样式

    ::-webkit-scrollbar {/*滚动条整体样式*/ width: 5px; /*高宽分别对应横竖滚动条的尺寸*/ height: 1px; } ::-webkit-scrollbar-t ...

  2. css的基础知识1

    总结:css引用:1内联:在标签中加style属性,<标签名 style="样式1:样式值1:样式2:样式值2"> </标签名>.2.内嵌:在head标签中 ...

  3. CF17E Palisection (回文自动机+DP)

    题目传送门 题目大意:给你一个字符串,让你求出有多少对相交的回文子串 啊啊啊啊降智了,我怎么又忘了正难则反! 求相交会很难搞.把问题转化成求互不相交的回文子串再减一下就行了 先利用$PAM$求出以每个 ...

  4. BZOJ 1631 Usaco 2007 Feb. Cow Party

    [题解] 最短路裸题.. 本题要求出每个点到终点走最短路来回的距离,因此我们先跑一遍最短路得出每个点到终点的最短距离,然后把边反向再跑一遍最短路,两次结果之和即是答案. #include<cst ...

  5. Marshal.ReleaseComObject() vs. Marshal.FinalReleaseComObject()

    很简单,不翻译了. If you are using COM components on your .NET code, you might be already aware of the Marsh ...

  6. 公钥基本结构(PKI)的概念

    公钥证书 ,通常简称为证书 ,用于在 Internet.Extranet 和 Intranet 上进行身份验证并确保数据交换的安全.证书的颁发者和签署者就是众所周知的 证书颁发机构 (CA),将在下一 ...

  7. poj 1273最大流dinic算法模板

    #include<stdio.h> #include<string.h> #define N 300 #define inf 0x7fffffff #include<qu ...

  8. 接水问题(2010年NOIP全国联赛普及组)

    时间限制: 1 s    空间限制: 128000 KB 题目描述 Description 学校里有一个水房,水房里一共装有m 个龙头可供同学们打开水,每个龙头每秒钟的供水量相等,均为1. 现在有n ...

  9. Jquery书写ajax

    根据API学习本章 Jquery书写ajax 使用ajax发送表单到servlet,发送时显示等待图片,servlet处理完返回信息,在页面显示返回信息,并且隐藏等待图片 <%@ page la ...

  10. 造成segment fault,产生core dump的可能原因

    1.内存访问越界 a) 由于使用错误的下标,导致数组访问越界 b) 搜索字符串时,依靠字符串结束符来判断字符串是否结束,但是字符串没有正常的使用结束符 c) 使用strcpy, strcat, spr ...