Android ListView implements 3-level nodes (N-level extension)
The second-level node of ListView can be easily implemented by using ExpandableListView, but how to implement level 3 or even multi-level menus? Using ExpandableListView will be very cumbersome. Today we will explore another implementation method.
Idea: each time you click to expand the sub-menu, it can be understood as a re-painting of listView (data update <Add sub-node data>), and the receiving sub-menu is to remove sub-data under the current node, this is a data update. The implementation of each itemView on the interface can be implemented in the adapter. Depending on the level of NO sub-element, whether the sub-node is included or whether the sub-node has been expanded to configure different display effects on the interface. First, let's look at the implementation results:
1: first look at the child element bean
Package com. example. androidexpandablelistview; import java. util. arrayList; import java. util. list;/*** elements can add new attributes as needed * @ author jrh **/public class TreeElement {/*** hierarchical ID of each element */private int parentLevel; /*** node title */private String noteName;/*** subnode Element Set */private ArrayList
DataList = new ArrayList
();/*** Whether it has been extended */private boolean isExpandAble;/*** whether it has a subnode element */private boolean isHasChild; /*** current node position */private int position; /***** @ param parentLevel hierarchical ID of each element * @ param noteName node display title * @ param dataList sub-node Element Set * @ param isExpandAble whether it has been extended * @ param isHasChild sub-node element * @ param position current node location */public TreeElement (int parentLevel, string noteName, ArrayList
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
GetDataList () {return dataList;} public void setDataList (ArrayList
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 common * @ author jrh **/public class TreeAdapter extends BaseAdapter {private List
MParentList; private Context context; public TreeAdapter (List
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: mParentList. 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) {// 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); // traverses extended elements and deletes the ArrayList
Temp = new ArrayList
(); // 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);} policydatasetchanged ();} else {// The parent node is a vertex-open TreeElement objElement = mParentList. get (position); objElement. setExpandAble (true); int level = objElement. getParentLevel (); int nextLevel = level + 1; ArrayList
TempList = objElement. getDataList (); // expands the parent class set for (int I = 0; I <tempList. size (); I ++) {TreeElement element = tempList. get (I); element. setParentLevel (nextLevel); element. setExpandAble (false); mParentList. add (position + 1, element) ;}for (int I = position + 1; I
3: 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;/*** the specific sub-adapter can be customized according to different requirements * @ author jrh **/public class DetaiTreeAdapter extends TreeAdapter {private LayoutInflater inflater; private List
MParentList; public DetaiTreeAdapter (List
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 // The hodler must be the 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 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);} // sets the line if (treeElement) between "-" and "+" when expanding. getParentLevel () = 0) {if (position + 1 <getCount () & mParentList. get (position + 1 ). getParentLevel () = 0) {hodler. connection. setBackgroundResource (0);} else if (position + 1 = getCount () {hodler. 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. setBackgroundResource (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);} // set the title background 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 (78, 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
DataList; private ArrayList
SeconddataList; private ArrayList
ThirddataList; @ Overrideprotected void onCreate (Bundle savedInstanceState) {super. onCreate (savedInstanceState); requestWindowFeature (Window. FEATURE_NO_TITLE); setContentView (R. layout. activity_main); initView (); initData (); initEvent ();}/*** event processing */private void initEvent () {mLv. setOnItemClickListener (new OnItemClickListener () {@ Overridepublic void onItemClick (AdapterView
Arg0, View arg1, int arg2, long arg3) {adapter. onExpandClick (arg2) ;}}) ;}/ *** data loading */private void initData () {dataList = new ArrayList
(); SeconddataList = new ArrayList
(); ThirddataList = new ArrayList
(); Adapter = new DetaiTreeAdapter (dataList, MainActivity. this); mLv. setAdapter (adapter); // simulate third-level node Data for (int I = Data. thridTitle. length-1; I> = 0; I --) {TreeElement element = new TreeElement (2, Data. thridTitle [I], new ArrayList
(), False, false, I); thirddataList. add (element);} // simulate second-level node Data for (int I = Data. secondTitle. length-1; I> = 0; I --) {TreeElement element = new TreeElement (1, Data. secondTitle [I], I = 0? ThirddataList: null, false, I = 0? True: false, I); seconddataList. add (element);} // simulate 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); dataList. add (element);} adapter. notifyDataSetChanged ();} private void initView () {mLv = (ListView) findViewById (R. id. lv );}}
5. Simulate data
Package com. example. androidexpandablelistview;/*** simulate Data ** @ author jrh **/public class Data {public static String title [] = {common sense judgment, verbal understanding, quantitative relationship, judgment reasoning, data analysis}; public static String secondTitle [] = {political, economic, legal, historical, humanistic}; public static String thridTitle [] = {current political, Marxist philosophy, Communist Party history, socialism with Chinese Characteristics };}
6. Interface Layout
7: itemView