本例中目录树的菜单数据是从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>
最终显示结果,在该实例中,目录树的层级数是可以任意添加的