Android多级树形列表控件
我们开发app过程中,经常会碰到需要多级列表展⽰的效果。⽽Android原⽣sdk中根本没有3级 4级甚⾄更多级别的列表控件。
所以我们就要⾃⼰去实现⼀个类似treeListView 的控件,下⾯这个是我项⽬中的⼀个效果图,可⽀持多级列表扩展。
android中有ExpandListView控件,但是这个控件只⽀持两级列表。对于多级列表如果重写这个不是很好⽤。
实现这种列表思想就是递归,构造⼀个⼦⽗级的关系。
话不多说代码中体会
Activity
ample.customtreeviewdemo;
import java.util.ArrayList;
import java.util.List;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ListView;
import android.widget.Toast;
ample.customtreeviewdemo.bean.MyNodeBean;
Node;
TreeListViewAdapter.OnTreeNodeClickListener;
public class MainActivity extends Activity {
private ListView treeLv;
private Button checkSwitchBtn;
private MyTreeListViewAdapter<MyNodeBean> adapter;
private List<MyNodeBean> mDatas = new ArrayList<MyNodeBean>();
/
/标记是显⽰Checkbox还是隐藏
private boolean isHide = true;
@Override
protected void onCreate(Bundle savedInstanceState) {
setContentView(R.layout.activity_main);
initDatas();
treeLv = (ListView) this.findViewById(_lv);
checkSwitchBtn = (Button)this.findViewById(R.id.check_switch_btn);
checkSwitchBtn.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View v) {
if(isHide){
isHide = false;
}else{
isHide = true;
}
adapter.updateView(isHide);
}
});
try {
adapter = new MyTreeListViewAdapter<MyNodeBean>(treeLv, this,
mDatas, 10, isHide);
adapter.setOnTreeNodeClickListener(new OnTreeNodeClickListener() {
@Override
public void onClick(Node node, int position) {
if (node.isLeaf()) {
Toast.makeText(getApplicationContext(), Name(),
Toast.LENGTH_SHORT).show();
}
}
@Override
public void onCheckChange(Node node, int position,
List<Node> checkedNodes) {
StringBuffer sb = new StringBuffer();
for (Node n : checkedNodes) {
int pos = n.getId() - 1;
sb.(pos).getName()).append("---")
.append(pos + 1).append(";");
}
Toast.makeText(getApplicationContext(), sb.toString(),
Toast.LENGTH_SHORT).show();
}
});
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
treeLv.setAdapter(adapter);
}
private void initDatas() {
mDatas.add(new MyNodeBean(1, 0, "中国古代"));
mDatas.add(new MyNodeBean(2, 1, "唐朝"));
mDatas.add(new MyNodeBean(3, 1, "宋朝"));
mDatas.add(new MyNodeBean(4, 1, "明朝"));
mDatas.add(new MyNodeBean(5, 2, "李世民"));
mDatas.add(new MyNodeBean(6, 2, "李⽩"));
mDatas.add(new MyNodeBean(7, 3, "赵匡胤"));
mDatas.add(new MyNodeBean(8, 3, "苏轼"));
mDatas.add(new MyNodeBean(9, 4, "朱元璋"));
mDatas.add(new MyNodeBean(10, 4, "唐伯虎"));
mDatas.add(new MyNodeBean(11, 4, "⽂征明"));
mDatas.add(new MyNodeBean(12, 7, "赵建⽴"));
mDatas.add(new MyNodeBean(13, 8, "苏东东"));
mDatas.add(new MyNodeBean(14, 10, "秋⾹"));
listview控件在哪里
}
}
Adapter
这个adapter是继承了⾃⼰的定义的⼀个TreeListViewAdapter,核⼼实现都是在TreeListViewAdapter这个⾥⾯
ample.customtreeviewdemo;
import java.util.List;
t.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
Node;
TreeListViewAdapter;
public class MyTreeListViewAdapter<T> extends TreeListViewAdapter<T> {
public MyTreeListViewAdapter(ListView mTree, Context context,
List<T> datas, int defaultExpandLevel,boolean isHide)
throws IllegalArgumentException, IllegalAccessException {
super(mTree, context, datas, defaultExpandLevel,isHide);
}
@SuppressWarnings("unchecked")
@Override
public View getConvertView(Node node, int position, View convertView,
ViewGroup parent) {
ViewHolder viewHolder = null;
if (convertView == null)
{
convertView = mInflater.inflate(R.layout.list_item, parent, false);
viewHolder = new ViewHolder();
viewHolder.icon = (ImageView) convertView
.
findViewById(R.id.id_treenode_icon);
viewHolder.label = (TextView) convertView
.findViewById(R.id.id_treenode_name);
viewHolder.checkBox = (CheckBox)convertView.findViewById(R.id.id_treeNode_check);      convertView.setTag(viewHolder);
} else
{
viewHolder = (ViewHolder) Tag();
}
if (Icon() == -1)
{
viewHolder.icon.setVisibility(View.INVISIBLE);
} else
{
viewHolder.icon.setVisibility(View.VISIBLE);
viewHolder.icon.Icon());
}
if(node.isHideChecked()){
viewHolder.checkBox.setVisibility(View.GONE);
}else{
viewHolder.checkBox.setVisibility(View.VISIBLE);
setCheckBoxBg(viewHolder.checkBox,node.isChecked());
}
viewHolder.label.Name());
return convertView;
}
private final class ViewHolder
{
ImageView icon;
TextView label;
CheckBox checkBox;
}
/**
* checkbox是否显⽰
* @param cb
* @param isChecked
*/
private void setCheckBoxBg(CheckBox cb,boolean isChecked){
if(isChecked){
cb.setBackgroundResource(R.drawable.check_box_bg_check);
}else{
cb.setBackgroundResource(R.drawable.check_box_bg);
}
}
}
⾃定义TreeListViewAdapter  这个是整个树形结构的⼀个适配器,这⾥⾯主要是实现对Node节点的操作点击,选中改变更新等
;
import java.util.ArrayList;
import java.util.List;
t.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.ListView;
import android.widget.RelativeLayout;
/**
* tree适配器
* @param <T>
*/
public abstract class TreeListViewAdapter<T> extends BaseAdapter {
protected Context mContext;
/
**
* 存储所有可见的Node
*/
protected List<Node> mNodes;
protected LayoutInflater mInflater;
/**
* 存储所有的Node
*/
protected List<Node> mAllNodes;
/**
* 点击的回调接⼝
*/
private OnTreeNodeClickListener onTreeNodeClickListener;
public interface OnTreeNodeClickListener {
/**
* 处理node click事件
* @param node
* @param position
*/
void onClick(Node node, int position);
/**
* 处理checkbox选择改变事件
* @param node
* @param position
* @param checkedNodes
*/
void onCheckChange(Node node, int position,List<Node> checkedNodes);
}
public void setOnTreeNodeClickListener(
OnTreeNodeClickListener onTreeNodeClickListener) {
}
/**
*
* @param mTree
* @param context
* @param datas
* @param defaultExpandLevel
*      默认展开⼏级树
* @throws IllegalArgumentException
* @throws IllegalAccessException
*/
public TreeListViewAdapter(ListView mTree, Context context, List<T> datas,      int defaultExpandLevel, boolean isHide)
throws IllegalArgumentException, IllegalAccessException {
mContext = context;
/**
* 对所有的Node进⾏排序
*/
mAllNodes = TreeHelper
.getSortedNodes(datas, defaultExpandLevel, isHide);
/**
* 过滤出可见的Node
*/
mNodes = TreeHelper.filterVisibleNode(mAllNodes);
mInflater = LayoutInflater.from(context);
/
**
* 设置节点点击时,可以展开以及关闭;并且将ItemClick事件继续往外公布    */
mTree.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
expandOrCollapse(position);
if (onTreeNodeClickListener != null) {
<(position),
position);
}
}
});
}
/**
* 相应ListView的点击事件展开或关闭某节点
*
* @param position
*/
public void expandOrCollapse(int position) {
Node n = (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) {
(position);
}
@Override
public long getItemId(int position) {
return position;
}

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。