Android可展开树


最近项目有个需求,需要分不同等级的不同信息在手机上显示,要分等级展示,比如第一层显示第一等级的信息,第二层显示第一层从属的信息,如果有子数据,则可以提示展开,如果没有,则不用提示可以展开,并且不能站看的数据点击后将数据显示出来。

效果如下:

效果图

我想到的第一个方法是 expandListView,但是后来用了用,效果并不是很好,最后发现了一个用listview直接OK的方法。

就是用listview中的adapter中显示的数据用实体类表示,这个实体类是比较要技巧的,我是这样定义的:

private String gridId;//id
private String gridName;//name要显示的数据
private String departId;//这个是自己用的
private boolean hasParent;//是否有父节点
private boolean hasChild;//是否有子节点
private String parent;//父节点ID
private int level;//第几层
private boolean expanded;//是否已经展开

先是你要用的ID,NAME,然后就是列表显示用的,是否有父节点、是否有子节点、父节点ID、第几层的、是否已经展开(这个用来判断展开与否的图片显示)。

下面是自己定义的adapter,里面显示的信息没什么,重要的是根据状态判断显示图片。

private class GirdTreeAdapter extends ArrayAdapter<SyncGridBean> {

    private LayoutInflater mInflater;
    private List<SyncGridBean> mfilelist;
    private Bitmap mIconCollapse;
    private Bitmap mIconExpand;

    public GirdTreeAdapter(Context context, int textViewResourceId,
            List<SyncGridBean> objects) {
        super(context, textViewResourceId, objects);
        mInflater = LayoutInflater.from(context);
        mfilelist = objects;
        mIconCollapse = BitmapFactory.decodeResource(
                context.getResources(), R.drawable.gird_item_collapse);
        mIconExpand = BitmapFactory.decodeResource(context.getResources(),
                R.drawable.gird_item_expand);

    }
    public int getCount() {
        return mfilelist.size();
    }

    public SyncGridBean getItem(int position) {
        return mfilelist.get(position);
    }

    public long getItemId(int position) {
        return position;
    }

    public View getView(int position, View convertView, ViewGroup parent) {

        ViewHolder holder;
        /*if (convertView == null) {*/
            convertView = mInflater.inflate(R.layout.item_girdtree, null);
            holder = new ViewHolder();
            holder.text = (TextView) convertView.findViewById(R.id.text);
            holder.icon = (ImageView) convertView.findViewById(R.id.icon);
            convertView.setTag(holder);
        /*} else {
            holder = (ViewHolder) convertView.getTag();
        }*/

        int level = mfilelist.get(position).getLevel();
         holder.icon.setPadding(25 * (level + 1), holder.icon
                .getPaddingTop(), 0, holder.icon.getPaddingBottom());
        holder.text.setText(mfilelist.get(position).getGridName());
        if (mfilelist.get(position).isHasChild()
                && (!mfilelist.get(position).isExpanded())) {
            holder.icon.setImageBitmap(mIconCollapse);
        } else if (mfilelist.get(position).isHasChild()
                && (mfilelist.get(position).isExpanded())) {
            holder.icon.setImageBitmap(mIconExpand);
        } else if (!mfilelist.get(position).isHasChild()){
            holder.icon.setImageBitmap(mIconCollapse);
            holder.icon.setVisibility(View.INVISIBLE);
        }
        return convertView;
    }

    class ViewHolder {
        TextView text;
        ImageView icon;

    }
}

重点来了,重点就在于你点击的时候 判断的这个信息

@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
    super.onListItemClick(l, v, position, id);
    if (!mGirdParents.get(position).isHasChild()) {

        //如果没有子节点了  可以处理你自己的逻辑
        return;
    }

    //如果没有展开,那就展开
    if (mGirdParents.get(position).isExpanded()) {
        mGirdParents.get(position).setExpanded(false);
        SyncGridBean pdfOutlineElement=mGirdParents.get(position);
        ArrayList<SyncGridBean> temp=new ArrayList<SyncGridBean>();

        for (int i = position+1; i < mGirdParents.size(); i++) {
            if (pdfOutlineElement.getLevel()>=mGirdParents.get(i).getLevel()) {
                break;
            }
            temp.add(mGirdParents.get(i));
        }

        mGirdParents.removeAll(temp);

        girdTreeAdapter.notifyDataSetChanged();


    } else {//如果已经展开,那就缩回
        mGirdParents.get(position).setExpanded(true);
        int level = mGirdParents.get(position).getLevel();
        int nextLevel = level + 1;
        for (SyncGridBean pdfOutlineElement : mGirdChilds) {
            int j=1;
            if (pdfOutlineElement.getParent()==mGirdParents.get(position).getGridId()) {
                pdfOutlineElement.setLevel(nextLevel);
                pdfOutlineElement.setExpanded(false);
                mGirdParents.add(position+j, pdfOutlineElement);
                j++;
            }            
        }
        girdTreeAdapter.notifyDataSetChanged();

    }
}

这个做的是点击整个item的话是这样的,你也可以单独点击那个图片来展开或者缩回,点击文字显示,这些在这里都是可以实现的

项目地址:https://github.com/wedcel/TreeTest