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>

实现效果:

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Android提高之多级树形菜单的实现方法

    一般来说在Android里要实现树形菜单,都是用ExpandableList(也有高手自己继承ListView或者LinearLayout来做),但是ExpandableList一般只能实现2级树形菜单.本文所述实例也依然使用ExpandableList,但是要实现的是3级树形菜单. 本文程序运行效果图如下图所示: 当用BaseExpandableListAdapter来实现二级树形菜单时,父项(getGroupView())和子项(getChildView())都是使用TextView.当要实

  • 选择TreeView控件的树状数据节点的JS方法(jquery)

    方法要达到的效果是:" 改变一节点的选中状态时,其后代节点选中状态也要跟随当前节点的选中状态改变而改变.当前节点选中时,其所有祖先节点也要跟着选中;如取消时,要根据其同级节点是否有选中时,来决定其祖先节点的选中状态." 说明:树是用vs的TreeView控件生成的. 如图: 代码如下: 复制代码 代码如下: jQuery(function(){ jQuery(":checkbox").click(function(){ var objNode = this; var

  • Android实现树形层级ListView

    直接贴代码,代码中有相应注释: 主界面Activity,布局就只一个ListView: public class MainActivity extends Activity { private ListView mListView; private TreeListViewAdapter<TestBean> mAdapter; private List<TestBean> mDatas = new ArrayList<TestBean>(); @Override pro

  • js树形控件脚本代码

    /*---------------------------------------------------------------------------*\ |  Subject: JavaScript Framework |  Author:  meizz |  Created: 2005-02-27 |  Version: 2006-08-11 |----------------------------------- |  MSN:huangfr@msn.com  QQ:112889082

  • 详解js树形控件—zTree使用总结

    0 zTree简介 树形控件的使用是应用开发过程中必不可少的.zTree 是一个依靠 jQuery 实现的多功能 "树插件".优异的性能.灵活的配置.多种功能的组合是 zTree 最大优点. 0.0 zTree的特点 最新版的zTree将核心代码按照功能进行了分割,不需要的代码可以不用加载,如普通使用只需要加载核心的jquery.ztree.core-3.5.js,需要使用勾选功能加载jquery.ztree.excheck-3.5.min.js,需要使用编辑功能加载jquery.zt

  • Android多级树形列表控件

    我们开发app过程中,经常会碰到需要 多级列表展示的效果.而Android原生sdk中根本没有3级 4级甚至更多级别的列表控件. 所以我们就要自己去实现一个类似treeListView 的控件,下面这个是我项目中的一个效果图,可支持多级列表扩展. android中有ExpandListView控件,但是这个控件只支持两级列表.对于多级列表如果重写这个不是很好用. 实现这种列表 思想就是递归,构造一个子父级的关系. 话不多说 代码中体会 Activity package com.example.c

  • Bootstrap树形控件使用方法详解

    一.JQuery树形控件 Jquery树形控件是一款基于JQuery+bootstrap.完全通过js和样式手写出来的非常轻量级的控件,网上很多地方都能看到它的影子.它功能简单.用户体验不错.对于一些简单的层级关系展示比较实用,但对于节点的增删改实现起来就不容易了,如果非要做,可能需要自己去封装. 1.一睹初容 全部收起 展开一级 全部展开 2.代码示例 此控件实现起来也非常简单,只需要引用jQuery和bootstrap组件即可. <link href="~/Content/Tree1/

  • jQuery树形控件zTree使用小结

    0 zTree简介 树形控件的使用是应用开发过程中必不可少的.zTree 是一个依靠 jQuery 实现的多功能 "树插件".优异的性能.灵活的配置.多种功能的组合是 zTree 最大优点. 0.0 zTree的特点  •最新版的zTree将核心代码按照功能进行了分割,不需要的代码可以不用加载,如普通使用只需要加载核心的jquery.ztree.core-3.5.js,需要使用勾选功能加载jquery.ztree.excheck-3.5.min.js,需要使用编辑功能加载jquery.

  • 基于jQuery的树控件实现代码(asp.net+json)

    语言: asp.net (其实都一样 只要服务器返回json就可以了); 先介绍下: 这个是一个美女大姐问我要的 写好了DEMO准备发给他 总不能独享 就贴出来了 第二次在cnblogs写博.. - - 那个代码有冗余 各位大虾可以自行修改... (失恋了 没心情弄); 压缩包: 里面有3个自己写的插件 1.一个是jQuery 请求webservices的便捷插件 2.一个防ext的mask()加载效果 3.树控件... 关于: /* 本代码只限交流学习使用,勿用于商业用途 系统难免存在bug

  • Android树形控件绘制方法

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

随机推荐