android 选人 多级树的实现

源码是从网上找的,自己修改了一下,具体作者忘了是谁了  在此说一声抱歉

节点  Node.java

package com.chinaunicom.yczft.tree;

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

public class Node {
    private Node parent;//父节点
    private List<Node> children = new ArrayList<Node>();//子节点
    private String text;//节点显示的文字
    private String value;//节点的值
    private String type;//节点类型
    private int icon = -1;//是否显示小图标,-1表示隐藏图标
    private boolean isChecked = false;//是否处于选中状态
    private boolean isExpanded = true;//是否处于展开状态
    private boolean hasCheckBox = true;//是否拥有复选框
    
    /**
     * Node构造函数
     * @param text 节点显示的文字
     * @param value 节点的值
     */
    public Node(String text,String value,String type){
    	this.text = text;
    	this.value = value;
    	this.type = type;
    }
    
    /**
     * 设置父节点
     * @param node
     */
    public void setParent(Node node){
    	this.parent = node;
    }
    /**
     * 获得父节点
     * @return
     */
    public Node getParent(){
    	return this.parent;
    }
    /**
     * 设置节点文本
     * @param text
     */
    public void setText(String text){
    	this.text = text;
    }
    /**
     * 获得节点文本
     * @return
     */
    public String getText(){
    	return this.text;
    }
    /**
     * 设置节点值
     * @param value
     */
    public void setValue(String value){
    	this.value = value;
    }
    /**
     * 获得节点值
     * @return
     */
    public String getValue(){
    	return this.value;
    }
    /**
     * 获得节点类型
     * @return
     */
    public String getType() {
		return type;
	}
    /**
     * 设置节点类型
     * @param type
     */
	public void setType(String type) {
		this.type = type;
	}

	/**
     * 设置节点图标文件
     * @param icon
     */
    public void setIcon(int icon){
    	this.icon = icon;
    }
    /**
     * 获得图标文件
     * @return
     */
    public int getIcon(){
    	return icon;
    }
    /**
     * 是否根节点
     * @return
     */
    public boolean isRoot(){
    	return parent==null?true:false;
    }
    /**
     * 获得子节点
     * @return
     */
    public List<Node> getChildren(){
    	return this.children;
    }
    /**
     * 添加子节点
     * @param node
     */
    public void add(Node node){
    	if(!children.contains(node)){
    		children.add(node);
    	}
    }
    /**
     * 清除所有子节点
     */
    public void clear(){
    	children.clear();
    }
    /**
     * 删除一个子节点
     * @param node
     */
    public void remove(Node node){
    	if(!children.contains(node)){
    		children.remove(node);
    	}
    }
    /**
     * 删除指定位置的子节点
     * @param location
     */
    public void remove(int location){
    	children.remove(location);
    }
    /**
     * 获得节点的级数,根节点为0
     * @return
     */
    public int getLevel(){
    	return parent==null?0:parent.getLevel()+1;
    }
    /**
     * 设置节点选中状态
     * @param isChecked
     */
    public void setChecked(boolean isChecked){
    	this.isChecked = isChecked;
    	if(parent!=null){
    		List<Node> nodes = new ArrayList<Node>();
    		for(int i=0;i<parent.getChildren().size();i++){
    			Node n = parent.getChildren().get(i);
    			if(n.isChecked()){
    				nodes.add(n);
    			}
    		}
    		if(nodes.size()==parent.getChildren().size()){
    			parent.setChecked(true);
    		}else{
    			parent.setChecked(false);
    		}
    	}
    }
    /**
     * 获得节点选中状态
     * @return
     */
    public boolean isChecked(){
        return isChecked;
    }
    /**
     * 设置是否拥有复选框
     * @param hasCheckBox
     */
    public void setCheckBox(boolean hasCheckBox){
    	this.hasCheckBox = hasCheckBox;
    }
    /**
     * 是否拥有复选框
     * @return
     */
    public boolean hasCheckBox(){
        return hasCheckBox;
    }
    
