源码是从网上找的,自己修改了一下,具体作者忘了是谁了 在此说一声抱歉
节点 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>