源碼是從網上找的,自己修改了一下,具體作者忘了是誰了 在此說一聲抱歉
節點 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>