    /**
     * 是否叶节点,即没有子节点的节点
     * @return
     */
    public boolean isLeaf(){
    	return children.size()<1?true:false;
    }
    /**
    * 当前节点是否处于展开状态 
    * @return
    */
    public boolean isExpanded(){
        return isExpanded;
    }
    /**
     * 设置节点展开状态
     * @return
     */
    public void setExpanded(boolean isExpanded){
    	 this.isExpanded =  isExpanded;
    }
    /**
     * 递归判断父节点是否处于折叠状态,有一个父节点折叠则认为是折叠状态
     * @return
     */
    public boolean isParentCollapsed(){
    	if(parent==null)return !isExpanded;
    	if(!parent.isExpanded())return true;
    	return parent.isParentCollapsed();
    }
    /**
     * 递归判断所给的节点是否当前节点的父节点
     * @param node 所给节点
     * @return
     */
    public boolean isParent(Node node){
    	if(parent==null)return false;
    	if(node.equals(parent))return true;
    	return parent.isParent(node);
    }
}


ToolbarAdapter.java

package com.chinaunicom.yczft.tree;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

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

import com.chinaunicom.yczft.R;

public class ToolbarAdapter extends BaseAdapter{
	private Context con;
    private List<Map<String, Object>> alls = new ArrayList<Map<String, Object>>();
    private LayoutInflater lif;
    private List<Integer> posClickable = new ArrayList<Integer>();
    
    /// 设置绑定字段 
    public static final String NAME = "name";//文字
    public static final String IMAGE = "image";//图片
    
   /**
    * 构造函数
    * @param context
    * @param name_array 菜单文字数组
    * @param image_array 菜单图片数组
    * @param position 可以点击的菜单位置数组
    */
    public ToolbarAdapter(Context context,
    		String[] name_array,int[]image_array,int[]position) {
    	this.con = context;
    	this.lif = (LayoutInflater) con.
    	getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    	
    	if(name_array != null && name_array.length>0){
    		for(int i=0;i<name_array.length;i++){
    			Map<String,Object> item = new HashMap<String,Object>();
    			item.put(NAME, name_array[i]);
    			if(image_array!=null && image_array.length==name_array.length){
    				item.put(IMAGE, image_array[i]);
    			}
    			alls.add(item);
        	}
    	}
    	
    	if(position != null && position.length>0){
    		for(int i=0;i<position.length;i++){
    			posClickable.add(position[i]);
        	}
    	}
    	
    }
    
    @Override
	public int getCount() {
		// TODO Auto-generated method stub
    	return alls.size();
	}

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

	@Override
	public long getItemId(int index) {
		// TODO Auto-generated method stub
		return index;
	}
	
	public String getBh(int index){
		Map<String,Object> item = alls.get(index);
		String bh = item.get(NAME).toString();
		return bh;
	}
	
	@Override
	public View getView(int indexID, View view, ViewGroup arg2) {
		// TODO Auto-generated method stub
		if (view == null) {
			view = this.lif.inflate(R.layout.item_toolbar, null);
			Map<String, Object> mapItem = alls.get(indexID);
			
			ViewHolder holder = new ViewHolder();
			//holder.ivImage = (ImageView) view.findViewById(R.id.item_image);
			holder.tvText = (TextView) view.findViewById(R.id.item_text);
			
			if(mapItem != null){
			    String name = mapItem.get(NAME).toString();
			    holder.tvText.setText(name);
			    
			    if(mapItem.get(IMAGE)==null){
			    	//holder.ivImage.setVisibility(View.GONE);
			    }else{
			    	//holder.ivImage.setVisibility(View.VISIBLE);
			    	//holder.ivImage.setImageResource(Integer.valueOf(mapItem.get(IMAGE).toString()));
			    }
			}
			view.setFocusable(false);
			view.setClickable(false);
			//System.out.println("this position is:"+indexID+",text is:"+holder.tvText.getText());
			
			// 控制是否可以点击和获得焦点
			if(!posClickable.contains(indexID)){
				view.setFocusable(true);
				view.setClickable(true);
				//System.out.println("this position is clickable:"+indexID+",text is:"+holder.tvText.getText());
			}
			
		}
		return view;
		
	}
	/**
	 * 
	 * 列表项控件集合
	 *
	 */
	private class ViewHolder{
		//ImageView ivImage;//
		TextView tvText;//
	}
}


