在Android上实现树形控件
16lz
2021-01-24
在PC上我们已经习惯了树形控件,因为其可以清晰的展现各个节点之间的层次结果,但是在Android平台上,系统并没有提供这样一个控件,而是只有ListView。不过通过改写改写与ListView绑定的Adapter可以实现这样一个效果。
一个ListView需要和一个Adapter绑定,用于管理数据。在这里以BaseAdapter为例,继承Adapter需要重写四个函数,其中较为重要的是两个:
1public int getCount();//该函数返回ListView 的ListItem的条数
2public 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;//该节点的oidprivate String name=null;//该节点信息的描述private String value=null;//该节点的值private boolean isLeaf=false;//是否为叶节点private boolean isExpanded=false;//该节点是否展开private int icon=-1;//该节点的图标对应的idprivate 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;}//设置valuepublic void setValue(String value){this.value=value;}//得到valuepublic String getValue(){return this.value;}//设置图标public void setIcon(int icon){this.icon=icon;}public int getIcon(){return this.icon;}//得到descriptionpublic 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;elsereturn 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 stubreturn nodeListToShow.size();}public Object getItem(int arg0) {// TODO Auto-generated method stubreturn nodeListToShow.get(arg0);}public long getItemId(int arg0) {// TODO Auto-generated method stubreturn arg0;}public View getView(int position, View view, ViewGroup parent) {// TODO Auto-generated method stubHolder 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);}elseholder.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>
实现效果:
更多相关文章
- Android第十九课 attempt to write a readonly database解决
- 这篇文章适合所有Android手机第一次买Android手机的可以看看!(ZT
- android 动态注册 广播
- Android(安卓)Launcher3修改应用图标,隐藏应用图标
- Android实机调试出现“您的手机未安装此应用”
- Android(安卓)Notification
- 详解Android解析Xml的三种方式——DOM、SAX以及XMLpull
- 使用getevent监听Android输入设备文件
- Android布局优化的几种方法