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-08-27 14:33:23

Android树形控件的实现方法的相关文章

Android树形控件绘制方法

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

Android重要控件SnackBar使用方法详解_Android

SnackBar是DesignSupportLibrary中的一个重要的控件,用于在界面下面提示一些关键信息,跟Toast不同的地方是SnackBar允许用户向右滑动消除它,同时,也允许在SnackBar中设定一个Action,当用户点击了SnackBar里面的按钮的时候,可以进行一些操作,所以,功能绝对是很强大的.  SnackBar的构造:  // 参数分别是父容器,提示信息,持续时间public static Snackbar make(@NonNull View view, @NonNu

Android重要控件SnackBar使用方法详解

SnackBar是DesignSupportLibrary中的一个重要的控件,用于在界面下面提示一些关键信息,跟Toast不同的地方是SnackBar允许用户向右滑动消除它,同时,也允许在SnackBar中设定一个Action,当用户点击了SnackBar里面的按钮的时候,可以进行一些操作,所以,功能绝对是很强大的. SnackBar的构造: // 参数分别是父容器,提示信息,持续时间public static Snackbar make(@NonNull View view, @NonNull

Android设置控件阴影的三种方法

本文实例为大家分享了Android设置控件阴影的方法,供大家参考,具体内容如下 第一种方式:elevation View的大小位置都是通过x,y确定的,而现在有了z轴的概念,而这个z值就是View的高度(elevation),而高度决定了阴影(shadow)的大小. View Elevation(视图高度) View的z值由两部分组成,elevation和translationZ(它们都是Android L新引入的属性). eleavation是静态的成员,translationZ是用来做动画.

Android常见控件使用详解

本文实例为大家分享了六种Android常见控件的使用方法,供大家参考,具体内容如下 1.TextView 主要用于界面上显示一段文本信息 2.Button 用于和用户交互的一个按钮控件 //为Button点击事件注册一个监听器 public class Click extends Activity{ private Button button; @Override ptotected void onCreate(Bundle savedInstanceState) { super.onCreat

Android TextView控件文字添加下划线的实现方法_Android

如下所示: TextView tv = (TextView) findViewById(R.id.text); tv.getPaint().setFlags(Paint.UNDERLINE_TEXT_FLAG); tv.setText("添加下划线"); 以上就是小编为大家带来的Android TextView控件文字添加下划线的实现方法的全部内容了,希望对大家有所帮助,多多支持~ 以上是小编为您精心准备的的内容,在的博客.问答.公众号.人物.课程等栏目也有的相关内容,欢迎继续使用右上

Android仿英语流利说取词放大控件的实现方法(附demo源码下载)_Android

本文实例讲述了Android仿英语流利说取词放大控件的实现方法.分享给大家供大家参考,具体如下: 1 取词放大控件 英语流利说是一款非常帮的口语学习app,在app的修炼页面长按屏幕,会弹出一个放大镜,当手指移到某个单词的附近,可以看到该英文单词会被选中,效果如下图所示: 2 代码示例 该控件挺有意思,于是我写了个简单的demo,完整实例代码点击此处本站下载.,程序运行后的效果如下: 3 实现原理 该控件的实现原理比较简单,下面介绍几个比较重要的类 ① WordView 在实习该控件的过程中,我

Android自带倒计时控件Chronometer使用方法详解_Android

公司的以前的项目,看到使用了这个Android自带的倒计时控件Chronometer,现在整合了一下 先看看效果: <Chronometer android:id="@+id/chronometer" android:layout_width="wrap_content" android:layout_height="30dp" /> <Button android:onClick="start" andro

Android基础控件(EditView、SeekBar等)的使用方法_Android

 android提供了大量的UI控件,本文将介绍TextView.ImageView.Button.EditView.ProgressBar.SeekBar.ScrollView.WebView的使用方法.在介绍各种控件之前,先简单介绍android UI控件最基本的几种属性: id: id是控件唯一标识符,可通过**findViewById(R.id.*)**操作控件. layout_width:控件宽度,可设置为match_parent(充满父布局,即让父布局决定当前控件的宽度).wrap_