TreeAdapter.java

package com.chinaunicom.yczft.tree;

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

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.CheckBox;
import android.widget.ImageView;
import android.widget.TextView;

import com.chinaunicom.yczft.R;

public class TreeAdapter extends BaseAdapter{

	private Context con;
	private LayoutInflater lif;
	private List<Node> allsCache = new ArrayList<Node>();
	private List<Node> alls = new ArrayList<Node>();
	private TreeAdapter oThis = this;
	private boolean hasCheckBox = true;//是否拥有复选框
	private int expandedIcon = -1;
	private int collapsedIcon = -1;
	
	/**
	 * TreeAdapter构造函数
	 * @param context 
	 * @param rootNode 根节点
	 */
	public TreeAdapter(Context context,List<Node> rootNodeList){
		this.con = context;
		this.lif = (LayoutInflater) con.
    	getSystemService(Context.LAYOUT_INFLATER_SERVICE);
		for (Node rootNode : rootNodeList) {
			addNode(rootNode);
		}
	}
	
	private void addNode(Node node){
		alls.add(node);
		allsCache.add(node);
		if(node.isLeaf())return;
		for(int i=0;i<node.getChildren().size();i++){
			addNode(node.getChildren().get(i));
		}
	}
	

	// 复选框联动
	private void checkNode(Node node,boolean isChecked){
		node.setChecked(isChecked);
		for(int i=0;i<node.getChildren().size();i++){
			checkNode(node.getChildren().get(i),isChecked);
		}
	}
	
	/**
	 * 获得选中节点
	 * @return
	 */
	public List<Node> getSeletedNodes(){
		List<Node> nodes = new ArrayList<Node>();
		for(int i=0;i<allsCache.size();i++){
			Node n = allsCache.get(i);
			if(n.isChecked()){
				nodes.add(n);
			}
		}
		return nodes;
	}
	
	// 控制节点的展开和折叠
	private void filterNode(){
		alls.clear();
		for(int i=0;i<allsCache.size();i++){
			Node n = allsCache.get(i);
			if(!n.isParentCollapsed() || n.isRoot()){
				alls.add(n);
			}
		}
	}
	
	/**
     * 设置是否拥有复选框
     * @param hasCheckBox
     */
    public void setCheckBox(boolean hasCheckBox){
    	this.hasCheckBox = hasCheckBox;
    }
	
    /**
     * 设置展开和折叠状态图标
     * @param expandedIcon 展开时图标
     * @param collapsedIcon 折叠时图标
     */
    public void setExpandedCollapsedIcon(int expandedIcon,int collapsedIcon){
    	this.expandedIcon = expandedIcon;
    	this.collapsedIcon = collapsedIcon;
    }
    
	/**
	 * 设置展开级别
	 * @param level
	 */
	public void setExpandLevel(int level){
		alls.clear();
		for(int i=0;i<allsCache.size();i++){
			Node n = allsCache.get(i);
			if(n.getLevel()<=level){
				if(n.getLevel()<level){// 上层都设置展开状态
					n.setExpanded(true);
				}else{// 最后一层都设置折叠状态
					n.setExpanded(false);
				}
				alls.add(n);
			}
		}
		this.notifyDataSetChanged();
	}
	
	/**
	 * 控制节点的展开和收缩
	 * @param position
	 */
	public void ExpandOrCollapse(int position){
		Node n = alls.get(position);
		if(n != null){
			if(!n.isLeaf()){
				n.setExpanded(!n.isExpanded());
				filterNode();
				this.notifyDataSetChanged();
			}
		}
	}
	
