ListView实现二级节点想必大家都知道可以用ExpandableListView 就可以轻松实现,但是要实现3级甚至多级菜单怎么实现呢? 再利用ExpandableListView 就会十分繁琐,今天我们来探究另一种实现方式来实现。
思路:每次点击展开子菜单 ,可以理解为 listView的一次重绘(数据更新<增加子节点数据>),而收起子菜单就是移除当前节点下的子数据,这是数据更新。对于界面每一个itemView的实现可以在adapter里面实现,根据没个子元素的级别,是否含有子节点,是否已经展开来配置不同的界面显示效果。首先来看实现的效果:
1:首先看子元素bean
package com.example.androidexpandablelistview;
import java.util.ArrayList;
import java.util.List;
/**
* 元素 可根据需要添加新的属性
* @author jrh
*
*/
public class TreeElement {
/**
* 各个元素的层级标识
*/
private int parentLevel;
/**
* 节点显示标题
*/
private String noteName;
/**
* 子节点元素集合
*/
private ArrayList<TreeElement> dataList = new ArrayList<TreeElement>();
/**
* 是否已扩展
*/
private boolean isExpandAble;
/**
* 是否有子节点元素
*/
private boolean isHasChild;
/**
* 当前节点位置
*/
private int position;
/**
*
* @param parentLevel 各个元素的层级标识
* @param noteName 节点显示标题
* @param dataList 子节点元素集合
* @param isExpandAble 是否已扩展
* @param isHasChild 是否有子节点元素
* @param 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;
}
}
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;
/**
* 处理点击 数据更新 通用
* @author jrh
*
*/
public class TreeAdapter extends BaseAdapter {
private List<TreeElement> mParentList;
private Context context;
public TreeAdapter(List<TreeElement> parentList, Context context) {
super();
this.mParentList = parentList;
this.context = context;
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return mParentList == null ? 0 : mParentList.size();
}
@Override
public Object getItem(int arg0) {
// TODO Auto-generated method stub
return mParentList == null ? null : mParentList.get(arg0);
}
@Override
public long getItemId(int arg0) {
// TODO Auto-generated method stub
return arg0;
}
@Override
public View getView(int arg0, View arg1, ViewGroup arg2) {
// TODO Auto-generated method stub
return null;
}
public void onExpandClick(int position) {
// 父节点没有子元素直接返回
if (!mParentList.get(position).isHasChild()) {
return;
}
// 父节点已经扩展
if (mParentList.get(position).isExpandAble()) {
mParentList.get(position).setExpandAble(false);
TreeElement element = mParentList.get(position);
// 遍历已扩展的元素,删除
ArrayList<TreeElement> temp = new ArrayList<TreeElement>();
// 从当前点的下一个元素开始隐藏
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 {
// 父节点为点开
TreeElement objElement = mParentList.get(position);
objElement.setExpandAble(true);
int level = objElement.getParentLevel();
int nextLevel = level + 1;
ArrayList<TreeElement> tempList = objElement.getDataList();
//扩充父类集合
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 <mParentList.size(); i++) {
mParentList.get(i).setPosition(i);
}
notifyDataSetChanged();
}
}
}
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;
/**
* 具体子adapter 可根据不同的要求自定义
* @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;
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return super.getCount();
}
@Override
public Object getItem(int arg0) {
// TODO Auto-generated method stub
return super.getItem(arg0);
}
@Override
public long getItemId(int arg0) {
// TODO Auto-generated method stub
return super.getItemId(arg0);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
// hodler 需为局部变量
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();
}
// "-"; "+";图标处理
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);
}
// 设置 展开 时,“-”、“+”间的连线
if (treeElement.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);
else
hodler.connection
.setBackgroundResource(R.drawable.knowledgetree_connection);
}
// 标题背景设置
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;
}
@Override
public void onExpandClick(int position) {
super.onExpandClick(position);
}
class ViewHodler {
ImageView icon;
TextView title;
RelativeLayout connection;
}
}
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;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
initView();
initData();
initEvent();
}
/**
* 事件处理
*/
private void initEvent() {
mLv.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
adapter.onExpandClick(arg2);
}
});
}
/**
* 数据加载
*/
private void initData() {
dataList = new ArrayList<TreeElement>();
seconddataList = new ArrayList<TreeElement>();
thirddataList = new ArrayList<TreeElement>();
adapter = new DetaiTreeAdapter(dataList, MainActivity.this);
mLv.setAdapter(adapter);
//模拟三级节点数据
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);
}
//模拟二级节点数据
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);
}
//模拟一级节点数据
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);
}
}
package com.example.androidexpandablelistview;
/**
* 模拟数据
* @author jrh
*
*/
public class Data {
public static String title[] = {"常识判断","言语理解","数量关系","判断推理","资料分析"};
public static String secondTitle[]={"政治","经济","法律","历史","人文"};
public static String thridTitle[] ={"时政","马克思主义哲学","中共党史","中国特色社会主义体系"};
}
<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>
<?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="wrap_content"
android:layout_height="fill_parent" >
<RelativeLayout
android:id="@+id/layout_treeview_connection"
android:layout_width="wrap_content"
android:layout_height="match_parent"
>
<ImageView
android:id="@+id/img_treeview_ico"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_centerInParent="true"
android:scaleType="fitXY"
android:contentDescription="@string/app_name" />
</RelativeLayout>
<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>
android ListView 实现3级节点 (可拓展N级)
原文:http://blog.csdn.net/jiaruihua_blog/article/details/43270125