自定义多极树形列表:可实现无限级树形结构的显示,其实现原理就是利用了android当中的ListView控件,在ListView当中,不断的插入和删除数据,以及给后插入的数据加上缩进,造成一种类似于树形结构的假象,其本质就是一个ListView;
先放上3张运行效果图,接下来再讲实现的具体步骤
:
好了,接下来讲具体实现.
步骤一:我们先来定义下树节点的结构
public class TreeElement {
private String title; // 章节文本
private String value; //
private String icon; // 加载图片的序号
private String knowledge_id; // 知识点id(用来判断是否是叶子节点)
private int level; // 在tree中的层级
private Boolean hasChildren; // 是否有子节点
private Boolean isExpanded; // item是否展开
private List<TreeElement> childTreeList; //子结点列表
}这里重点要解释的是 level 这个变量,level 是用了标示当前节点所在整个树结构里的层级,什么意思呢,看第3张图,“第一章”“第二章”“第三章”“第四章”位于第0层,也就是level=0,"整式的加减"及其兄弟节点位于第1层level=1,以此类推,“整式加减的运算法则”level=2.........
数据结构定义完之后,我们接下来进入第二步
步骤二:我们定义一个继承自BaseAdapter的AdapterView,下面看具体代码
public class TreeViewAdapter extends BaseAdapter {
/** 元素数据源 */
private ArrayList<TreeElement> elementsData;
/** 树中元素 */
private ArrayList<TreeElement> elements;
/** LayoutInflater */
private LayoutInflater inflater;
/** item的行首缩进基数 */
private int indentionBase;
public TreeViewAdapter() {
// TODO Auto-generated constructor stub
super();
}
public TreeViewAdapter(ArrayList<TreeElement> elements,
ArrayList<TreeElement> elementsData, LayoutInflater inflater) {
this.elements = elements;
this.elementsData = elementsData;
this.inflater = inflater;
indentionBase = 50;
}
public ArrayList<TreeElement> getElements() {
return elements;
}
public ArrayList<TreeElement> getElementsData() {
return elementsData;
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return elements.size();
}
@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return elements.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) {
// TODO Auto-generated method stub
ViewHolder holder = null;
if( convertView == null )
{
holder = new ViewHolder();
convertView = inflater.inflate(R.layout.study_treeview_item, null);
holder.disclosureImg = (ImageView)convertView.findViewById(R.id.treeitemimage);
holder.contentText = (TextView)convertView.findViewById(R.id.treeitemtitle);
convertView.setTag(holder);
}
else{
holder = (ViewHolder)convertView.getTag();
}
TreeElement element = elements.get(position);
int level = element.getLevel();
holder.disclosureImg.setPadding(
indentionBase * level,
holder.disclosureImg.getPaddingTop(),
holder.disclosureImg.getPaddingRight(),
holder.disclosureImg.getPaddingBottom());
holder.contentText.setText(element.getTitle());
if (element.getHasChildren() && !element.getIsExpanded()) {
holder.disclosureImg.setImageResource(R.drawable.close);
//这里要主动设置一下icon可见,因为convertView有可能是重用了"设置了不可见"的view,下同。
holder.disclosureImg.setVisibility(View.VISIBLE);
} else if (element.getHasChildren() && element.getIsExpanded()) {
holder.disclosureImg.setImageResource(R.drawable.open);
holder.disclosureImg.setVisibility(View.VISIBLE);
} else if (!element.getHasChildren()) {
holder.disclosureImg.setImageResource(R.drawable.close);
holder.disclosureImg.setVisibility(View.INVISIBLE);
}
return convertView;
}
static class ViewHolder {
ImageView disclosureImg;
TextView contentText;
}
}
这里需要解释的是
1. elementsData:就是从服务器上获取的全部的数据
2.elements:这个要重点解释一下,这个变量是用来实现树结构最重要,最核心的一个数据源,首先最开始它存放的是根节点的全部子结点数据,也就是图上的第一章,第二章,第三章,第四章,这四个数据,当我们每点击一下屏幕上的节点,我们就会往这个变量里面插入和删除当前节点的子结点数据,这下明白了吧,哈哈哈哈
3.indentionBase:这个就是子节点相对于父节点的缩进量。
第三步:我们实现一个自定义的监听类
public class TreeViewItemClickListener implements OnItemClickListener {
/** adapter */
private TreeViewAdapter treeViewAdapter