	@Override
	public int getCount() {
		// TODO Auto-generated method stub
		return alls.size();
	}

	@Override
	public Object getItem(int position) {
		// TODO Auto-generated method stub
		return alls.get(position);
	}

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

	@Override
	public View getView(int position, View view, ViewGroup parent) {
		// TODO Auto-generated method stub
		
		ViewHolder holder = null;
		if (view == null) {
			view = this.lif.inflate(R.layout.listview_item_tree, null);
			holder = new ViewHolder();
			holder.chbSelect = (CheckBox)view.findViewById(R.id.chbSelect);
			
			// 复选框单击事件
			holder.chbSelect.setOnClickListener(new OnClickListener(){

				@Override
				public void onClick(View v) {
					// TODO Auto-generated method stub
					Node n = (Node)v.getTag();
					checkNode(n,((CheckBox)v).isChecked());
					oThis.notifyDataSetChanged();
				}
				
			});
			holder.ivIcon = (ImageView)view.findViewById(R.id.ivIcon);
			holder.tvText = (TextView)view.findViewById(R.id.tvText);
			holder.ivExEc = (ImageView)view.findViewById(R.id.ivExEc);
			view.setTag(holder);
		}else{
			holder = (ViewHolder)view.getTag();
		}
		
		// 得到当前节点
		Node n = alls.get(position);
		
		if(n != null){
			holder.chbSelect.setTag(n);
			holder.chbSelect.setChecked(n.isChecked());
			
			// 是否显示复选框
			if(n.hasCheckBox() && hasCheckBox){
				holder.chbSelect.setVisibility(View.VISIBLE);
			}else{
				holder.chbSelect.setVisibility(View.GONE);
			}
			
			// 是否显示图标
			if(n.getIcon() == -1){
			    holder.ivIcon.setVisibility(View.GONE);
			}else{
				holder.ivIcon.setVisibility(View.VISIBLE);
				holder.ivIcon.setImageResource(n.getIcon());
			}
			
			// 显示文本
			holder.tvText.setText(n.getText());
			
			if(n.isLeaf()){
				// 是叶节点 不显示展开和折叠状态图标
				holder.ivExEc.setVisibility(View.GONE);
			}else{ 
				// 单击时控制子节点展开和折叠,状态图标改变
				holder.ivExEc.setVisibility(View.VISIBLE);
				if(n.isExpanded()){
					if(expandedIcon != -1)
					holder.ivExEc.setImageResource(expandedIcon);
				}
				else {
					if(collapsedIcon != -1)
					holder.ivExEc.setImageResource(collapsedIcon);
				}
				
			}
			
			// 控制缩进
			view.setPadding(35*n.getLevel(), 3,3, 3);
			
		}
		
		return view;
	}

	
	/**
	 * 
	 * 列表项控件集合
	 *
	 */
	public class ViewHolder{
		CheckBox chbSelect;//选中与否
		ImageView ivIcon;//图标
		TextView tvText;//文本〉〉〉
		ImageView ivExEc;//展开或折叠标记">"或"v"
	}
}


最后是启动的Activity.java

package com.chinaunicom.yczft.tree;

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

import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import org.json.JSONArray;
import org.json.JSONObject;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.Gravity;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.GridView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.Toast;

import com.chinaunicom.yczft.MyApp;
import com.chinaunicom.yczft.MyApplicationExit;
import com.chinaunicom.yczft.R;
import com.chinaunicom.yczft.util.HttpUtil;

