在开发Android的时候,需要做一个多级的树状菜单,而且级数可能会变化,查阅网上很多材料,受到很大启发,之前网上找过一个,当时完成了功能要求,但存在几个问题,今天重新拿出原来长长的代码,经过增删及自己的理解,终于整理出来啦。
源码资源下载http://download.csdn.net/detail/op_kapu/5815691
大体的思路:点开父亲节点的时候,把子节点添加到listview中,刷新listview
关闭父亲节点的时候,把子节点从listview中删除,刷新listview
先上图:
然后是代码~
TreeNode.java
package com.example.treetest; import java.util.ArrayList; import java.util.List; /** * 树节点对象 * * @author Kapu */ public class TreeNode { private String title; private boolean hasChildren; private int Level; private List<TreeNode> children = new ArrayList<TreeNode>(); private boolean expanded; public void addChild(TreeNode node) { this.hasChildren = true; this.children.add(node); } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public int getLevel() { return Level; } public void setLevel(int level) { Level = level; } public boolean isExpanded() { return expanded; } public void setExpanded(boolean expanded) { this.expanded = expanded; } public boolean hasChildren() { return hasChildren; } public void hasChildren(boolean hasChildren) { this.hasChildren = hasChildren; } public List<TreeNode> getChildren() { return children; } public void setChildren(List<TreeNode> children) { this.hasChildren = true; this.children = children; } }TreeViewAdapter.java
package com.example.treetest; import java.util.List; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.ImageView; import android.widget.TextView; public class TreeViewAdapter extends BaseAdapter { private LayoutInflater mInflater; private List<TreeNode> mfilelist; private Bitmap mIconCollapse; //- , 收缩 private Bitmap mIconExpand; //+ ,展开 public TreeViewAdapter(Context context, List<TreeNode> treeNodes) { super(); mInflater = LayoutInflater.from(context); mfilelist = treeNodes; mIconCollapse = BitmapFactory.decodeResource(context.getResources(), R.drawable.plus); mIconExpand = BitmapFactory.decodeResource(context.getResources(), R.drawable.minus); } 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) { ViewHolder holder; convertView = mInflater.inflate(R.layout.tree_node, null); holder = new ViewHolder(); holder.text = (TextView) convertView.findViewById(R.id.treetext); holder.icon = (ImageView) convertView.findViewById(R.id.icon); convertView.setTag(holder); final TreeNode obj = mfilelist.get(position); int level = obj.getLevel(); holder.icon.setPadding( 15 * (level + 1), holder.icon.getPaddingTop(), 0, holder.icon.getPaddingBottom()); holder.text.setText(obj.getTitle()); if (obj.hasChildren()&& (obj.isExpanded() == false)) { holder.icon.setImageBitmap(mIconCollapse); } else if (obj.hasChildren() && (obj.isExpanded() == true)) { holder.icon.setImageBitmap(mIconExpand); } else if (!obj.hasChildren()) { holder.icon.setImageBitmap(mIconCollapse); holder.icon.setVisibility(View.INVISIBLE); } return convertView; } class ViewHolder { TextView text; ImageView icon; } }MainActivity.java
package com.example.treetest; import java.util.ArrayList; import java.util.List; import android.os.Bundle; import android.view.View; import android.widget.AdapterView; import android.widget.ListView; import android.widget.AdapterView.OnItemClickListener; import android.app.Activity; public class MainActivity extends Activity{ /** 左侧树 */ private List<TreeNode> nodes = new ArrayList<TreeNode>(); private TreeViewAdapter treeViewAdapter = null; /** 目录树数据 */ private ListView dir; /** 当前在左侧目录选中的位置 */ int currentPosition; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); dir = (ListView) findViewById(R.id.dir); //初始化数据 List<TreeNode> treeNodeList = new ArrayList<TreeNode>(); TreeNode tree0 = new TreeNode(); tree0.setLevel(0); tree0.setTitle("第一章"); List<TreeNode> treeNodeList0 = new ArrayList<TreeNode>(); TreeNode tree00 = new TreeNode(); tree00.setLevel(1); tree00.setTitle("第一课"); TreeNode tree01 = new TreeNode(); tree01.setLevel(1); tree01.setTitle("第二课"); List<TreeNode> treeNodeList00 = new ArrayList<TreeNode>(); TreeNode tree000 = new TreeNode(); tree000.setLevel(2); tree000.setTitle("第二课第一节"); TreeNode tree001 = new TreeNode(); tree001.setLevel(2); tree001.setTitle("第二课第二节"); treeNodeList00.add(tree000); treeNodeList00.add(tree001); tree01.setChildren(treeNodeList00); treeNodeList0.add(tree00); treeNodeList0.add(tree01); tree0.setChildren(treeNodeList0); tree0.hasChildren(true); TreeNode tree1 = new TreeNode(); tree1.setLevel(0); tree1.setTitle("第二章"); treeNodeList.add(tree0); treeNodeList.add(tree1); nodes = treeNodeList; dir.setDivider(null); treeViewAdapter = new TreeViewAdapter(this, nodes); dir.setAdapter(treeViewAdapter); dir.setOnItemClickListener(new OnItemClickListener() { public void onItemClick(AdapterView<?> l, View v, int position, long id) { // 此节点下没有子节点,即某一个小节 if (!nodes.get(position).hasChildren()) { return; } // 假如 此父节点下有子节点,且 已展开 关闭的时候删除 if (nodes.get(position).isExpanded()) { nodes.get(position).setExpanded(false); TreeNode element = nodes.get(position); // 先得到该 父节点 ArrayList<TreeNode> temp = new ArrayList<TreeNode>(); // 循环得到 子节点 for (int i = position + 1; i < nodes.size(); i++) { if (element.getLevel() >= nodes.get(i).getLevel()) { break; } temp.add(nodes.get(i)); } nodes.removeAll(temp); treeViewAdapter.notifyDataSetChanged(); } else { // 假如 此父节点未展开,则 展开 展开的时候增加 TreeNode obj = nodes.get(position); obj.setExpanded(true); int level = obj.getLevel(); // 父节点级数 int nextLevel = level + 1; // 子节点 级数 = 父节点级数+1 int temp = position;//临时位置 // 循环 得到 此父节点的所有子节点 for (TreeNode element : obj.getChildren()) { element.setLevel(nextLevel); element.setExpanded(false); temp = temp+1; nodes.add(temp, element); } // 将已变化的nodes列表 刷新 treeViewAdapter.notifyDataSetChanged(); } } }); } }