有时需要一个多级列表结构来显示内容,google只提供了listview 单级列表和ExpandableListView二级列表(我所知),基于这些自己修改,可以实现简单的多级列表。
刚写的小demo,还很不完善基于listview来实现多级列表(参考了网上的思路,也有用ExpandableListView)。
layout只是简单的listview的layout。
一个属性类
class Connection {
boolean hasChild = false;// 是否有子节点
int level = 0;// 级别,左缩进,0为最高级
long id = -1;// 标识 -1为err
boolean isExpansion = false;// 展开状态
}
每个item拥有如上属性来判断他的显示内容和ui状态。
根据此属性,在adapter中的getview方法中实现显示(没有添加view不为空时的判断,效率低)。
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = LayoutInflater.from(mContext);
View v = inflater.inflate(R.layout.company_list, null);
Connection c = mConnections.get(position);
v.setTag(R.id.company_list_image, c.level);
v.setTag(R.id.company_list_text, position);
v.setTag(R.id.companys_list, c);
TextView text = (TextView) v.findViewById(R.id.company_list_text);
text.setText(c.id + "");
ImageView image = (ImageView) v.findViewById(R.id.company_list_image);
v.setPadding(c.level * v.getPaddingLeft()*mLeftScan, 0, 0, 0);
if (!c.hasChild) {
image.setVisibility(View.INVISIBLE);
} else {
image.setVisibility(View.VISIBLE);
if (c.isExpansion) {
image.setImageResource(R.drawable.arrow_right);
}else {
image.setImageResource(R.drawable.arrow_bottom);
}
}
return v;
}
此时,如果已经预先设置了一些值,这个多级列表已经可以正确显示。最后还缺少监听控制。
OnItemClickListener itemClickListener = new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
ArrayList<Connection> connections = mAdapter.getConnections();
ArrayList<Connection> mConnections2 = new ArrayList<Connection>();
Connection c = (Connection) arg1.getTag(R.id.companys_list);
if (c == null) {
return;
}
if (c.hasChild) {
int level = c.level;
int pos = connections.indexOf(c);
boolean isCheck = true;
if (c.isExpansion) {
// 收缩
c.isExpansion = false;
for (int i = 0; i < connections.size(); i++) {
if (isCheck) {
if (i > pos && connections.get(i).level > level) {
continue;
}
}
if (i > pos) {
isCheck = false;
}
mConnections2.add(connections.get(i));
}
} else {
// 展开
c.isExpansion = true;
ArrayList<Connection> c2 = new ArrayList<Connection>();
int pos2 = (mConnections.indexOf(c) + 1);
int level2 = -1;
for (int i = pos2; i < mConnections.size(); i++) {
if (mConnections.get(i).level > level) {
c2.add(mConnections.get(i));
if (!mConnections.get(i).isExpansion) {
level2 = mConnections.get(i).level;
for (int j = (i + 1); j < mConnections.size(); j++) {
if (mConnections.get(j).level > level2) {
i++;
} else {
break;
}
}
}
} else {
break;
}
}
for (int j = 0; j < connections.size(); j++) {
mConnections2.add(connections.get(j));
if (j == pos) {
for (int i = 0; i < c2.size(); i++) {
mConnections2.add(c2.get(i));
}
}
}
}
mAdapter.setConnections(mConnections2);
mAdapter.notifyDataSetInvalidated();
} else {
}
}
};
计算部分很混乱,只是个小demo就先这样。
最好封装为一个view(监听和adapter都写里面)这样使用的时候直接把文件copy过来设值、调用就行了。
粗糙的效果图