the ListView Implementation of level Two nodes presumably everyone knows can be easily implemented with Expandablelistview, but to achieve level 3 or even multilevel menu how to achieve it? Re-use of Expandablelistview will be very cumbersome, today we explore another way to achieve.
Idea: Each Click to expand the submenu can be understood as a redraw of the ListView (Data Update < add child node data >), and the pick-up menu is to remove the sub-data under the current node, which is the data update. For the interface of each Itemview implementation can be implemented in the adapter, according to the level of no sub-element, whether it contains child nodes, whether has been expanded to configure a different interface display effect. First look at the effect of the implementation:
1: First look at the child element bean
Package Com.example.androidexpandablelistview;import java.util.arraylist;import java.util.list;/** * Elements can add new properties as needed * @author JRH * */public class Treeelement {/** * hierarchy identity of individual elements */private int parentlevel;/** * Node display title */private String notename /** * child node element collection */private arraylist<treeelement> dataList = new arraylist<treeelement> ();/** * Expanded */private Boolean isexpandable;/** * Whether there are child node elements */private Boolean ishaschild;/** * current node position */private int position;/** * @param pare Ntlevel the level identity of each element * @param notename node display title * @param dataList child node element collection * @param isexpandable expanded * @param ishaschild if there are any sub-sections Point element * @param position current node position */public treeelement (int parentlevel, String notename,arraylist<treeelement> dataList , Boolean isexpandable,boolean ishaschild, int position) {super (); this.parentlevel = Parentlevel;this.notename = Notename;this.datalist = datalist;this.isexpandable = Isexpandable;this.ishaschild = IsHasChild;this.position = Position;} public int getPosition () {return PositiOn;} public void setposition (int position) {this.position = position;} public Boolean ishaschild () {return ishaschild;} public void Sethaschild (Boolean ishaschild) {this.ishaschild = Ishaschild;} public int Getparentlevel () {return parentlevel;} public void Setparentlevel (int parentlevel) {this.parentlevel = Parentlevel;} Public String Getnotename () {return notename;} public void Setnotename (String notename) {this.notename = Notename;} Public arraylist<treeelement> getdatalist () {return dataList;} public void Setdatalist (arraylist<treeelement> dataList) {this.datalist = dataList;} public Boolean isexpandable () {return isexpandable;} public void Setexpandable (Boolean isexpandable) {this.isexpandable = isexpandable;}}
2: Data Update adapter
Package Com.example.androidexpandablelistview;import Java.util.arraylist;import Java.util.list;import Android.content.context;import Android.view.view;import Android.view.viewgroup;import Android.widget.BaseAdapter /** * Processing Click Data Update General * @author JRH * */public class Treeadapter extends Baseadapter {private list<treeelement> Mparen Tlist;private Context context;public treeadapter (list<treeelement> parentlist, context context) {super (); This.mparentlist = Parentlist;this.context = Context;} @Overridepublic int GetCount () {//TODO auto-generated method Stubreturn mparentlist = = null? 0:mparentlist.size ();} @Overridepublic Object getItem (int arg0) {//TODO auto-generated method Stubreturn mparentlist = null? null:mparentlis T.get (arg0);} @Overridepublic long getitemid (int arg0) {//TODO auto-generated method Stubreturn arg0;} @Overridepublic view GetView (int arg0, view arg1, ViewGroup arg2) {//TODO auto-generated method Stubreturn null;} public void Onexpandclick (int position) {//parent node does not have child elements directly returned if (!mparentlist.get (position). Ishaschild ()) {return;} The parent node has extended if (mparentlist.get (position). Isexpandable ()) {mparentlist.get (position). Setexpandable (false); treeelement element = Mparentlist.get (position);//traversal of extended elements, delete arraylist<treeelement> temp = new arraylist< Treeelement> ();//from the next element of the current point, hide for (int i = position + 1; i < mparentlist.size (); i++) {if (Element.getparentlevel ( ) >= Mparentlist.get (i). Getparentlevel ()) {break;} Temp.add (Mparentlist.get (i)); Mparentlist.removeall (temp); for (int i = position + 1; i < mparentlist.size (); i++) {Mparentlist.get (i). SetPosition (i) ;} Notifydatasetchanged ();} else {//parent node is point open treeelement objelement = mparentlist.get (position); objelement.setexpandable (true); int level = Objelement.getparentlevel (); int nextlevel = level + 1; arraylist<treeelement> templist = Objelement.getdatalist ();//Expand Parent class set for (int i = 0; i < templist.size (); i++) {Tre eelement element = Templist.get (i); Element.setparentlevel (nextlevel); elemenT.setexpandable (false); Mparentlist.add (position+1,element);} for (int i = position+1; I <mparentlist.size (); i++) {Mparentlist.get (i). SetPosition (i);} Notifydatasetchanged ();}}}
3: Specific Adaptation adapter
Package Com.example.androidexpandablelistview;import Java.util.list;import Android.content.context;import Android.graphics.color;import Android.graphics.drawable.layerdrawable;import Android.view.LayoutInflater;import Android.view.view;import Android.view.viewgroup;import Android.widget.imageview;import Android.widget.relativelayout;import android.widget.textview;/** * Specific sub-adapter can be customized according to different requirements * @author JRH * */public class Detaitreeadapter extends Treeadapter {private layoutinflater inflater;private list<treeelement> mParentList; Public Detaitreeadapter (list<treeelement> parentlist, context context) {Super (parentlist, context); Inflater = Layoutinflater.from (context); mparentlist = Parentlist;} @Overridepublic int GetCount () {//TODO auto-generated method Stubreturn Super.getcount ();} @Overridepublic Object getItem (int arg0) {//TODO auto-generated method Stubreturn Super.getitem (arg0);} @Overridepublic long getitemid (int arg0) {//TODO auto-generated method Stubreturn Super.getitEmId (arg0);} @Overridepublic view GetView (int position, view Convertview, ViewGroup parent) {//TODO auto-generated method stub//Hodle R needs to be local variable viewhodler hodler = new Viewhodler (); Treeelement treeelement = mparentlist.get (position), if (Convertview = = null) {Convertview = Inflater.inflate ( R.layout.itemview, null); Hodler.icon = (ImageView) Convertview.findviewbyid (r.id.ic_img); hodler.title = (TextView) Convertview.findviewbyid (R.ID.TITLE_TV); hodler.connection = (relativelayout) Convertview.findviewbyid (R.id.layout _treeview_connection); Convertview.settag (Hodler);} else {Hodler = (Viewhodler) Convertview.gettag ();} // "-"; "+"; the icon handles if (Treeelement.ishaschild ()) {if (treeelement.isexpandable ()) {if (treeelement.getparentlevel () = = 0) { Hodler.icon.setImageResource (r.drawable.knowledgetree_rootexpanded);} else {hodler.icon.setImageResource (r.drawable.knowledgetree_expanded);}} else {if (treeelement.getparentlevel () = = 0) {Hodler.icon.setImageResource (r.drawable.knowledgetree_rootunexpanded) ;} ElSE {hodler.icon.setImageResource (r.drawable.knowledgetree_unexpanded);}}} else {hodler.icon.setImageResource (r.drawable.knowledgetree_leaf);} When the setting is expanded, the lines between "-", "+" (treeelement.getparentlevel () = = 0) {if (position + 1 < GetCount () && Mparentlist.get (p Osition + 1). Getparentlevel () = = 0) {hodler.connection.setBackgroundResource (0);} else if (position + 1 = = GetCount ()) {Ho Dler.connection.setBackgroundResource (0);} else {hodler.connection.setBackgroundResource (r.drawable.knowledgetree_halfconnection_root);}} else {if (position + 1 < GetCount () && mparentlist.get (position + 1). Getparentlevel () = = 0) {hodler.connection.s Etbackgroundresource (r.drawable.knowledgetree_halfconnection_leaf);} else if (position = = GetCount ()-1) Hodler.connection.setBackgroundResource (r.drawable.knowledgetree_halfconnection_ leaf); Elsehodler.connection.setBackgroundResource (r.drawable.knowledgetree_connection);} Title Background Setting if (treeelement.getparentlevel () = = 0) {Hodler.title.setBackgroundColor (COlor. BLUE); hodler.title.setPadding (8, 8, 8, 8);} else if (treeelement.getparentlevel () = = 1) {Hodler.title.setBackgroundColor (color.red); Hodler.title.setPadding (38, 8, 8, 8);} else if (treeelement.getparentlevel () = = 2) {hodler.title.setPadding (8, 8, 8); Hodler.title.setBackgroundColor ( Color.gray);} Hodler.title.setTextColor (Color.White); Hodler.title.setText (Treeelement.getnotename ()); return Convertview;} @Overridepublic void Onexpandclick (int position) {Super.onexpandclick (position);} Class Viewhodler {ImageView icon; TextView title; Relativelayout Connection;}}
4: Main interface
Package Com.example.androidexpandablelistview;import Java.util.arraylist;import Android.os.bundle;import Android.app.activity;import Android.view.menu;import Android.view.view;import Android.view.Window;import Android.widget.adapterview;import Android.widget.adapterview.onitemclicklistener;import Android.widget.ListView; public class Mainactivity extends Activity {private ListView mlv;private detaitreeadapter adapter;private arraylist< treeelement> datalist;private arraylist<treeelement> seconddatalist;private ArrayList<TreeElement> thirddatalist; @Overrideprotected void OnCreate (Bundle savedinstancestate) {super.oncreate (savedinstancestate); Requestwindowfeature (Window.feature_no_title); Setcontentview (R.layout.activity_main); InitView (); InitData (); Initevent ();} /** * Event handling */private void Initevent () {Mlv.setonitemclicklistener (new Onitemclicklistener () {@Overridepublic void Onitemclick (adapterview<?> arg0, View arg1, int arg2,long arg3) {Adapter.onexpandclick (arg2);}});} /** * Data load */private void InitData () {dataList = new arraylist<treeelement> (); seconddatalist = new Arraylist<tre Eelement> (); thirddatalist = new arraylist<treeelement> (); adapter = new Detaitreeadapter (dataList, Mainactivity.this); Mlv.setadapter (adapter);//Analog three-level node data for (int i = data.thridtitle.length-1; I >=0; i--) { treeelement element = new Treeelement (2, Data.thridtitle[i], New arraylist<treeelement> (), False, False, I); Thirddatalist.add (element);} Analog two-level node data for (int i = data.secondtitle.length-1; I >=0; i--) {treeelement element = new Treeelement (1, DATA.SECONDTITL E[i],i = = 0? Thirddatalist:null, False,i = = 0? True:false, i); Seconddatalist.add (element);} Simulates the first-level node data for (int i = 0; i < Data.title.length; i++) {treeelement element = new Treeelement (0, data.title[i],i = 0?). Seconddatalist:null, false, I = = 0? True:false, i);d atalist.add (Element); Adapter.notifydatasetchanged ();} private void Initview () {mLv = (ListView) Findviewbyid (r.id.lv);}}
5: Analog Data
Package com.example.androidexpandablelistview;/** * Simulation Data * @author JRH * */public class Data {public static String title[] = {"Common sense", "verbal comprehension", "Quantitative relation", "Judgment Inference", "Data Analysis"};p ublic static String secondtitle[]={"politics", "economy", "Law", "History", "Humanities"};p ublic static String thridtitle[] ={"politics", "Marxist Philosophy", "CPC History", "socialist system with Chinese characteristics"};
6: Interface Layout
<relativelayout xmlns:android= "http://schemas.android.com/apk/res/android" xmlns:tools= "http// Schemas.android.com/tools " android:layout_width=" match_parent " android:layout_height=" Match_parent " > <listview android:id= "@+id/lv" android:layout_width= "wrap_content" android:layout_ height= "Wrap_content" /></relativelayout>
7:itemview
<?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=" match_parent "android:gravity=" Center|left " android:orientation= "Horizontal" android:paddingleft= "8DP" > <relativelayout android:layout_width= "WR Ap_content "android:layout_height=" fill_parent "> <relativelayout android:id=" @+id/layout_t Reeview_connection "android:layout_width=" wrap_content "android:layout_height=" Match_parent " > <imageview android:id= "@+id/img_treeview_ico" Android:layout_width= "W Rap_content "android:layout_height=" Match_parent "android:layout_centerinparent=" true " Android:scaletype= "Fitxy" android:contentdescription= "@string/app_name"/> </relativ Elayout> <imageview Android:id= "@+id/ic_img" android:layout_centerinparent= "true" android:layout_width= "Wrap_ Content "android:layout_height=" wrap_content "/> </RelativeLayout> <textview Android:id= "@+id/title_tv" android:layout_width= "wrap_content" android:layout_height= "Wrap_content" android:padding= "8DP" android:textsize= "18SP"/></linearlayout>
Sample code Download
Android ListView implements level 3 nodes (scalable to n-level)