Android - N级树形结构实现

    目前已经实现3级之内的任意级树形结构展示(如果想增加更多级,需要扩展排序算法),并支持单选和多选(使用不同的适配器)。

    实现使用的控件:ListView

    首先,最重要的应该是数据源的格式,支持树形结构的数据源,每条数据应该都要指明它的父级是谁,本文为parent_org,并把每条数据都存放在一个HashMap里面。这里使用的除了parent_org(父营业部),还有org_name(营业部名称),org_code(营业部编号)。

    其次,对数据进行排序。因为只使用ListView实现,所以需要实现层次结构的树形结构,需要对数据按父级->2级->3级->父级->2级->父级->2级->父级->2级->3级这样的顺序排序。

    接着,实现适配器,展现树形结构。

    最后,调用适配器,并调用适配器里的方法获取选择结果。



排序算法:

/**
 * 查询操作员营业部列表类
 * 
 * @author xinyan
 * 
 */
public class QueryIntOrgListWork extends BaseWork implements Runnable {

	private static final String TAG = "QueryIntOrgListWork";
	HashMap<String, String> params;

	public QueryIntOrgListWork(Context context, Map args) {
		super(context, args);

	}

	public QueryIntOrgListWork(Context context, View layoutView, Map args) {
		super(context, layoutView, args);

	}

