利用ListView做多级菜单


在开发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();
				}
			}
		});
    }
}
时间: 2024-10-03 10:00:28

利用ListView做多级菜单的相关文章

extjs desktop 多级菜单的快捷方式问题

问题描述 用的事ext2.0下面的desktop,在做多级菜单的快捷方式的时候遇到一个问题,开始菜单式动态拼出来的,官方例子中只有一级的快捷方式,修改了一下Desktop.js shortcuts.on('click', function(e, t){ if(t = e.getTarget('dt', shortcuts)){ e.stopEvent(); var module = app.getModule(t.id.replace('-shortcut', '')); if(module){

如何利用html做一个具有二级菜单的导航框

问题描述 如何利用html做一个具有二级菜单的导航框 我学习了html的基础知识,不知道怎么样才能做一个具有二级菜单的导航框,求各位大神指点, 解决方案 这个不难实现,使用列表和css就能实现.实例代码: http://www.oschina.net/code/snippet_2274992_44265 解决方案二: css菜单 13个不错的Javascript和CSS的菜单 解决方案三: 可以参考: http://www.jq22.com/jquery-plugins%E6%89%8B%E9%

怎么截取多级菜单

  我们可以用两种方法解决.一是使用能够直接一键抓取各级菜单的工具来实现(需进行相应的设置),比如Snagit软件;二是利用普通抓取法进行全区域抓取,而后用修图软件对无关区域进行裁剪处理.就是利用画图工具剪切. 怎么截取多级菜单 多级菜单截取技巧 方法一:使用Snagit软件一键抓取各级菜单 如果我们使用Snagit抓图软件,在系统托盘该软件图标上点击鼠标右键,选择"捕获类型"为"菜单".这样,之后遇到需要抓取多级菜单时,只需逐级打开菜单,然后按下该软件的抓图快捷键

builder如何利用treeview做文件列表

问题描述 builder如何利用treeview做文件列表 就是要做出类似windows管理器的树列表,该怎么做呢,用treeview做,但是怎么在treeview里显示文件列表,求各位大神 解决方案 资源管理器左边区域显示目录的是treeview,而右边显示文件和目录的是ListView,是两个不同的控件 解决方案二: 资源管理器左边区域显示目录的是treeview,而右边显示文件和目录的是ListView,是两个不同的控件 解决方案三: // 完美解决方案void __fastcall TF

treeview xml iframe-treeview读取xml做导航菜单不能跳转到mainframe框架中去

问题描述 treeview读取xml做导航菜单不能跳转到mainframe框架中去 index.aspx页 tree.aspx页 /asp:TreeView tree.aspx.cs protected void Page_Load(object sender, EventArgs e) { string path = @"e:s2tree.xml"; if (!IsPostBack) { InitialTreeView(this.TreeView1.Nodes, path); } }

excel中如何利用公式做求和算法?

  excel中如何利用公式做求和算法?          步骤 1.隔列求和 H3=SUMIF($A$2:$G$2,H$2,A3:G3); 2.单条件求和 F2=SUMIF(A:A,E2,C:C) 3.单条件模糊求和 公式: SUMIF(A2:A4,"*A*",C2:C4) 4.多条件模糊求和 公式:C11=SUMIFS(C2:C7,A2:A7,A11&"*",B2:B7,B11); 5.多表相同位置求和 公式:b2=SUM(Sheet1:Sheet19!

用 Fireworks 做雅虎菜单

菜单|雅虎 最近,这种菜单好象很流行,不少网站都有了,这个菜单可以节约有限的空间,很有价值,经常设计中要用到,今天有Fireworks 的初学者,来问怎么做这种菜单,所以顺手做了一下,其实这样的菜单不复杂,无非是渐变的填充,用 fireworks 强大的交互式填充工具来制作,那简直是手到擒来.另外矢量化修改,也很方便,所以 fireworks 非常适合 web 设计创作. 第一步,做底条,注意边框颜色和渐变设置 第二步.做菜单条.其实就是复制一下底条,调整长宽和填充. 第三步.做菜单条的突出效果

浅谈自己利用论坛做外链的一些心得

论坛做外链相信很多站长都使用过,对于论坛的热爱因为其免费并且可以有效的增加网站外链,像一些权重比较高的论坛,通过发贴一分钟就被收录了,从而可以快速的增加网站反链.但是很多的论坛都会对于发推广广告进行严格的管理.致使很多时候站长辛苦推广最终遭到封号,那么之前做的外链通通都成了无效链接,也就是外链忽上忽下的原因之一.今天笔者分享一些在论坛做外链不被封号的方法: 首先注册帐号.每个论坛想发贴都必须拥有论坛帐号,而注册帐号时,一般不要让论坛管理员从帐号就发现是来推广广告的.帐号名最好使用一些非主流的,原

企业利用搜索引擎做品牌宣传的好处

近年来,企业利用互联网做品牌宣传的例子屡见不鲜,这说明越来越多的企业意识到了网络营销推广的重要性,从过去的资金比拼转化为现在的品牌.形象上下功夫,这说明品质在用户心目中的地位也越来越重要.许多企业家都觉得,利用互联网作为平台,做企业品牌宣传是企业家迫在眉睫的事,毕竟,互联网上的绝大部分人群是利用搜索引擎来寻找自己需求的物品,而一直以来品质一直是阻碍互联网购物潮发展的最大因素,商家的信用反而是其次,毕竟有中介.那么,面对如此大的商机,企业家又该如何跨越这一道防线走向人群,走向富饶呢?在这里,SEO