Directly attached code, the code has the corresponding comments:
The main interface activity, the layout is only one listview:
public class Mainactivity extends activity {private ListView Mlistview; private treelistviewadapter<testbean> Mada
Pter;
Private list<testbean> Mdatas = new arraylist<testbean> (); @Override protected void OnCreate (Bundle savedinstancestate) {//TODO auto-generated Method stub super.oncreate (savedins
Tancestate);
Setcontentview (R.layout.activity_main);
This.mlistview = (ListView) Findviewbyid (R.id.listview);
Inittestdatas (); try {madapter = new treelistviewadapter<testbean> (Mlistview, this, Mdatas, 0);} catch (Exception e) {E.printstack
Trace ();
} this.mListView.setAdapter (Madapter); Madapter.setmtreelistener (New Treeviewonitemclick () {@Override public void Ontreeitemclick (int position, node node) {T
Oast.maketext (Mainactivity.this, "What you clicked is:" + node.getname (), Toast.length_short). Show ();
}
}); This.mListView.setOnItemLongClickListener (New Onitemlongclicklistener () {@Override public boolean Onitemlongclick ( Adapterview<?> arg0, View arg1, final int aRG2, long Arg3) {final EditText EDT = new EditText (mainactivity.this), New Alertdialog.builder (mainactivity.this). Settit Le ("Insert"). Setview (EDT). Setpositivebutton ("Submit", new Onclicklistener () {@Override public void OnClick ( Dialoginterface dialog, int which) {if (Textutils.isempty (Edt.gettext (). toString ())) {Toast.maketext (
Mainactivity.this, "Please fill in Add Content", Toast.length_short. Show ();
else {madapter.insertnodedata (arg2, Edt.gettext (). toString ());
}). Setnegativebutton ("Cancel", null). Create (). Show ();
return true;
}
}); private void Inittestdatas () {Testbean bean = null; bean = new Testbean (1, 0, "file directory 1"); Mdatas.add (bean); bean = new
Testbean (2, 0, "file directory 2");
Mdatas.add (Bean);
Bean = new Testbean (3, 0, "file directory 3");
Mdatas.add (Bean);
Bean = new Testbean (4, 1, "file directory 4");
Mdatas.add (Bean);
Bean = new Testbean (5, 1, "file directory 5");
Mdatas.add (Bean);
Bean = new Testbean (6, 2, "file directory 6");
Mdatas.add (Bean);
Bean = new Testbean (7, 2, "file directory 7");
Mdatas.add (Bean); Bean = new Testbean (8, 3, "file directory")8 ");
Mdatas.add (Bean);
Bean = new Testbean (9, 3, "file directory 9");
Mdatas.add (Bean);
Bean = new Testbean (10, 0, "file directory 10");
Mdatas.add (Bean);
}
}
Data adapter base class:
* * Tree ListView Data Adapter class * @description: * @author LDM * @date 2015-10-9 a.m. 9:47:01 * * Public abstract class TREEVIEWBA Seadapter<t> extends Baseadapter {protected context; protected list<t> datas; protected List<node
> mallnodes;
protected list<node> mvisiblenodes;
protected Layoutinflater Minflater;
protected ListView Treelv;
protected Treeviewonitemclick Mtreelistener; Public Treeviewbaseadapter (ListView Treelv, context, list<t> datas, int defaultexpandlevel) throws Illegalaccessexception, illegalargumentexception {this.context = context; This.treelv = Treelv; mInflater = LayoutInflat
Er.from (context);
Mallnodes = Treehelpertools.getsortednodes (datas, defaultexpandlevel);
Mvisiblenodes = Treehelpertools.filtervisiblenodes (mallnodes); This.treeLv.setOnItemClickListener (New Onitemclicklistener () {@Override public void Onitemclick (ADAPTERVIEW<? > arg0, View arg1, int position, long Arg3) {expandorcollapse (position); if (MtreelisTener!=null) {Mtreelistener.ontreeitemclick (position, mvisiblenodes.get (position));}
});
public void Setmtreelistener (Treeviewonitemclick mtreelistener) {this.mtreelistener = Mtreelistener;} /** * Settings ListView Click the Item node should be expanded * @description: * @author LDM * @date 2015-10-10 a.m. 9:05:08 * * protected void Expandorcoll Apse (int position) {Node n=mvisiblenodes.get (position); if (n!=null) {if (N.isleaf ()) {return;} n.setexpand (!n.isexpand
());
Mvisiblenodes=treehelpertools.filtervisiblenodes (Mallnodes);
Notifydatasetchanged ();
@Override public int GetCount () {//TODO auto-generated Method stub return Mvisiblenodes.size ();}
@Override public Object getitem (int position) {//TODO auto-generated Method stub return Mvisiblenodes.get (position);}
@Override public long getitemid (int position) {//TODO auto-generated method stub return position;} @Override public View getview (int position, View Convertview, ViewGroup parent) {Node node=mvisiblenodes.get (position); Onvertview = Getcontentview (Node,position, Convertview, parent);
return convertview;
Public abstract View Getcontentview (Node node,int position, View Convertview, viewgroup parent);
public interface treeviewonitemclick{void Ontreeitemclick (int position,node Node);}
The adapter we use
public class Treelistviewadapter<t> extends treeviewbaseadapter<t> {public Treelistviewadapter (ListView T Reelv, Context, list<t> datas, int defaultexpandlevel) throws Illegalaccessexception,
illegalargumentexception {Super (Treelv, Context, datas, defaultexpandlevel);} @Override Public View Getcontentview (node node, int position, View Convertview, ViewGroup parent) {Viewholder holder = Nu
ll if (Convertview = = null) {holder = new Viewholder (); Convertview = Minflater.inflate (R.layout.tree_listview_item, parent,
FALSE);
HOLDER.MITEMIV = (ImageView) Convertview.findviewbyid (R.ID.MITEMIV);
HOLDER.MITEMTV = (TextView) Convertview.findviewbyid (R.ID.MITEMTV);
Convertview.settag (holder);
else {holder = (Viewholder) Convertview.gettag ();} holder.mItemIv.setPadding (Node.getlevel () *30, 3, 3, 3); if (node.geticon () = = 1) {holder.mItemIv.setVisibility (view.invisible);} else {holder.mItemIv.setVisibility (
view.visible); Holder.mItemIv.setImageResource (node. GetIcon ());
} holder.mItemTv.setText (Node.getname ());
return convertview;
private static class Viewholder {ImageView mitemiv;
TextView MITEMTV; /** * Insert Data dynamically * @description: * @author LDM * @date 2015-10-10 a.m. 10:08:03/public void insertnodedata (int position,st
Ring label {node node=mvisiblenodes.get (position); int indexof=mallnodes.indexof (node);
Node Insertnode=new node ( -1, Node.getid (), label);
Insertnode.setparent (node);
Node.getchildren (). Add (Insertnode);
Mallnodes.add (Indexof+1,insertnode);
Mvisiblenodes=treehelpertools.filtervisiblenodes (Mvisiblenodes);
Notifydatasetchanged ();
}
}
Tool classes for data processing:
public class Treedatashelpertools {/** * Converts user-supplied data to available data at the tree level * @description: * @date 2015-10-9 PM 4:07:24 * * Public Stati C <T> list<node> datas2nodes (list<t> datas) throws Illegalaccessexception, IllegalArgumentException
{list<node> nodes = new arraylist<node> ();
node node = null;
for (T t:datas) {int id =-1; int pid =-1;
String label = "";
node = new node ();
Class clazz = T.getclass (); field[] fields = Clazz.getdeclaredfields ();//Reflection Gets the field in the class for (field Field:fields) {if field.getannotation (treenodeid.cl Ass) {////!=) {///////////////////////////////////////////////////////////
Field.getint (t); } if (Field.getannotation (treenodepid.class)!= null) {field.setaccessible (true); pid = Field.getint (t);} if (Field.geta
Nnotation (Treenodelabel.class)!= null) {field.setaccessible (true); label = (String) field.get (t);}
node = new node (ID, PID, label);
Nodes.Add (node); //Set Parent-child node relationship in nodes for (int i = 0; I &Lt 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 () = = N.G Etid ()) {//if M's parent node Pid==n ID, then M is the parent node, n is a child node N.getchildren (). Add (M); M.setparent (n);} else if (m.getid () = = N.getpid ()) {m.
GetChildren (). Add (n);
N.setparent (m);
}}//Set node picture for (nodes N:nodes) {Setnodeicon (n);} return nodes; /** * Set the corresponding icon for our Node data * @description: * @date 2015-10-9 PM 4:46:29 * * private static void Setnodeicon (node n) {if (n . GetChildren (). Size () > 0 && n.isexpand ()) {//If there are child nodes and the expanded state N.seticon (r.drawable.icon_unable);} else if (n.get
Children (). Size () > 0 &&!n.isexpand ()) {N.seticon (r.drawable.icon_enable);} else {N.seticon (-1);}} public static <T> list<node> getsortednodes (list<t> datas, int defaultexpandlevel) throws
Illegalaccessexception, illegalargumentexception {list<node> result = new arraylist<node> ();
list<node> nodes = Datas2nodes (datas); Get root section FirstPoint data list<node> rootnodes = getrootnodes (nodes);
for (node Node:rootnodes) {AddNode (Result, node, defaultexpandlevel, 1);
}
/** * Get all the root node data in the data * @description: * @date 2015-10-9 pm 5:00:32/private static list<node> Getrootnodes (list<n Ode> nodes) {list<node> root = new arraylist<node> (); for (Node node:nodes) {if (Node.isroot ()) {root.
Add (node);
} return root; /** * Get to the Visible node data * @description: * @date 2015-10-9 PM 5:12:58 * * public static list<node> Filtervisiblenodes (List <Node> mallnodes) {list<node> nodes = new arraylist<node> (); for (Node node:mallnodes) {if (NODE.ISR Oot () | |
Node.isparentexpand ()) {Setnodeicon (node); Nodes.Add (node);}}
return nodes; /** * Put all child nodes of a node into result * @description: * @date 2015-10-9 pm 5:05:57/private static void AddNode (List<node> ; result, node node, int defaultexpandlevel, int currentlevel) {result.add (node); if (Defaultexpandlevel >= currentlevel {Node.setexpand (true);} if (Node.isleaf ()) {return;} for (int i = 0; i < Node.getchildren (). Size (); i++) {Addnod E (result, Node.getchildren (). get (i), defaultexpandlevel, CurrentLevel + 1);
}
}
}
Data Entity Bean:
public class Testbean {
@TreeNodeId
private int id;//add corresponding annotations
@TreeNodePid
private int pid;
@TreeNodeLabel
private String label;
Private String desc;
public Testbean (int id, int pid, String label) {
super ();
This.id = ID;
This.pid = pid;
This.label = label;
}
Public Testbean () {
//TODO auto-generated constructor stub
} public
int getId () {return
ID;
} Public
void setId (int id) {
this.id = ID;
}
public int getpid () {return
pid;
}
public void setpid (int pid) {
this.pid = pid;
}
Public String Getlabel () {return
label;
}
public void SetLabel (String label) {
this.label = label;
}
Public String GetDesc () {return
desc;
}
public void Setdesc (String desc) {
THIS.DESC = desc;
}
}
The node class in the data display, we can map any entity bean such as testbean into the node we want by reflection + annotation
public class Node {private int id;//node ID private int pid = 0;//parent Node ID private Strin G name;//corresponding content private int level;//ListView Tree Level Private Boolean isexpand = false;//where node expands private int icon;//icon ico N Private node parent;//parent node Private list<node> children = new arraylist<node> ()//corresponding child node dataset public node (
{} public Node (int id, int pid, String name) {this.id = id; this.pid = pid; this.name = name;}
public int getId () {return ID;}
public void setId (int id) {this.id = ID;}
public int getpid () {return PID;}
public void setpid (int pid) {this.pid = pid;}
Public String GetName () {return name;}
public void SetName (String name) {this.name = name;}
/** * The level of the current node * @description: * @date 2015-10-9 PM 4:02:29/public int getlevel () {return parent = = null? 0:parent
. Getlevel () + 1;
public void Setlevel (int level) {this.level = level;}
public Boolean Isexpand () {return isexpand;} public void Setexpand (Boolean isexpand) {This.isexpand = Isexpand; if (!isexpand && children.size () > 0) {//AS
If the current node is not expanded, its child node expansion state is also: not expanded for (node Node:children) {Node.setexpand (false);}}
public int GetIcon () {return icon;}
public void SetIcon (int icon) {This.icon = icon;}
Public Node GetParent () {return parent;}
public void SetParent (Node parent) {this.parent = parent;}
Public list<node> GetChildren () {return children;}
public void Setchildren (list<node> children) {This.children = children;} /** * To determine whether the current node has child nodes * @description: * @author ldm * @date 2015-10-9 PM 3:59:42/public boolean isleaf () {return children.
Size () = = 0; /** * is not a root node * @description: * @author LDM * @date 2015-10-9 pm 3:58:15/public boolean isRoot () {return parent = = NULL;} /** * The parent node of the current node expands * @description: * @author ldm * @date 2015-10-9 PM 3:58:34 * * Public boolean Isparentexpand () {if (par
ENT = = null) {return false;} else {return Parent.isexpand}}}
}
annotation classes to use:
@Target (Elementtype.field)//Defines the purpose of the annotation: field, constant of the enumeration
@Retention (retentionpolicy.runtime)//annotation policy: annotations exist in the class bytecode file , the public
@interface Treenodeid {} can be obtained by reflection at run time
@Target (Elementtype.field)//Defines the purpose of the annotation: field, constant of the enumeration
@Retention (retentionpolicy.runtime)//annotation policy: annotations exist in the class bytecode file , the public
@interface Treenodelabel {
}
' can be obtained by reflection at run time
@Target (Elementtype.field)//Defines the purpose of the annotation: field, constant of the enumeration
@Retention (retentionpolicy.runtime)//Annotation policy: Annotations exist in the class bytecode file and can be obtained by reflection to public
@interface treenodepid {
}
The above is the android to achieve the tree-level listview of the relevant code, I hope to help you learn.