public class TreeActivity extends Activity implements OnItemClickListener{
	private ProgressDialog progressDialog;
	private ListView code_list;
	private LinearLayout toolBar;
	private TreeActivity oThis = this;
	private MyApp myApp;
	private JSONArray treeJsonArray;
	private HashMap<String, String> selectedHM;
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.tree);
		MyApplicationExit.getInstance().addActivity(this);//单例模式管理所有开启的activity	
		myApp = (MyApp) getApplicationContext();
		Bundle bl = new Bundle();
		Intent intent = this.getIntent();
		// 获取Intent中的Bundle数据
		bl = intent.getExtras();
		String selectedUserCodes=bl.getString("selectedUserCodes");
		selectedHM = new HashMap<String, String>();
		if(selectedUserCodes!=null&&!selectedUserCodes.equals("")){
			String[] selectedUserCodesArrAy=selectedUserCodes.split(",");
			for (String selectedUserCode : selectedUserCodesArrAy) {
				selectedHM.put(selectedUserCode, selectedUserCode);
			}
		}
        toolBar = (LinearLayout) findViewById(R.id.toolBar);
        code_list = (ListView)findViewById(R.id.code_list);
        code_list.setOnItemClickListener(this);
        
        progressDialog = new ProgressDialog(oThis);
        setToolBar(new String[]{ "确定","","","返回" },new int[]{0, 3});
