閱讀505 返回首頁    go 人物


在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:andro
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
    <ImageView
       android:
       android:layout_height="fill_parent"
       android:layout_width="wrap_content"
       android:layout_alignParentLeft="true"
       android:paddingRight="10dp"/>
    <TextView 
        android:
        android:layout_height="fill_parent"
        android:layout_width="wrap_content"
        android:layout_toRightOf="@id/imageview_nodeImage"
        />
    <ImageView 
        android:
        android:layout_height="fill_parent"
        android:layout_width="wrap_content"
        android:layout_alignParentRight="true"/>

    

</RelativeLayout>

實現效果:


最後更新:2017-04-03 18:51:52

  上一篇:go 8年苦戀阿裏終棄中國雅虎
  下一篇:go 在Ubuntu下安裝lamp可以采用新立得軟件包管理器來安裝