在Android上实现树形控件

  在PC上我们已经习惯了树形控件,因为其可以清晰的展现各个节点之间的层次结果,但是在Android平台上,系统并没有提供这样一个控件,而是只有ListView。不过通过改写改写与ListView绑定的Adapter可以实现这样一个效果。

  一个ListView需要和一个Adapter绑定,用于管理数据。在这里以BaseAdapter为例,继承Adapter需要重写四个函数,其中较为重要的是两个:

   1 public int getCount();//该函数返回ListView 的ListItem的条数

   2 public View getView(int position, View view, ViewGroup arg2)//负责绘制每一个item。如果getCount()返回10,那么getView()就会被调用10次。

首先开发自己的数据结构:

package bupt.liyazhou.ui;

import java.util.ArrayList;
import java.util.List;

/*
 * @ author:liyazhou
 * @date:2013.4.29
 * @description:Node类用来在UI层中存储一个节点的信息
 *
 */
public class Node {
	private Node parent=null;//父节点
	private List<Node> children=null;
	private String oid=null;//该节点的oid
	private String name=null;//该节点信息的描述
	private String value=null;//该节点的值
	private boolean isLeaf=false;//是否为叶节点
	private boolean isExpanded=false;//该节点是否展开
	private int icon=-1;//该节点的图标对应的id
	private int iconForExpandedOrFolded=-1;
	private int iconForExpanding=-1;
	private int iconForFolding=-1;
	private boolean tableItemOrNot=false;//表示是否为表结构的一列

	public Node(Node parent,String oid,String description,boolean isLeaf,int icon,int exIcon,int foIcon)
	{
		this.parent=parent;
		this.oid=oid;
		this.name=description;
		this.isLeaf=isLeaf;
		this.icon=icon;
		this.iconForExpanding=exIcon;
		this.iconForFolding=foIcon;
	}
	public void setTableItemOrNot(boolean tableItemOrNot)
	{
		this.tableItemOrNot=tableItemOrNot;
	}
	public boolean getTableItemOrNot()
	{
		return this.tableItemOrNot;
	}
	//设置value
	public void setValue(String value)
	{
		this.value=value;
	}
	//得到value
	public String getValue()
	{
		return this.value;
	}
	//设置图标
	public void setIcon(int icon)
	{
		this.icon=icon;
	}
	public int getIcon()
	{
		return this.icon;
	}
	//得到description
	public String getDescription()
	{
		return this.name;
	}
	//得到oid
	public String getOid()
	{
		return this.oid;
	}
	//得到是否为叶节点
	public boolean isLeafOrNot()
	{
		return this.isLeaf;
	}
	//得到当前节点所在的层数,根为0层
	public int getLevel()
	{
		return parent==null?0:parent.getLevel()+1;
	}
	//设置是否展开
	public void setExpanded(boolean isExpanded)
	{
		this.isExpanded=isExpanded;
	}
	public boolean getExpanded()
	{
		return this.isExpanded;
	}
	//添加子节点
	public void addChildNode(Node child)
	{
		if(this.children==null)
		{
			this.children=new ArrayList<Node>();
		}
		this.children.add(child);
	}
	//清空子节点
	public void clearChildren()
	{
		if(!this.children.equals(null))
		{
			this.children.clear();
		}
	}
	//是否为根节点
	public boolean isRoot()
	{
		return this.parent.equals(null)?true:false;
	}
    //设置展开图标
	public void setExpandIcon(int expand)
	{
		this.iconForExpanding=expand;
	}
	//设置折叠图标
	public void setFoldIcon(int fold)
	{
		this.iconForFolding=fold;
	}
	//得到展开或折叠图标
	public int getExpandOrFoldIcon()
	{
		if(this.isExpanded==true)
			return this.iconForExpanding;
		else
			return this.iconForFolding;
	}
	//得到子树
	public List<Node> getChildren()
	{
		return this.children;
	}
}

然后写自己的Adapter

package bupt.liyazhou.ui;

import java.util.ArrayList;
import java.util.List;

import android.R;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

public class MibTreeListAdapter extends BaseAdapter {
	private Context context=null;
	private List<Node> nodeList=new ArrayList<Node> ();//所有的节点
	private List<Node> nodeListToShow=new ArrayList<Node>();//要展现的节点
    private LayoutInflater inflater=null;
    private Node root=null;

    public MibTreeListAdapter(Context con,Node Root,int layout)
    {
    	this.context=con;
    	this.inflater=(LayoutInflater)con.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    	establishNodeList(Root);
    	this.root=Root;
    	setNodeListToShow();
    }
    public void establishNodeList(Node node)
    {
    	nodeList.add(node);
    	if(node.isLeafOrNot())
    		return;
    	List<Node> children=node.getChildren();
    	for(int i=0;i<children.size();i++)
    	{
    		establishNodeList(children.get(i));
    	}
    }
    public void setNodeListToShow()
    {
    	this.nodeListToShow.clear();
    	establishNodeListToShow(this.root);
    }