	@Override
	public void work() {
		params = new HashMap<String, String>();
		AppState appState = AppState.getState();

		BrokerInfo brokerInfo = appState.getBrokerInfo();
		// params.put("uuid", brokerInfo.getUuid());
		Utils.putUuid(params);
		params.put("funcno", "20017");
		params.put("org_type", "0");
		params.put("right_flag", "1");
		try {
			HttpFactory httpFactory = new HttpFactory();
			byte[] bytes = httpFactory.send(
					Configuration.getString("system.http"), params,
					HttpFactory.POST);

			if (bytes == null) {
				return;
			}

			String result = new String(bytes,
					Configuration.getString("system.charSet"));

			JSONObject jsonObject = new JSONObject(result);

			// 增加登录过期或账号已在其他地方登录的处理
			try {
				String strPrompt = jsonObject.getString("errorInfo");
				String strErrorNo = jsonObject.getString("errorNo");
				if (!StringHelper.isEmpty(strPrompt)) {
					if (strPrompt.contains("未登")
							|| strPrompt.contains("其它地方登陆")) {
						sendMessage(new LoginExpiredUiWork(null));
						return;
					}
				}
				// 如果访问接口异常,提示信息
				if (!strErrorNo.equals("0")) {
					HashMap<String, String> param = new HashMap<String, String>();
					if (null != strPrompt) {
						param.put("errorInfo", "调用查询操作员机构列表接口:" + strPrompt);
					} else {
						param.put("errorInfo", "");
					}

					sendMessage(new CallInterfaceExceptionUiWork(param));
					if ("-111".equals(strErrorNo) || "-110".equals(strErrorNo)
							|| "-2008000".equals(strErrorNo)) {
						return;
					}
				}
			} catch (Exception e) {
			}

			String errorNo = jsonObject.getString("errorNo");
			if (errorNo.equals("-1")) {
				String errorInfo = jsonObject.getString("errorInfo");
				Map<String, String> map = new HashMap<String, String>();
				map.put("errorNo", "-1");
				map.put("errorInfo", errorInfo);
			} else if (errorNo.equals("-999")) {

				Intent intent = new Intent("com.thinkive.action.MAIN");
				context.startActivity(intent);

			} else if (errorNo.equals("0")) {
				JSONArray array = jsonObject.getJSONArray("results");

				ArrayList<HashMap<String, Object>> dataList = new ArrayList<HashMap<String, Object>>();
				HashMap<String, Object> dataItem = null;

				for (int i = 0; i < array.length(); i++) {
					dataItem = new HashMap<String, Object>();

					JSONObject item = array.getJSONObject(i);
					String org_name = item.getString("org_name");
					// String area_addr = item.getString("area_addr");
					//
					// String org_type = item.getString("org_type");
					// String right_flag = item.getString("right_flag");
					// String zip_code = item.getString("zip_code");
					// String acct_len = item.getString("acct_len");
					String org_code = item.getString("org_code");
					// String acct_prefix = item.getString("acct_prefix");

					// String org_full_name = item.getString("org_full_name");
					String parent_org = item.getString("parent_org");
					// String area_no = item.getString("area_no");
					// String org_status = item.getString("org_status");
					// String org_cls = item.getString("org_cls");

					dataItem.put("org_name", org_name);
					dataItem.put("org_code", org_code);
					dataItem.put("parent_org", parent_org);

					dataList.add(dataItem);
				}
				AppState.getState().getBrokerInfo()
						.setIntOrgs(regroupData(dataList));
			}

		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	/**
	 * 对数据根据子父级关系进行重组
	 */
	private List<HashMap<String, Object>> regroupData(
			List<HashMap<String, Object>> dataList) {
		HashMap<String, Object> item = null;
		ArrayList<HashMap<String, Object>> regroupedDataList = null;
		for (int i = 0; i < dataList.size(); i++) {
			item = dataList.get(i);

			String strOrg = item.get("org_code").toString();
			String strParentOrg = item.containsKey("parent_org") ? item.get(
					"parent_org").toString() : "";

			// 如果没有父营业部,遍历列表是否存在子营业部
			if (StringHelper.isEmpty(strParentOrg)) {
				HashMap<String, Object> item2 = null;

				ArrayList<HashMap<String, Object>> childList = null;

				// 遍历列表是否存在子营业部
				for (int j = 0; j < dataList.size(); j++) {
					if (i == j) {
						continue;
					}

					item2 = dataList.get(j);

					// 列表存在子营业部
					if (strOrg.equals(item2.get("parent_org"))) {
						childList = new ArrayList<HashMap<String, Object>>();
						if (null != item2.get("child")) {

							// 如果该营业部的子营业部还存在子营业部,那么此营业部是1级,最高级
							item2.put("org_level", "1");
						} else {

							// 如果该营业部的子营业部不存在子营业部,那么将此营业部暂定为2级
							item2.put("org_level", "2");
						}
						childList.add(item2);
					}// end if
				}// end for
				item.put("child", childList);

			} else {// 如果有父营业部
				HashMap<String, Object> parentOrgItem = null;

				boolean isParentOrgExist = false;

				// 首先检查列表是否存在父营业部
				for (int j = 0; j < dataList.size(); j++) {
					if (i == j) {
						continue;
					}

					parentOrgItem = dataList.get(j);

					// 列表存在父营业部
					if (strParentOrg.equals(parentOrgItem.get("org_code"))) {
						isParentOrgExist = true;

						// 加入当前营业部到该父营业部的子营业部列表,标记当前项为2级营业部
						item.put("org_level", "2");

						ArrayList<HashMap<String, Object>> childList = null;
						if (null != parentOrgItem.get("child")) {
							childList = (ArrayList<HashMap<String, Object>>) parentOrgItem
									.get("child");
						} else {
							childList = new ArrayList<HashMap<String, Object>>();
						}

						// 检查子营业部列表是否已经存在该营业部
						boolean isOrgExist = false;
						if (childList.size() > 0) {
							HashMap<String, Object> childItem = null;

							for (int k = 0; k < childList.size(); k++) {
								childItem = (HashMap<String, Object>) childList
										.get(k);

								if (childItem.get("org_code").toString()
										.equals(item.get("org_code"))) {
									isOrgExist = true;
								}
							}
						}
						if (!isOrgExist) {
							childList.add(item);
							parentOrgItem.put("child", childList);
						}

						break;
					}// end if
				}// end for

				// 检查完了是否存在父营业部之后,再检查列表是否存在该营业部的子营业部
				HashMap<String, Object> childOrgItem = null;

				ArrayList<HashMap<String, Object>> childList = new ArrayList<HashMap<String, Object>>();

				// 遍历列表是否存在子营业部
				for (int k = 0; k < dataList.size(); k++) {
					if (i == k) {
						continue;
					}

					childOrgItem = dataList.get(k);

					// 列表存在子营业部
					if (strOrg.equals(childOrgItem.get("parent_org"))) {

						if (null != childOrgItem.get("child")) {

							// 如果该营业部的子营业部还存在子营业部,那么此营业部是1级,最高级
							childOrgItem.put("org_level", "1");
						} else {

							// 如果该营业部的子营业部不存在子营业部,那么将此营业部暂定为2级
							childOrgItem.put("org_level", "2");
						}
						childList.add(childOrgItem);
					}// end if
				}// end for

				if (childList.size() > 0) {
					item.put("child", childList);

					// 如果当前营业部存在父营业部和子营业部,那么就是2级
					if (isParentOrgExist) {
						item.put("org_level", "2");
					} else {

						// 不存在父营业部,那么是1级
						item.put("org_level", "1");
					}
				} else {

					// 不存在子营业部
					if (isParentOrgExist) {

						// 不存在子营业部,但存在父营业部,那么是2级
						item.put("org_level", "2");
					} else {

						// 不存在子营业部和父营业部,那么是1级
						item.put("org_level", "1");
					}
				}
			}// end else
		}// end for

		// 当数据按数学结构组织好之后,按顺序排列为列表,以便在listview里显示
		regroupedDataList = new ArrayList<HashMap<String, Object>>();
		HashMap<String, Object> tempItem = null;
		for (int i = 0; i < dataList.size(); i++) {
			tempItem = dataList.get(i);

			if ("1".equals(tempItem.get("org_level").toString())) {
				regroupedDataList.add(tempItem);

				// 把子营业部加入到重组后的列表
				if (tempItem.containsKey("child")) {
					ArrayList<HashMap<String, Object>> childList = (ArrayList<HashMap<String, Object>>) tempItem
							.get("child");
					HashMap<String, Object> childItem = null;
					if (childList.size() > 0) {
						for (int j = 0; j < childList.size(); j++) {
							childItem = (HashMap<String, Object>) childList
									.get(j);
							regroupedDataList.add(childItem);

							// 检查子营业部是否还有子营业部
							if (childItem.containsKey("child")) {
								ArrayList<HashMap<String, Object>> childList2 = (ArrayList<HashMap<String, Object>>) childItem
										.get("child");
								HashMap<String, Object> childItem2 = null;
								if (childList2.size() > 0) {
									for (int k = 0; k < childList2.size(); k++) {
										childItem2 = (HashMap<String, Object>) childList2
												.get(k);
										regroupedDataList.add(childItem2);
									}// end for
								}// end if
							}// end if
						}// end for
					}// end if
				}// end if
			}// end if
		}// end for

		for (int i = 0; i < regroupedDataList.size(); i++) {
			if (regroupedDataList.get(i).containsKey("child")) {
				regroupedDataList.get(i).remove("child");
			}
		}

		// 父级、子级都得排序
		Log.i(TAG, "重组前的营业部数据" + dataList);
		Log.i(TAG, "重组后的营业部数据" + regroupedDataList);

		return regroupedDataList;
	}

	@Override
	public void run() {
		work();
	}

}

多选营业部树形列表适配器:

/**
 * 多选营业部树形列表适配器
 * 
 * @author xinyan
 * @date 2013-5-27
 */
public class MultiCheckIntOrgListAdapter extends BaseAdapter {
	public static final String TAG = "MultiCheckIntOrgListAdapter";

	public static final String CHECKED_TRUE = "1";
	public static final String CHECKED_FALSE = "0";
	public static final String IS_CHECKED = "IS_CHECKED";

	private List<HashMap<String, Object>> mDataList;

	private LayoutInflater mInflater;

	public MultiCheckIntOrgListAdapter(Context context,
			List<HashMap<String, Object>> dataList) {
		this.mInflater = LayoutInflater.from(context);
		mDataList = dataList;
		setDefaultChecked();
	}

	@Override
	public int getCount() {
		return mDataList.size();
	}

	@Override
	public Object getItem(int position) {
		return mDataList.get(position);
	}

	@Override
	public long getItemId(int position) {
		return 0;
	}

	@Override
	public View getView(final int position, View convertView, ViewGroup parent) {
		ViewHolder holder = null;
		final HashMap<String, Object> dataItem = mDataList.get(position);
		if (null == convertView) {
			holder = new ViewHolder();
			convertView = mInflater.inflate(R.layout.lv_item_tree_structure,
					null);

			holder.cb = (CheckBox) convertView
					.findViewById(R.id.lv_item_tree_structure_cb);
			holder.text = (TextView) convertView
					.findViewById(R.id.lv_item_tree_structure_text);
			holder.joinBottom = (ImageView) convertView
					.findViewById(R.id.lv_item_tree_structure_join_bottom);
			holder.leaf = (ImageView) convertView
					.findViewById(R.id.lv_item_tree_structure_leaf);
			holder.joinBottom2 = (ImageView) convertView
					.findViewById(R.id.lv_item_tree_structure_join_bottom2);
			holder.leaf2 = (ImageView) convertView
					.findViewById(R.id.lv_item_tree_structure_leaf2);
			holder.tree = (ImageView) convertView
					.findViewById(R.id.lv_item_tree_structure_tree);

			convertView.setTag(holder);
		} else {
			holder = (ViewHolder) convertView.getTag();
		}
		holder.tree.setVisibility(View.GONE);
		holder.joinBottom.setVisibility(View.GONE);
		holder.leaf.setVisibility(View.GONE);
		holder.joinBottom2.setVisibility(View.GONE);
		holder.leaf2.setVisibility(View.GONE);

		// 如果是父级
		if ("1".equals(dataItem.get("org_level"))) {
			holder.tree.setVisibility(View.VISIBLE);
			holder.joinBottom.setVisibility(View.GONE);
			holder.leaf.setVisibility(View.GONE);
			holder.joinBottom2.setVisibility(View.GONE);
			holder.leaf2.setVisibility(View.GONE);

		} else if ("2".equals(dataItem.get("org_level"))) {// 如果是子级
			holder.joinBottom2.setVisibility(View.GONE);
			holder.leaf2.setVisibility(View.GONE);
			holder.tree.setVisibility(View.GONE);

			holder.joinBottom.setVisibility(View.VISIBLE);
			holder.leaf.setVisibility(View.VISIBLE);
		} else { // 3级
			holder.tree.setVisibility(View.GONE);

			holder.joinBottom2.setVisibility(View.VISIBLE);
			holder.leaf2.setVisibility(View.VISIBLE);
			holder.joinBottom.setVisibility(View.VISIBLE);
			holder.leaf.setVisibility(View.VISIBLE);
		}

		try {
			holder.text.setText(dataItem.get("org_code").toString() + " "
					+ dataItem.get("org_name").toString());
		} catch (Exception e) {
		}

		final CheckBox cb = holder.cb;

		if (CHECKED_TRUE.equals(dataItem.get(IS_CHECKED))) {
			cb.setChecked(true);
		} else {
			cb.setChecked(false);
		}

		convertView.setOnTouchListener(new OnTouchListener() {

			@Override
			public boolean onTouch(View v, MotionEvent event) {
				if (MotionEvent.ACTION_DOWN == event.getAction()) {
					if (cb.isChecked()) {
						cb.setChecked(false);
						dataItem.put(IS_CHECKED, CHECKED_FALSE);
					} else {
						cb.setChecked(true);
						dataItem.put(IS_CHECKED, CHECKED_TRUE);
					}

					if ("1".equals(dataItem.get("org_level").toString())) {
						// 遍历子营业部
						HashMap<String, Object> item = null;
						for (int i = position + 1; i < mDataList.size(); i++) {
							item = mDataList.get(i);

							if ("2".equals(item.get("org_level"))
									|| "3".equals(item.get("org_level"))) {
								if (cb.isChecked()) {
									item.put(IS_CHECKED, CHECKED_TRUE);
								} else {
									item.put(IS_CHECKED, CHECKED_FALSE);
								}
							} else if ("1".equals(item.get("org_level"))) {
								break;
							}// end else if
						}// end for
						notifyDataSetChanged();
					}// end if
					else if ("2".equals(dataItem.get("org_level").toString())) {
						// 遍历子营业部
						HashMap<String, Object> item = null;
						for (int i = position + 1; i < mDataList.size(); i++) {
							item = mDataList.get(i);

							if ("3".equals(item.get("org_level"))) {
								if (cb.isChecked()) {
									item.put(IS_CHECKED, CHECKED_TRUE);
								} else {
									item.put(IS_CHECKED, CHECKED_FALSE);
								}
							} else if ("1".equals(item.get("org_level"))) {
								break;
							}// end else if
						}// end for
						notifyDataSetChanged();
					}// end else if

					return true;
				}
				return false;
			}
		});

		return convertView;
	}

	/**
	 * 拿到已选择营业部的代码字符串,代码之间逗号分隔
	 * 
	 * @return
	 */
	public String getSelectedOrgCodes() {
		StringBuilder sbOrgCodes = new StringBuilder();
		for (int i = 0; i < mDataList.size(); i++) {
			if (mDataList.get(i).get(IS_CHECKED).equals(CHECKED_TRUE)) {
				if (sbOrgCodes.length() <= 2) {
					sbOrgCodes.append(mDataList.get(i).get("org_code")
							.toString());
				} else {
					sbOrgCodes.append(","
							+ mDataList.get(i).get("org_code").toString());
				}// end else
			}// end if
		}// end for

		Log.i(TAG, "getSelectedOrgCodes: " + sbOrgCodes.toString());

		return sbOrgCodes.toString();
	}

	/**
	 * 拿到已选择的营业部(org_code+org_name)
	 * 
	 * @return
	 */
	public String getSelectedOrg() {
		StringBuilder sbOrg = new StringBuilder();
		for (int i = 0; i < mDataList.size(); i++) {
			if (mDataList.get(i).get(IS_CHECKED).equals(CHECKED_TRUE)) {
				String strText = mDataList.get(i).get("org_code").toString()
						+ " " + mDataList.get(i).get("org_name").toString();
				if (sbOrg.length() <= 2) {
					sbOrg.append(strText);
				} else {
					sbOrg.append("," + strText);
				}// end else
			}// end if
		}// end for

		Log.i(TAG, "getSelectedOrg: " + sbOrg.toString());

		return sbOrg.toString();
	}

	/**
	 * 默认全部选中
	 */
	private void setDefaultChecked() {
		for (int i = 0; i < mDataList.size(); i++) {
			mDataList.get(i).put(IS_CHECKED, CHECKED_TRUE);
		}
	}

	class ViewHolder {
		TextView text;
		CheckBox cb;
		ImageView tree;// 树形图
		ImageView joinBottom;// 连接线
		ImageView leaf;// 子节点图
		ImageView joinBottom2;// 3级连接线
		ImageView leaf2;// 3级子节点图
	}

}

 单选营业部树形列表适配器


/**
 * 单选营业部树形列表适配器
 * 
 * @author xinyan
 * @date 2013-5-27
 */
public class SingleChoiceIntOrgListAdapter extends BaseAdapter {
	public static final String TAG = "SingleChoiceIntOrgListAdapter";

	public static final String CHECKED_TRUE = "1";
	public static final String CHECKED_FALSE = "0";
	public static final String IS_CHECKED = "IS_CHECKED";

	private List<HashMap<String, Object>> mDataList;

	private LayoutInflater mInflater;

	public SingleChoiceIntOrgListAdapter(Context context,
			List<HashMap<String, Object>> dataList) {
		this.mInflater = LayoutInflater.from(context);
		mDataList = dataList;
	}

	@Override
	public int getCount() {
		return mDataList.size();
	}

	@Override
	public Object getItem(int position) {
		return mDataList.get(position);
	}

	@Override
	public long getItemId(int position) {
		return 0;
	}

	@Override
	public View getView(final int position, View convertView, ViewGroup parent) {
		ViewHolder holder = null;
		final HashMap<String, Object> dataItem = mDataList.get(position);
		if (null == convertView) {
			holder = new ViewHolder();
			convertView = mInflater.inflate(
					R.layout.lv_item_tree_structure_single_choice, null);

			holder.cb = (CheckBox) convertView
					.findViewById(R.id.lv_item_tree_structure_cb);
			holder.text = (TextView) convertView
					.findViewById(R.id.lv_item_tree_structure_text);
			holder.joinBottom = (ImageView) convertView
					.findViewById(R.id.lv_item_tree_structure_join_bottom);
			holder.leaf = (ImageView) convertView
					.findViewById(R.id.lv_item_tree_structure_leaf);
			holder.joinBottom2 = (ImageView) convertView
					.findViewById(R.id.lv_item_tree_structure_join_bottom2);
			holder.leaf2 = (ImageView) convertView
					.findViewById(R.id.lv_item_tree_structure_leaf2);
			holder.tree = (ImageView) convertView
					.findViewById(R.id.lv_item_tree_structure_tree);

			convertView.setTag(holder);
		} else {
			holder = (ViewHolder) convertView.getTag();
		}
		holder.tree.setVisibility(View.GONE);
		holder.joinBottom.setVisibility(View.GONE);
		holder.leaf.setVisibility(View.GONE);
		holder.joinBottom2.setVisibility(View.GONE);
		holder.leaf2.setVisibility(View.GONE);

		// 如果是父级
		if ("1".equals(dataItem.get("org_level"))) {
			holder.tree.setVisibility(View.VISIBLE);
			holder.joinBottom.setVisibility(View.GONE);
			holder.leaf.setVisibility(View.GONE);
			holder.joinBottom2.setVisibility(View.GONE);
			holder.leaf2.setVisibility(View.GONE);

		} else if ("2".equals(dataItem.get("org_level"))) {// 如果是子级
			holder.joinBottom2.setVisibility(View.GONE);
			holder.leaf2.setVisibility(View.GONE);
			holder.tree.setVisibility(View.GONE);

			holder.joinBottom.setVisibility(View.VISIBLE);
			holder.leaf.setVisibility(View.VISIBLE);
		} else { // 3级
			holder.tree.setVisibility(View.GONE);

			holder.joinBottom2.setVisibility(View.VISIBLE);
			holder.leaf2.setVisibility(View.VISIBLE);
			holder.joinBottom.setVisibility(View.VISIBLE);
			holder.leaf.setVisibility(View.VISIBLE);
		}

		try {
			holder.text.setText(dataItem.get("org_code").toString() + " "
					+ dataItem.get("org_name").toString());
		} catch (Exception e) {
		}

		convertView.setOnTouchListener(new OnTouchListener() {

			@Override
			public boolean onTouch(View v, MotionEvent event) {
				if (MotionEvent.ACTION_DOWN == event.getAction()) {
					dataItem.put(IS_CHECKED, CHECKED_TRUE);

					// 把其它的营业部设置为false
					for (int i = 0; i < mDataList.size(); i++) {
						if (i == position) {
							continue;
						} else {
							mDataList.get(i).put(IS_CHECKED, CHECKED_FALSE);
						}
					}
				}
				return false;
			}
		});

		return convertView;
	}

	/**
	 * 拿到已选择营业部的代码字符串,代码之间逗号分隔
	 * 
	 * @return
	 */
	public String getSelectedOrgCodes() {
		StringBuilder sbOrgCodes = new StringBuilder();
		for (int i = 0; i < mDataList.size(); i++) {
			if (mDataList.get(i).get(IS_CHECKED).equals(CHECKED_TRUE)) {
				if (sbOrgCodes.length() <= 2) {
					sbOrgCodes.append(mDataList.get(i).get("org_code")
							.toString());
				} else {
					sbOrgCodes.append(","
							+ mDataList.get(i).get("org_code").toString());
				}// end else
			}// end if
		}// end for

		Log.i(TAG, "getSelectedOrgCodes: " + sbOrgCodes.toString());

		return sbOrgCodes.toString();
	}

	/**
	 * 拿到已选择的营业部(org_code+org_name)
	 * 
	 * @return
	 */
	public String getSelectedOrg() {
		StringBuilder sbOrg = new StringBuilder();
		for (int i = 0; i < mDataList.size(); i++) {
			if (mDataList.get(i).get(IS_CHECKED).equals(CHECKED_TRUE)) {
				String strText = mDataList.get(i).get("org_code").toString()
						+ " " + mDataList.get(i).get("org_name").toString();
				if (sbOrg.length() <= 2) {
					sbOrg.append(strText);
				} else {
					sbOrg.append("," + strText);
				}// end else
			}// end if
		}// end for

		Log.i(TAG, "getSelectedOrg: " + sbOrg.toString());

		return sbOrg.toString();
	}

	/**
	 * 默认全部选中
	 */
	private void setDefaultChecked() {
		for (int i = 0; i < mDataList.size(); i++) {
			mDataList.get(i).put(IS_CHECKED, CHECKED_TRUE);
		}
	}

	/**
	 * 设置默认选中的营业部
	 * 
	 * @param orgCode
	 */
	public void setDefaultChecked(String orgCode) {
		for (int i = 0; i < mDataList.size(); i++) {
			if (orgCode.contains(mDataList.get(i).get("org_code").toString())) {
				mDataList.get(i).put(IS_CHECKED, CHECKED_TRUE);
			} else {

				// 因为查询框里使用的多选营业部框跟这里使用的一个数据源,
				// 为了避免其它地方对这造成的影响,所以全部初始化好
				mDataList.get(i).put(IS_CHECKED, CHECKED_FALSE);
			}
		}
	}

	class ViewHolder {
		TextView text;
		CheckBox cb;
		ImageView tree;// 树形图
		ImageView joinBottom;// 连接线
		ImageView leaf;// 子节点图
		ImageView joinBottom2;// 3级连接线
		ImageView leaf2;// 3级子节点图
	}

}

ListView的item布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="horizontal" >
    <ImageView
        android:id="@+id/lv_item_tree_structure_tree"
        android:layout_width="20dp"
        android:layout_height="20dp"
        android:layout_gravity="center_vertical"
        android:scaleType="fitXY"
        android:src="@drawable/customer_account_mgr"
        android:visibility="gone" />
    <ImageView
        android:id="@+id/lv_item_tree_structure_join_bottom"
        android:layout_width="20dp"
        android:layout_height="20dp"
        android:layout_gravity="center_vertical"
        android:scaleType="fitXY"
        android:src="@drawable/joinbottom"
        android:visibility="gone" />
    <ImageView
        android:id="@+id/lv_item_tree_structure_leaf"
        android:layout_width="20dp"
        android:layout_height="20dp"
        android:layout_gravity="center_vertical"
        android:scaleType="fitXY"
        android:src="@drawable/leaf"
        android:visibility="gone" />
    <ImageView
        android:id="@+id/lv_item_tree_structure_join_bottom2"
        android:layout_width="20dp"
        android:layout_height="20dp"
        android:layout_gravity="center_vertical"
        android:scaleType="fitXY"
        android:src="@drawable/joinbottom"
        android:visibility="gone" />
    <ImageView
        android:id="@+id/lv_item_tree_structure_leaf2"
        android:layout_width="20dp"
        android:layout_height="20dp"
        android:layout_gravity="center_vertical"
        android:scaleType="fitXY"
        android:src="@drawable/leaf"
        android:visibility="gone" />
    <CheckBox
        android:id="@+id/lv_item_tree_structure_cb"
        style="@style/custom_checkbox"
        android:layout_width="30dp"
        android:layout_height="30dp"
        android:layout_gravity="center_vertical"
        android:layout_marginLeft="5dp"
        android:clickable="false" />
    <TextView
        android:id="@+id/lv_item_tree_structure_text"
        android:layout_width="400dp"
        android:layout_height="40dp"
        android:gravity="center_vertical"
        android:paddingLeft="10dp"
        android:textColor="@color/black"
        android:textSize="20sp" />
</LinearLayout>


父级标志图
子级标志图

父级和子级的连接线









  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值