利用ListView做多级菜单

来源:互联网 发布:知乎怎么赚钱的 编辑:程序博客网 时间:2024/06/05 15:31

在开发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; // 子节点 级数 = 父节点级数+1int temp = position;//临时位置// 循环 得到 此父节点的所有子节点for (TreeNode element : obj.getChildren()) {element.setLevel(nextLevel);element.setExpanded(false);temp = temp+1;nodes.add(temp, element);}// 将已变化的nodes列表 刷新treeViewAdapter.notifyDataSetChanged();}}});    }}