    //构造要展示在listview的nodeListToShow
    public void establishNodeListToShow(Node node)
    {
    	this.nodeListToShow.add(node);
    	if(node.getExpanded()&&!node.isLeafOrNot()&&node.getChildren()!=null)
    	{
    		List<Node> children=node.getChildren();
    		for(int i=0;i<children.size();i++)
    		{
    			establishNodeListToShow(children.get(i));
    		}
    	}
    }

    //根据oid得到某一个Node,并更改其状态
    public void changeNodeExpandOrFold(int position)
    {
    	String oid=this.nodeListToShow.get(position).getOid();
    	for(int i=0;i<this.nodeList.size();i++)
    	{
    		if(nodeList.get(i).getOid().equals(oid))
    		{
    			boolean flag=nodeList.get(i).getExpanded();
    			nodeList.get(i).setExpanded(!flag);
    		}

    	}
    }

    //listItem被点击的响应事件
    public Node OnListItemClick(int position)
    {
    	Node node=this.nodeListToShow.get(position);
    	if(node.isLeafOrNot())
    	{
    		//处理snmp代码
    		Toast.makeText(this.context, "该节点为子节点", Toast.LENGTH_SHORT).show();
    		return node;
    	}
    	else
    	{
    		this.changeNodeExpandOrFold(position);
    		this.setNodeListToShow();
    		this.notifyDataSetChanged();
    		return null;
    	}
    }
	public int getCount() {
		// TODO Auto-generated method stub
		return nodeListToShow.size();
	}

	public Object getItem(int arg0) {
		// TODO Auto-generated method stub
		return nodeListToShow.get(arg0);
	}

	public long getItemId(int arg0) {
		// TODO Auto-generated method stub
		return arg0;
	}

	public View getView(int position, View view, ViewGroup parent) {
		// TODO Auto-generated method stub
		Holder holder=null;
		if(view!=null)
		{
			holder=(Holder)view.getTag();
		}
		else
		{
			holder=new Holder();
			view=this.inflater.inflate(bupt.liyazhou.R.layout.listview_item, null);
			holder.description=(TextView)view.findViewById(bupt.liyazhou.R.id.textview_nodeDescription);
			holder.nodeIcon=(ImageView)view.findViewById(bupt.liyazhou.R.id.imageview_nodeImage);
			holder.expandOrFoldIcon=(ImageView)view.findViewById(bupt.liyazhou.R.id.imageview_expandedImage);
			view.setTag(holder);
		}

		//绘制一个item

		//设置文字
		Node node= this.nodeListToShow.get(position);
		holder.description.setText(node.getDescription());

		//设置图标
		int icon=node.getIcon();
		if(icon!=-1)
		{
			holder.nodeIcon.setImageResource(icon);
			holder.nodeIcon.setVisibility(View.VISIBLE);
		}
		else
			holder.nodeIcon.setVisibility(View.INVISIBLE);

		//设置展开折叠图标
		if(!node.isLeafOrNot())
		{
		  int expandIcon=node.getExpandOrFoldIcon();
		  if(expandIcon==-1)
			  holder.expandOrFoldIcon.setVisibility(View.INVISIBLE);
		  else
		  {
			  holder.expandOrFoldIcon.setImageResource(expandIcon);
			  holder.expandOrFoldIcon.setVisibility(View.VISIBLE);
		  }

		}
		else
		{
			holder.expandOrFoldIcon.setVisibility(View.INVISIBLE);
		}
		view.setPadding(node.getLevel()*35, 10, 10, 10);
		return view;
	}

	public class Holder
	{
		TextView description;
		ImageView nodeIcon;
		ImageView expandOrFoldIcon;
	}

}

listview_item.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
    <ImageView
       android:id="@+id/imageview_nodeImage"
       android:layout_height="fill_parent"
       android:layout_width="wrap_content"
       android:layout_alignParentLeft="true"
       android:paddingRight="10dp"/>
    <TextView
        android:id="@+id/textview_nodeDescription"
        android:layout_height="fill_parent"
        android:layout_width="wrap_content"
        android:layout_toRightOf="@id/imageview_nodeImage"
        />
    <ImageView
        android:id="@+id/imageview_expandedImage"
        android:layout_height="fill_parent"
        android:layout_width="wrap_content"
        android:layout_alignParentRight="true"/>

</RelativeLayout>

实现效果:

时间: 2024-07-30 19:53:42

在Android上实现树形控件的相关文章

Android树形控件绘制方法