//        setPreson();
        fillTree();
    }

	@Override
	public void onItemClick(AdapterView<?> parent, View view, int position,
			long id) {
		// TODO Auto-generated method stub
		
		
		
		// 这句话写在最后面
		((TreeAdapter)parent.getAdapter()).ExpandOrCollapse(position);
	}
	
	private void fillTree() {
		RunGetDataTask();
	}
	
	private void RunGetDataTask() {

		if (!progressDialog.isShowing()) {
			progressDialog = ProgressDialog.show(oThis,
					"请稍等...", "数据加载中...", true);
		}

		GetDataTask task = new GetDataTask(oThis);
		task.execute("");
	}
	
	class GetDataTask extends AsyncTask<String, Integer, String> {
	    // 可变长的输入参数,与AsyncTask.exucute()对应
	    public GetDataTask(Context context){
	    }
	    @Override
	    protected String doInBackground(String... params) {
	    	treeJsonArray=myApp.getTreeJsonArray();
	    	if(treeJsonArray==null){
	    		treeJsonArray=getTreeJsonArray();
	    	}
	        return null;
	    }

	    @Override
	    protected void onCancelled() {
	        super.onCancelled();
	    }

	    @Override
	    protected void onPreExecute() {
	    }

	    @Override
	    protected void onPostExecute(String result) {
	    	doFillTree();
	    }
	    
	    @Override
	    protected void onProgressUpdate(Integer... values) {
	    }
	 }
	
	public JSONArray getTreeJsonArray(){
		JSONArray jsonArray = new JSONArray();
		String uriAPI =HttpUtil.SERVER_ADDRESS + "static/sys/information/getInfoStaff?userCode="+myApp.getUserCode();
		HttpGet httpRequest = new HttpGet(uriAPI);
		String rt = "";
		try {
			HttpResponse httpResponse = new DefaultHttpClient()
					.execute(httpRequest);
			if (httpResponse.getStatusLine().getStatusCode() == 200) {
				rt = EntityUtils.toString(httpResponse.getEntity());
				System.out.println(rt);
				if (rt != null) {
					jsonArray=new JSONArray(rt);
					myApp.setTreeJsonArray(jsonArray);
				}
				}
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		return jsonArray;
	}
	// Download by http://www.codefans.net
	// 设置节点,可以通过循环或递归方式添加节点
	private void doFillTree() {
		List<Node> rootList=new ArrayList<Node>();
		try {
		for (int i=0; i<treeJsonArray.length();i++) {
		
			JSONObject json =(JSONObject)treeJsonArray.get(i);
			String name=json.getString("name");
			String code=json.getString("code");
			String type=json.getString("type");
			boolean hasChildren=json.getBoolean("hasChildren");
			Node rootNode = new Node(name,code,type);
			if("1".equals(type)){
				rootNode.setIcon(R.drawable.icon_department);//设置图标
			}else{
				rootNode.setIcon(R.drawable.icon_police);//设置图标
			}
			if(hasChildren){
				rootNode=creatTreeNode(json,rootNode);
			}
			if(selectedHM.containsKey(code)){
				rootNode.setChecked(true);
			}
			rootList.add(rootNode);
		}
		} catch (Exception e) {
			showDialog("数据格式错误!");
			e.printStackTrace();
		}
		
		TreeAdapter ta = new TreeAdapter(oThis,rootList);
		// 设置整个树是否显示复选框
		ta.setCheckBox(true);
	    // 设置展开和折叠时图标
		ta.setExpandedCollapsedIcon(R.drawable.tree_ex, R.drawable.tree_ec);
		// 设置默认展开级别
		ta.setExpandLevel(2);
		code_list.setAdapter(ta);
		progressDialogClose();
	}
	
	public Node creatTreeNode(JSONObject json,Node parentNode) throws Exception{
		JSONArray childrens=json.getJSONArray("children");
		for (int i=0; i<childrens.length();i++) {
			JSONObject children =(JSONObject)childrens.get(i);
			String name=children.getString("name");
			String code=children.getString("code");
			String type=children.getString("type");
			boolean hasChildren=children.getBoolean("hasChildren");
			Node node = new Node(name,code,type);
			if("1".equals(type)){
				node.setIcon(R.drawable.icon_department);//设置图标
			}else{
				node.setIcon(R.drawable.icon_police);//设置图标
			}
			if(hasChildren){
				node=creatTreeNode(children,node);
			}
			parentNode.add(node);
			node.setParent(parentNode);
			if(selectedHM.containsKey(code)){
				node.setChecked(true);
			}
			
		}
		return parentNode;
	}
	// 设置底部工具栏
	private void setToolBar(String[] name_array,int[] pos_array){
		toolBar.removeAllViews();
		
		GridView toolbarGrid = new GridView(this);
		toolbarGrid.setNumColumns(4);// 设置每行列数
		toolbarGrid.setGravity(Gravity.CENTER);// 位置居中
		ToolbarAdapter adapter = new ToolbarAdapter(this,name_array,null,pos_array);
		toolbarGrid.setAdapter(adapter);
		toolbarGrid.setOnItemClickListener(new OnItemClickListener() {
			public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
					long arg3) {
				switch (arg2) {
				case 0://显示选中结果
					List<Node> nodes = ((TreeAdapter)code_list.getAdapter()).getSeletedNodes();
					String msg = "";
					StringBuffer selectUserNames=new StringBuffer();
					StringBuffer selectUserCodes=new StringBuffer();
					for(int i=0;i<nodes.size();i++){
						Node n = nodes.get(i);
						if(n.isLeaf()){
							if(!msg.equals(""))msg+=",";
							msg += n.getText()+"("+n.getValue()+")";
							if(selectUserNames.length()==0){
								selectUserNames.append(n.getText());
								selectUserCodes.append(n.getValue());
							}else{
								selectUserNames.append(",");
								selectUserCodes.append(",");
								selectUserNames.append(n.getText());
								selectUserCodes.append(n.getValue());
							}
						}
						
					}
					if(msg.equals("")){
						Toast.makeText(oThis, "没有选中任何项", Toast.LENGTH_SHORT).show();
					}else{
						 Intent backIntent=new Intent();
						 Bundle bundle=new Bundle();
						 bundle.putString("selectUserNames", selectUserNames.toString());
						 bundle.putString("selectUserCodes", selectUserCodes.toString());
						backIntent.putExtras(bundle);
						setResult(19, backIntent);
						oThis.finish();
//						Toast.makeText(oThis, msg, Toast.LENGTH_SHORT).show();
					}
					
					break;
				case 3://返回
					oThis.finish();
//					System.exit(0);
					break;
				}
			}
		});
		toolBar.addView(toolbarGrid);
	}
	
	/* 显示Dialog的method */
	private void showDialog(String mess) {
		new AlertDialog.Builder(oThis).setTitle("消息提示")
				.setMessage(mess)
				.setNegativeButton("确定", new DialogInterface.OnClickListener() {
					public void onClick(DialogInterface dialog, int which) {

					}
				}).show();
	}
	public void progressDialogClose() {
		if (progressDialog.isShowing()) {
			progressDialog.cancel();
		}
	}
}


 布局

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
	android:layout_width="fill_parent" android:layout_height="fill_parent"
	android:background="#ffffffff">
	<include layout="@layout/toolbar_bottom"></include>
	<RelativeLayout android:layout_width="fill_parent"
		android:layout_height="fill_parent" android:layout_above="@+id/toolBar">
		<ListView android:id="@+id/code_list" android:background="#ffffffff"
			android:fadingEdgeLength="0.0sp" android:layout_width="fill_parent"
			android:layout_height="wrap_content" android:drawSelectorOnTop="false"
			android:cacheColorHint="#ffffffff" android:divider="@drawable/divider_list"
			android:dividerHeight="2.0dip" android:layout_weight="0.0"
			android:fastScrollEnabled="true" android:scrollbars="none"
			/>

	</RelativeLayout>
