點擊上方「Android編程精選」,選擇「置頂公眾號」
關鍵時刻,第一時間送達!
先不說楚楓的這般年紀,能夠踏入元武一重說明了什麼,最主要的是,楚楓在剛剛踏入核心地帶時,明明只是靈武七重,而在這兩個月不到的時間,連跳兩重修為,又跳過一個大境界,踏入了元武一重,這般進步速度,簡直堪稱變態啊。
「這楚楓不簡單,原來是一位天才,若是讓他繼續成長下去,絕對能成為一號人物,不過可惜,他太狂妄了,竟與龔師兄定下生死約戰,一年時間,他再厲害也無法戰勝龔師兄。」有人認識到楚楓的潛力後,為楚楓感到惋惜。
「哼,何須一年,此子今日就必敗,巫九與龔師兄關係甚好,早就看他不順眼了,如今他竟敢登上生死臺挑戰巫九,巫九豈會放過他?」但也有人認為,楚楓今日就已是在劫難逃。
「何人挑戰老子?」就在這時,又是一聲爆喝響起,而後一道身影自人群之中掠出,最後穩穩的落在了比鬥臺上。
這位身材瘦弱,身高平平,長得那叫一個猥瑣,金鉤鼻子蛤蟆眼,嘴巴一張牙帶色兒,說話臭氣能傳三十米,他若是當面對誰哈口氣,都能讓那人跪在地上狂嘔不止。
不過別看這位長得不咋地,他在核心地帶可是鼎鼎有名,劍道盟創建者,青龍榜第九名,正是巫九是也。
「你就是巫九?」楚楓眼前一亮,第一次發現,世間還有長得如此奇葩的人。
巫九鼻孔一張,大嘴一咧,拍著那乾癟的肚子,得意洋洋的道:「老子就是巫九,你挑戰老子?」
「不是挑戰你,是要宰了你。」楚楓冷聲笑道。
「好,老子滿足你這個心願,長老,拿張生死狀來,老子今日在這裡了解了這小子。」巫九扯開嗓子,對著下方吼了一聲。
如果他對內門長老這麼說話,也就算了,但是敢這麼跟核心長老說話的,他可真是算作膽肥的,就連許多核心弟子,都是倒吸了一口涼氣,心想這楚楓夠狂,想不到這巫九更狂。
不過最讓人無言的就是,巫九話音落下不久,真有一位核心長老自人群走出,緩緩得來到了比鬥臺上,左手端著筆墨,右手拿著生死狀,來到了巫九的身前。
「我去,這巫九什麼身份,竟能這般使喚核心長老?」有人吃驚不已,那長老修為不低,乃是元武七重,比巫九還要高兩個層次,但卻這般聽巫九的話,著實讓人吃驚不已。
「這你就不知道了吧,巫九在前些時日,拜了鍾離長老為師尊,已正式得到鍾離長老的親傳。」有人解釋道。
「鍾離長老?可是那位性情古怪的鐘離一護?」
「沒錯,就是他。」
「天哪,巫九竟然拜入了他的門下?」
人們再次大吃一驚,那鍾離一護在青龍宗可是赫赫有名,若要是論其個人實力,在青龍宗內絕對能夠排入前三,連護宗六老單打獨鬥都不會是他的對手。
只不過那鍾離一護,如同諸葛青雲一樣,也是一位客卿長老,所以在青龍宗內只是掛個頭銜,什麼事都不管,更別說傳授宗內弟子技藝了,如今巫九竟然能拜入他老人家門下,著實讓人羨慕不已。
「恩怨生死臺,的確可以決鬥生死,但必須要有所恩怨,你們兩個人,可有恩怨?」那位長老開口詢問道。
作者:她的夢zAndroid編程精選整理髮布,轉載請聯繫作者獲得授權
實在不知道說什麼好了,這個東西以前也沒做過,這兩天公司有這方面的需求,就實現一下,然後把功能跟大家分享一下,以後有需要直接拿去用就好。先上個圖表達一下我此時的心情,畢竟已經完成要求了···
效果展示:
分析一波:
1.層級父節點與子節點的關聯
2.布局的復用
3.層級展開與關閉,顯示與隱藏問題
4.checkbox的標記勾選
功能的初步準備具體的代碼mean,項目注釋都有··
一、數據的實體類
public class Node<T, B> {
private String title;
private String bmid;
private String content;
private String code;
private String childBmid;
public B bean;
private T id;
private T pId;
private String name;
private int level;
private boolean isExpand = false;
private List<Node> children = new ArrayList<>();
private Node parent;
private boolean isChecked;
public Node() {
}
public Node(T id, T pId, String name) {
super();
this.id = id;
this.pId = pId;
this.name = name;
}
public Node(T id, T pId, String name, B bean) {
super();
this.id = id;
this.pId = pId;
this.name = name;
this.bean = bean;
}
public boolean isChecked() {
return isChecked;
}
public void setChecked(boolean isChecked) {
this.isChecked = isChecked;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getBmid() {
return bmid;
}
public void setBmid(String bmid) {
this.bmid = bmid;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getChildBmid() {
return childBmid;
}
public void setChildBmid(String childBmid) {
this.childBmid = childBmid;
}
public T getId() {
return id;
}
public void setId(T id) {
this.id = id;
}
public T getpId() {
return pId;
}
public void setpId(T pId) {
this.pId = pId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void setLevel(int level) {
this.level = level;
}
public boolean isExpand() {
return isExpand;
}
public List<Node> getChildren() {
return children;
}
public void setChildren(List<Node> children) {
this.children = children;
}
public Node getParent() {
return parent;
}
public void setParent(Node parent) {
this.parent = parent;
}
public boolean isRoot() {
return parent == null;
}
public boolean isParentExpand() {
if (parent == null)
return false;
return parent.isExpand();
}
public boolean isLeaf() {
return children.size() == 0;
}
public int getLevel() {
return parent == null ? 0 : parent.getLevel() + 1;
}
public void setExpand(boolean isExpand) {
this.isExpand = isExpand;
if (!isExpand) {
for (Node node : children) {
node.setExpand(isExpand);
}
}
}
}
二、設置節點關係
public class TreeHelper {
public static List<Node> getSortedNodes(List<Node> datas,
int defaultExpandLevel) {
List<Node> result = new ArrayList<Node>();
List<Node> nodes = convetData2Node(datas);
List<Node> rootNodes = getRootNodes(nodes);
for (Node node : rootNodes) {
addNode(result, node, defaultExpandLevel, 1);
}
return result;
}
public static List<Node> filterVisibleNode(List<Node> nodes) {
List<Node> result = new ArrayList<Node>();
for (Node node : nodes) {
if (node.isRoot() || node.isParentExpand()) {
result.add(node);
}
}
return result;
}
private static List<Node> convetData2Node(List<Node> nodes) {
for (int i = 0; i < nodes.size(); i++) {
Node n = nodes.get(i);
for (int j = i + 1; j < nodes.size(); j++) {
Node m = nodes.get(j);
if (m.getpId() instanceof String) {
if (m.getpId().equals(n.getId())) {
n.getChildren().add(m);
m.setParent(n);
} else if (m.getId().equals(n.getpId())) {
m.getChildren().add(n);
n.setParent(m);
}
} else {
if (m.getpId() == n.getId()) {
n.getChildren().add(m);
m.setParent(n);
} else if (m.getId() == n.getpId()) {
m.getChildren().add(n);
n.setParent(m);
}
}
}
}
return nodes;
}
private static List<Node> getRootNodes(List<Node> nodes) {
List<Node> root = new ArrayList<Node>();
for (Node node : nodes) {
if (node.isRoot())
root.add(node);
}
return root;
}
private static <T, B> void addNode(List<Node> nodes, Node<T, B> node,
int defaultExpandLeval, int currentLevel) {
nodes.add(node);
if (defaultExpandLeval >= currentLevel) {
node.setExpand(true);
}
if (node.isLeaf())
return;
for (int i = 0; i < node.getChildren().size(); i++) {
addNode(nodes, node.getChildren().get(i), defaultExpandLeval,
currentLevel + 1);
}
}
}
三、Adapter的封裝
public abstract class TreeListViewAdapter extends BaseAdapter {
protected Context mContext;
protected List<Node> mNodes = new ArrayList<>();
protected LayoutInflater mInflater;
protected List<Node> mAllNodes = new ArrayList<>();
public TreeListViewAdapter(ListView mTree, Context context, List<Node> datas,
int defaultExpandLevel) {
mContext = context;
mAllNodes = TreeHelper.getSortedNodes(datas, defaultExpandLevel);
mNodes = TreeHelper.filterVisibleNode(mAllNodes);
mInflater = LayoutInflater.from(context);
mTree.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
expandOrCollapse(position);
}
});
}
public void expandOrCollapse(int position) {
Node n = mNodes.get(position);
if (n != null) {
if (!n.isLeaf()) {
n.setExpand(!n.isExpand());
mNodes = TreeHelper.filterVisibleNode(mAllNodes);
notifyDataSetChanged();
}
}
}
@Override
public int getCount() {
return mNodes.size();
}
@Override
public Object getItem(int position) {
return mNodes.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
Node node = mNodes.get(position);
convertView = getConvertView(node, position, convertView, parent);
convertView.setPadding(node.getLevel() * 50, 3, 3, 3);
return convertView;
}
protected void setChecked(final Node node, boolean checked) {
node.setChecked(checked);
setChildChecked(node, checked);
if (node.getParent() != null)
setNodeParentChecked(node.getParent(), checked);
notifyDataSetChanged();
}
public <T, B> void setChildChecked(Node<T, B> node, boolean checked) {
if (!node.isLeaf()) {
node.setChecked(checked);
for (Node childrenNode : node.getChildren()) {
setChildChecked(childrenNode, checked);
}
} else {
node.setChecked(checked);
}
}
private void setNodeParentChecked(Node node, boolean checked) {
if (checked) {
node.setChecked(checked);
if (node.getParent() != null)
setNodeParentChecked(node.getParent(), checked);
} else {
List<Node> childrens = node.getChildren();
boolean isChecked = false;
for (Node children : childrens) {
if (children.isChecked()) {
isChecked = true;
}
}
if (!isChecked) {
node.setChecked(checked);
}
if (node.getParent() != null)
setNodeParentChecked(node.getParent(), checked);
}
}
public abstract View getConvertView(Node node, int position,
View convertView, ViewGroup parent);
}
一、布局代碼
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:descendantFocusability="blocksDescendants"
android:orientation="horizontal">
<CheckBox
android:id="@+id/check_box"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_gravity="center_vertical"
android:layout_marginLeft="10dp"
android:background="@drawable/screen_check_box_style"
android:button="@null" />
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:paddingBottom="10dp"
android:paddingTop="10dp">
<TextView
android:id="@+id/tv_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:gravity="center_vertical"
android:text="項目"
android:textColor="#000000"
android:textSize="18sp" />
</LinearLayout>
</LinearLayout>
二、Adapter
public class SimpleTreeAdapter extends TreeListViewAdapter {
private onNodeDataListener onNodeDataListener;
public SimpleTreeAdapter(ListView mTree, Context context, List<Node> datas, int defaultExpandLevel) {
super(mTree, context, datas, defaultExpandLevel);
}
@Override
public View getConvertView(final Node node, int position, View convertView, ViewGroup parent) {
final ViewHolder holder;
if (convertView == null) {
convertView = mInflater.inflate(R.layout.item_tree_title, parent, false);
holder = new ViewHolder();
holder.tvName = (TextView) convertView.findViewById(R.id.tv_name);
holder.cb = (CheckBox) convertView.findViewById(R.id.check_box);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.cb.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
setChecked(node, holder.cb.isChecked());
onNodeDataListener.onNodeDataListener(node);
}
});
if (node.isChecked()) {
holder.cb.setChecked(true);
holder.tvName.setTextColor(Color.parseColor("#1FCC7C"));
} else {
holder.cb.setChecked(false);
holder.tvName.setTextColor(Color.parseColor("#000000"));
}
holder.tvName.setText(node.getName());
return convertView;
}
class ViewHolder {
TextView tvName;
CheckBox cb;
}
public void setNodeDataListener(onNodeDataListener setNodeDataListener) {
this.onNodeDataListener = setNodeDataListener;
}
public interface onNodeDataListener {
void onNodeDataListener(Node node);
}
}
聲明
private List<Node> mDatas = new ArrayList<>();
private List<Node> mResultDatas = new ArrayList<>();
private SimpleTreeAdapter mAdapter;
root節點:
List<DepartMentForm> rootList = daoSession.getDepartMentFormDao().queryBuilder().where(DepartMentFormDao.Properties.Id.eq(unit)).list();
Node root = new Node();
String rootId = rootList.get(0).getId();
root.setId(rootId);
root.setpId(0);
root.setName(rootList.get(0).getName());
mDatas.add(root);
數據源我直接用的我們公司的,這裡我就介紹一下數據源的節點關聯。
pid作為根的節點值。
rootId為當前節點的id值,為下級節點的父節點值
name就是當前節點的名稱
二層下級節點:
Node secondNode = new Node();
String secondId = secondData.get(i).getId();
secondNode.setId(secondId);
secondNode.setpId(rootId);
secondNode.setName(secondData.get(i).getName()); mDatas.add(secondNode);
pid為父節點的id值
id為下級節點的父節點值
三層下級節點:
Node threeNode = new Node();
String threeId = three.get(j).getId();
threeNode.setId(threeId);
threeNode.setpId(secondId);
threeNode.setName(three.get(j).getName());
mDatas.add(threeNode);
checkbox的監聽
/給 ListView 設置 Adapter
mAdapter = new SimpleTreeAdapter(mListview, mContext, mDatas, 10);
mListview.setAdapter(mAdapter);
mAdapter.setNodeDataListener(new SimpleTreeAdapter.onNodeDataListener() {
@Override
public void onNodeDataListener(Node node) {
這塊文字沒注釋,沒注釋看的清楚 0.0
node返回的是當前的節點數據的值
因為所有的節點數據都已經掛在node上了,
所有在node中可以看到當前節點的parent值,以及子節點值,為null代表沒有
結構我說清楚了,具體的這個check怎麼處理,看你們需求,我就不多說了。
}
});
over,基本就這些
附送源碼小demo:https://github.com/BINBINXIAO/TreeDemo