前言 作为一个开发者,日常会接触到很多优秀的软件,其实,或多或少会有这样的想法,我能不能开发一个自己软件,甚至办公软件都希望是Markdown的文本,为何用office?我常常想自己做一个IDE什么的.但是,很多只是想了一下就过了,一直没有实现. 我接触思维导图软件已经很久的了,开始是使用微软的思维导图软件,接着XMind,后来使用了MindMaple Lite.感觉很好用的.也想过如何去实现一个思维导图的软件,加之我特别注意软件的快捷键,我选取软件常常是,看快捷如何,快捷键差的就不要了.基于自

Android树形控件的实现方法

在PC上我们已经习惯了树形控件,因为其可以清晰的展现各个节点之间的层次结果,但是在Android平台上,系统并没有提供这样一个控件,而是只有ListView.不过通过改写与ListView绑定的Adapter可以实现这样一个效果. 一个ListView需要和一个Adapter绑定,用于管理数据.在这里以BaseAdapter为例,继承Adapter需要重写四个函数,其中较为重要的是两个:    1 public int getCount()://该函数返回ListView 的ListItem的条

Android怎么在一个View控件上画动态扫描效果?

问题描述 Android怎么在一个View控件上画动态扫描效果? 怎么在一个View上画动态扫描效果?例如在一张图片上画一个左右扫描这张图片的效果? 解决方案 背景图片和前景图片运用相结合,前景图片运用旋转动画

JavaScript面向对象技术实现树形控件

javascript|对象|控件 树形控件是一种人们熟悉的用户界面控件,广泛地用来显示层次型数据. 树形控件具有独特的扩展和折叠分支的能力,能够以较小的空间显示出大量的信息,一目了然地传达出数据之间的层次关系.凡是熟悉图形用户界面的用户,都能够自如地运用树形控件. 图一:用JavaScript实现的树形控件 HTML本身不支持树形控件,但我们可以通过一些JavaScript脚本代码实现.为了提高控件的可重用性,我们要充分运用JavaScript对面向对象编程技术的支持.本文的树形控件适用于IE

教你如何使用JSP面向对象web编程技术实现树形控件

js|web|编程|对象|控件 树形控件是一种人们熟悉的用户界面控件,广泛地用来显示层次型数据. 树形控件具有独特的扩展和折叠分支的能力,能够以较小的空间显示出大量的信息,一目了然地传达出数据之间的层次关系.凡是熟悉图形用户界面的用户,都能够自如地运用树形控件. 图一:用java script实现的树形控件 HTML本身不支持树形控件,但我们可以通过一些java script脚本代码实现.为了提高控件的可重用性,我们要充分运用java script对面向对象编程技术的支持.本文的树形控件适用于I

Android ExpandableListView展开列表控件使用实例_Android

你是否觉得手机QQ上的好友列表那个控件非常棒? 不是..... 那也没关系,学多一点知识对自己也有益无害. 那么我们就开始吧. 展开型列表控件, 原名ExpandableListView 是普通的列表控件进阶版, 可以自由的把列表进行收缩, 非常的方便兼好看. 首先看看我完成的截图, 虽然界面不漂亮, 但大家可以自己去修改界面. 该控件需要一个主界面XML 一个标题界面XML及一个列表内容界面XML 首先我们来看看 mian.xml 主界面 复制代码 代码如下: //该界面非常简单, 只要一个E

Android自定义控件之组合控件学习笔记分享_Android

我们来讲一下自定义组合控件,相信大家也接触过自定义组合控件吧,话不多说,直接干(哈~哈~): 大家看到这个觉得这不是很简单的吗,这不就是写个布局文件就搞定嘛,没错,确实直接上布局就行,不过,我只是用这个简单的例子来讲一下自定义组合控件的用法. 首先看看,这一行行的条目看起来都长得差不多,只是图片和文字不一样,没错,就是看中这一点,我们可以把一个条目做成一个组合控件,做为一个整体,这样不管你有几个条目,就写几个组合控件就行了. 步骤: 1.先建立组合控件的布局 myView.xml <Relati

Android编程实现改变控件背景及形态的方法_Android

本文实例讲述了Android编程实现改变控件背景及形态的方法.分享给大家供大家参考,具体如下: 1. 改变背景 在res/drawable下创建一个xml文件: <?xml version="1.0" encoding="UTF-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> // 控件被按下时候的背景 <item

MFC 树形控件CTreeCtrl显示文件路径及文件

在上篇文章中简单讲述了"MFC单文档分割窗口显示图片",但是我想实现的是左边显示图片的路径,右边显示图片的情况,所以这里需要讲述如何使用控件List Control和Tree Control.    CListCtrl(列表控件):可以用大图标.小图标.列表.报表四种不同方式显示一组信息.    CTreeCtrl(树形控件):用树结构显示一组信息,并能反映这些信息的层次关系.首先声明:该文章主要是数字图形处理知识并结合liujiannan_1987的上传资源讲述,在此感谢该作者:ht