</RelativeLayout>


 

快速实现Android多级形列表,这个库是在鸿洋多级形列表demo中修改而来。解决的问题:支持ID为int类型和String类型。支持多级复选框选中,使用只需一行代码。支持动态更新数据并保持原有展开/关闭状态。支持ListView、RecyclerView。USE我们关联列表需要有三个必须元素,当前id、父级id即pid,显示的内容。id和pid可以为int或者String以及其他类型。要显示的内容需要包装一下://id pid name  FileNode为实际用的实体Bean对象 mlist.add(new Node("223","0","我也是添加的root节点",new FileNode()));对于ListView,需要继承自TreeListViewAdapter,如:public class SimpleTreeAdapter extends TreeListViewAdapter {     public SimpleTreeAdapter(ListView mTree, Context context, List datas, int defaultExpandLevel, int iconExpand, int iconNoExpand) {         super(mTree, context, datas, defaultExpandLevel, iconExpand, iconNoExpand);     }     public SimpleTreeAdapter(ListView mTree, Context context, List datas,                              int defaultExpandLevel) {         super(mTree, context, datas, defaultExpandLevel);     }     @Override     public View getConvertView(final Node node , int position, View convertView, ViewGroup parent)     {        final ViewHolder viewHolder ;         if (convertView == null) {             convertView = mInflater.inflate(R.layout.list_item, parent, false);             viewHolder = new ViewHolder();             viewHolder.cb = (CheckBox) convertView                     .findViewById(R.id.cb_select_tree);             viewHolder.label = (TextView) convertView                     .findViewById(R.id.id_treenode_label);             viewHolder.icon = (ImageView) convertView.findViewById(R.id.icon);             convertView.setTag(viewHolder);         } else {             viewHolder = (ViewHolder) convertView.getTag();         }         viewHolder.cb.setOnClickListener(new View.OnClickListener() {             @Override             public void onClick(View v) {                 setChecked(node,viewHolder.cb.isChecked());             }         });         if (node.isChecked()){             viewHolder.cb.setChecked(true);         }else {             viewHolder.cb.setChecked(false);         }         if (node.getIcon() == -1) {             viewHolder.icon.setVisibility(View.INVISIBLE);         } else {             viewHolder.icon.setVisibility(View.VISIBLE);             viewHolder.icon.setImageResource(node.getIcon());         }         viewHolder.label.setText(node.getName());         return convertView;     }     private final class ViewHolder     {         ImageView icon;         CheckBox cb;         TextView label;     } }对于RecyclerView,需继承自TreeRecyclerAdapter,如:public class SimpleTreeRecyclerAdapter extends TreeRecyclerAdapter {     public SimpleTreeRecyclerAdapter(RecyclerView mTree, Context context, List datas, int defaultExpandLevel, int iconExpand, int iconNoExpand) {         super(mTree, context, datas, defaultExpandLevel, iconExpand, iconNoExpand);     }     public SimpleTreeRecyclerAdapter(RecyclerView mTree, Context context, List datas, int defaultExpandLevel) {         super(mTree, context, datas, defaultExpandLevel);     }     @Override     public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {         return new MyHoder(View.inflate(mContext, R.layout.list_item,null));     }     @Override     public void onBindViewHolder(final Node node, RecyclerView.ViewHolder holder, int position) {         final MyHoder viewHolder = (MyHoder) holder;         //todo do something         viewHolder.cb.setOnClickListener(new View.OnClickListener() {             @Override             public void onClick(View v) {                 setChecked(node,viewHolder.cb.isChecked());             }         });         if (node.isChecked()){             viewHolder.cb.setChecked(true);         }else {             viewHolder.cb.setChecked(false);         }         if (node.getIcon() == -1) {             viewHolder.icon.setVisibility(View.INVISIBLE);         } else {             viewHolder.icon.setVisibility(View.VISIBLE);             viewHolder.icon.setImageResource(node.getIcon());         }         viewHolder.label.setText(node.getName());     }     class MyHoder extends RecyclerView.ViewHolder{         public CheckBox cb;         public TextView label;         public ImageView icon;         public MyHoder(View itemView) {             super(itemView);             cb = (CheckBox) itemView                     .findViewById(R.id.cb_select_tree);             label = (TextView) itemView                     .findViewById(R.id.id_treenode_label);             icon = (ImageView) itemView.findViewById(R.id.icon);         }     } }初始化: ListView://第一个参数  ListView //第二个参数  上下文 //第三个参数  数据集 //第四个参数  默认展开层级数 0为不展开 //第五个参数  展开的图标 //第六个参数  闭合的图标 mAdapter = new SimpleTreeAdapter(mTree, ListViewActivity.this,                         mDatas, 1,R.mipmap.tree_ex,R.mipmap.tree_ec); mTree.setAdapter(mAdapter);RecyclerView://第一个参数  RecyclerView //第二个参数  上下文 //第三个参数  数据集 //第四个参数  默认展开层级数 0为不展开 //第五个参数  展开的图标 //第六个参数  闭合的图标 mAdapter = new SimpleTreeRecyclerAdapter(mTree, RecyclerViewActivity.this,                 mDatas, 1,R.mipmap.tree_ex,R.mipmap.tree_ec); mTree.setAdapter(mAdapter);添加数据,可以保持原有选中或者展开状态:List mlist = new ArrayList(); mlist.add(new Node("223","0","我也是添加的root节点",new FileNode())); mAdapter.addData(0,mlist);获取选中内容:如果node的isChecked()为true,即为选中状态。StringBuilder sb = new StringBuilder(); //获取排序过的nodes //如果不需要刻意直接用 mDatas既可 final List allNodes = mAdapter.getAllNodes(); for (int i = 0; i < allNodes.size(); i ) {    if (allNodes.get(i).isChecked()){        sb.append(allNodes.get(i).getName() ",");    } } String strNodesName = sb.toString(); if (!TextUtils.isEmpty(strNodesName))    Toast.makeText(this, strNodesName.substring(0, strNodesName.length()-1),Toast.LENGTH_SHORT).show();控制父子之间联动的选中与取消状态,只需调用setChecked方法既可,注意如果在setOnCheckedChangeListener中处理会有问题:因为如果要子节点/父节点选中或者取消需要刷新页面,而刷新页面又会触发viewHolder.cb.setChecked(true/false);的判断从而又会进入setOnCheckedChangeListener,会导致如果父节点选中某些子节点取消不了的情况。//viewHolder.cb 为CheckBox  viewHolder.cb.setOnClickListener(new View.OnClickListener() {             @Override             public void onClick(View v) {                 setChecked(node,viewHolder.cb.isChecked());             }         });
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值