2013-10-10 43 views
9

我有一个多级别(3级,根 - >父 - >子)ExpandableListView包含也是ExpandableListViews的子级。 我没有填充它们的问题;不过,当我第一次显示活动(onCreate)时,我需要展开父级别中的特定项目。问题与扩展多级ExpandableListView

我成功展开父项的相关根项目,但似乎无法展开父项目。给定的监听者被调用,但结果并没有反映在我的多级列表中。

活动中,我所说的扩展:

public class Activity { 
    private int groupToExpand = 4, childToExpand = 3; 
    protected void onCreate(Bundle savedInstance) { 
     final ExpandableListView elv = (ExpandableListView) findViewById(R.id.elv); 
     if (arrayList!= null && !arrayList.isEmpty()) { 
      elv.setAdapter(new RootAdapter(this, arrayList); 
      // this selects the correct group, but doesn't expand the child. 
      elv.setSelectedChild(groupToExpand, childToExpand, true); 
      elv.expandGroup(groupToExpand); // this works. 
     } 
    } 
} 

我的根适配器:

public class RootAdapter extends BaseExpandableListAdapter { 

private List<Objects> arrayList; 
private Context context; 
private LayoutInflater inflater; 

public RootAdapter(Context context, List<Objects> arrayList) { 
    this.context = context; 
    this.arrayList = arrayList; 
    this.inflater = LayoutInflater.from(context); 
} 

@Override 
public Object getChild(int groupPosition, int childPosition) { 
    final Objects parent = (Objects) getGroup(groupPosition); 
    return parent.arrayList.get(childPosition); 
} 

@Override 
public long getChildId(int groupPosition, int childPosition) { 
    return childPosition; 
} 

@Override 
public View getChildView(int groupPosition, int childPosition, 
     boolean isLastChild, View convertView, ViewGroup parent) { 
    final Objects o = (Objects) getChild(groupPosition, childPosition); 

    CustomExpandableListView elv = (CustomExpandableListView) convertView; 
    ChildViewHolder holder; 

    if (elv == null) { 
     holder = new ChildViewHolder(); 

     elv = new CustomExpandableListView(context); 
     elv.setGroupIndicator(null); 
     elv.setDivider(null); 
     elv.setCacheColorHint(Color.parseColor("#00000000")); 
     elv.setChildDivider(null); 
     elv.setChildIndicator(null); 
     elv.setScrollingCacheEnabled(false); 
     elv.setAnimationCacheEnabled(false); 

     holder.cListView = elv; 
     elv.setTag(holder); 
    } else { 
     holder = (ChildViewHolder) elv.getTag(); 
    } 

    final ParentAdapter adapter = new ParentAdapter(context, o); 
    holder.cListView.setAdapter(adapter); 

    return elv; 
} 

private static class ChildViewHolder { 
    CustomExpandableListView cListView; 
} 

@Override 
public int getChildrenCount(int groupPosition) { 
    final Objects parent = (Objects) getGroup(groupPosition); 
    return parent.arrayList.size(); 
} 

@Override 
public Object getGroup(int groupPosition) { 
    return arrayList.get(groupPosition); 
} 

@Override 
public int getGroupCount() { 
    return arrayList.size(); 
} 

@Override 
public long getGroupId(int groupPosition) { 
    return groupPosition; 
} 

@Override 
public View getGroupView(int groupPosition, boolean isExpanded, 
     View convertView, ViewGroup parent) { 
    View layout = convertView; 
    GroupViewHolder holder; 
    final Objects o = (Objects) getGroup(groupPosition); 

    if (layout == null) { 
     layout = inflater.inflate(R.layout.item_to_inflate, parent, false); 
     holder = new GroupViewHolder(); 

     holder.title = (TextView) layout.findViewById(R.id.title); 
     holder.image = (ImageView) layout.findViewById(R.id.image); 
     layout.setTag(holder); 
    } else { 
     holder = (GroupViewHolder) layout.getTag(); 
    } 

    holder.title.setText(o.title.trim()); 

    return layout; 
} 

@Override 
public boolean hasStableIds() { 
    return true; 
} 

@Override 
public boolean isChildSelectable(int groupPosition, int childPosition) { 
    return true; 
} 

private static class GroupViewHolder { 
    TextView title; 
    ImageView image; 
} 

public class CustomExpandableListView extends ExpandableListView { 

    public CustomExpandableListView(Context context) { 
     super(context); 
    } 

    @Override 
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
     heightMeasureSpec = MeasureSpec.makeMeasureSpec(2000, MeasureSpec.AT_MOST); 
     super.onMeasure(widthMeasureSpec, heightMeasureSpec); 
    } 

} 

} 

最后我ParentAdapter:

public class ParentAdapter extends BaseExpandableListAdapter { 

private Objects child; 
private LayoutInflater inflater; 

public ParentAdapter(Context context, Objects child) { 
    this.child = child; 
    this.inflater = LayoutInflater.from(context); 
} 

@Override 
public Object getChild(int groupPosition, int childPosition) { 
    return child.arrayList.get(childPosition); 
} 

@Override 
public long getChildId(int groupPosition, int childPosition) { 
    return childPosition; 
} 

@Override 
public View getChildView(int groupPosition, int childPosition, 
     boolean isLastChild, View convertView, ViewGroup parent) { 
    View layout = convertView; 
    final Objects o = (Objects) getChild(0, childPosition); 

    ChildViewHolder holder; 

    if (layout == null) { 
     layout = inflater.inflate(R.layout.item_to_inflate, parent, false); 

     holder = new ChildViewHolder(); 
     holder.title = (TextView) layout.findViewById(R.id.title); 
     layout.setTag(holder); 
    } else { 
     holder = (ChildViewHolder) layout.getTag(); 
    } 

    holder.title.setText(o.title.trim()); 

    return layout; 
} 

@Override 
public int getChildrenCount(int groupPosition) { 
    return child.arrayList.size(); 
} 

@Override 
public Object getGroup(int groupPosition) { 
    return child; 
} 

@Override 
public int getGroupCount() { 
    return 1; 
} 

@Override 
public long getGroupId(int groupPosition) { 
    return groupPosition; 
} 

@Override 
public View getGroupView(int groupPosition, boolean isExpanded, 
     View convertView, ViewGroup parent) { 
    View layout = convertView; 
    GroupViewHolder holder; 

    if (layout == null) { 
     layout = inflater.inflate(R.layout.item_to_inflate, parent, false); 
     holder = new GroupViewHolder(); 

     holder.image = (ImageView) layout.findViewById(R.id.image); 
     holder.title = (TextView) layout.findViewById(R.id.title); 
     layout.setTag(holder); 
    } else { 
     holder = (GroupViewHolder) layout.getTag(); 
    } 
    holder.title.setText(o.title.trim()); 

    return layout; 
} 

@Override 
public boolean hasStableIds() { 
    return true; 
} 

@Override 
public boolean isChildSelectable(int groupPosition, int childPosition) { 
    return true; 
} 

private static class GroupViewHolder { 
    TextView title; 
    ImageView image; 
} 

private static class ChildViewHolder { 
    TextView title; 
} 

} 

我不能展开子中列出根ExpandableListView;您是否知道在家长级别扩展项目的正确方法?

我试图在RootAdapter的getChildView:

if (groupToExpand == groupPosition && childToExpand == childPosition) { 
    elv.expandGroup(childToExpand); 
} 

然后在活动中,我改变:

if (arrayList!= null && !arrayList.isEmpty()) { 
    RootAdapter adapter = new RootAdapter(this, arrayList); 
    elv.setAdapter(adapter); 
    // this selects the correct group, but doesn't expand the child. 
    elv.setSelectedChild(groupToExpand, childToExpand, true); 
    elv.expandGroup(groupToExpand); // this works. 

    adapter.groupToExpand = groupToExpand; 
    adapter.childToExpand = childToExpand; 
    adapter.notifyDataSetChanged(); 
} 

这将展开父级别项目,但它产生的家长重复的项目。我如何正确地做到这一点?这是正确的方式,但我的适配器已损坏,因此生成重复的项目?

我无法找到我在这里失踪......

+1

具有u解决乌尔问题我也有同样的问题http://stackoverflow.com/questions/18765638/how-to-display-more-than-3-可扩展列表视图级别如果你已经解决了你的问题,请帮助我。 – Cropper

+0

是的,我最近解决了我的问题。我结束了在构造函数中实例化我的第二级项目,而不是getChildView方法。我会发布我的更新。 – Tomap

+0

好的,谢谢Tomap。 – Cropper

回答

11

我结束了使用从计算器另一篇文章多层次ExpandableListView适配器。不幸的是,我只是找不到链接,所以我只是在这里发布我的代码。

ExpandableListView适配器的顶层。

RootAdapter.java:

public class RootAdapter extends BaseExpandableListAdapter { 

    private Object root; 

    private final LayoutInflater inflater; 

    public class Entry { 
     public final CustExpListview cls; 
     public final SecondLevelAdapter sadpt; 

     public Entry(CustExpListview cls, SecondLevelAdapter sadpt) { 
      this.cls = cls; 
      this.sadpt = sadpt; 
     } 
    } 

    public Entry[] lsfirst; 

    // you can change the constructor depending on which listeners you wan't to use. 
    public RootAdapter(Context context, Object root, ExpandableListView.OnGroupClickListener grpLst, 
     ExpandableListView.OnChildClickListener childLst, ExpandableListView.OnGroupExpandListener grpExpLst) { 
     this.root = root; 
     this.inflater = LayoutInflater.from(context); 

     lsfirst = new Entry[root.children.size()]; 

     for (int i = 0; i < root.children.size(); i++) { 
      final CustExpListview celv = new CustExpListview(context); 
      SecondLevelAdapter adp = new SecondLevelAdapter(root.children.get(i)); 
      celv.setAdapter(adp); 
      celv.setGroupIndicator(null); 
      celv.setOnChildClickListener(childLst); 
      celv.setOnGroupClickListener(grpLst); 
      celv.setOnGroupExpandListener(grpExpLst); 

      lsfirst[i] = new Entry(celv, adp); 
     } 

    } 

    @Override 
    public Object getChild(int groupPosition, int childPosition) { 
     return childPosition; 
    } 

    @Override 
    public long getChildId(int groupPosition, int childPosition) { 
     return childPosition; 
    } 

    @Override 
    public View getChildView(int groupPosition, int childPosition, boolean isLastChild, 
     View convertView, ViewGroup parent) { 
     // second level list 
     return lsfirst[groupPosition].cls; 
    } 

    @Override 
    public int getChildrenCount(int groupPosition) { 
     return 1; 
    } 

    @Override 
    public Object getGroup(int groupPosition) { 
     return root.children.get(groupPosition); 
    } 

    @Override 
    public int getGroupCount() { 
     return root.children.size(); 
    } 

    @Override 
    public long getGroupId(int groupPosition) { 
     return groupPosition; 
    } 

    @Override 
    public View getGroupView(int groupPosition, boolean isExpanded, View convertView, 
     ViewGroup parent) { 

     // first level 

     View layout = convertView; 
     GroupViewHolder holder; 
     final Object item = (Object) getGroup(groupPosition); 

     if (layout == null) { 
      layout = inflater.inflate(R.layout.item_root, parent, false); 
      holder = new GroupViewHolder(); 
      holder.title = (TextView) layout.findViewById(R.id.itemRootTitle); 
      layout.setTag(holder); 
     } else { 
      holder = (GroupViewHolder) layout.getTag(); 
     } 

     holder.title.setText(item.title.trim()); 

     return layout; 
    } 

    private static class GroupViewHolder { 
     TextView title; 
    } 

    @Override 
    public boolean hasStableIds() { 
     return true; 
    } 

    @Override 
    public boolean isChildSelectable(int groupPosition, int childPosition) { 
     return true; 
    } 
} 

定制ExpandableListView与解决方案的项目有时不显示。当销毁视图时(通过按下后退按钮),还会调用IllegalArgumentException的已知错误的解决方法。

CustExpListview.java:

public class CustExpListview extends ExpandableListView { 

    public CustExpListview(Context context) { 
     super(context); 

    } 

    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
     // the value (2000) should not be fixed and be calculated 
     // as follows: cell_height x root_items_count x root_items_children_count 
     heightMeasureSpec = MeasureSpec.makeMeasureSpec(2000, MeasureSpec.AT_MOST); 
     super.onMeasure(widthMeasureSpec, heightMeasureSpec); 
    } 

    @Override 
    protected void onDetachedFromWindow() { 
     try { 
      super.onDetachedFromWindow(); 
     } catch (IllegalArgumentException e) { 
      // TODO: Workaround for http://code.google.com/p/android/issues/detail?id=22751 
     } 
    } 
} 

最后,该代码的最后一级适配器。

public class SecondLevelAdapter extends BaseExpandableListAdapter { 

    public Object child; 

    public SecondLevelAdapter(Object child) { 
     this.child = child; 
    } 

    @Override 
    public Object getChild(int groupPosition, int childPosition) { 
     return child.children.get(groupPosition).children.get(childPosition); 
    } 

    @Override 
    public long getChildId(int groupPosition, int childPosition) { 
     return childPosition; 
    } 

    // third level 
    @Override 
    public View getChildView(int groupPosition, int childPosition, boolean isLastChild, 
      View convertView, ViewGroup parent) { 
     View layout = convertView; 
     final Object item = (Object) getChild(groupPosition, childPosition); 

     ChildViewHolder holder; 

     if (layout == null) { 
      layout = inflater.inflate(R.layout.item_child, parent, false); 

      holder = new ChildViewHolder(); 
      holder.title = (TextView) layout.findViewById(R.id.itemChildTitle); 
      layout.setTag(holder); 
     } else { 
      holder = (ChildViewHolder) layout.getTag(); 
     } 

     holder.title.setText(item.title.trim()); 

     return layout; 
    } 

    @Override 
    public int getChildrenCount(int groupPosition) { 
     return child.children.get(groupPosition).children.size(); 
    } 

    @Override 
    public Object getGroup(int groupPosition) { 
     return child.children.get(groupPosition); 
    } 

    @Override 
    public int getGroupCount() { 
     return child.children.size(); 
    } 

    @Override 
    public long getGroupId(int groupPosition) { 
     return groupPosition; 
    } 

    // Second level 
    @Override 
    public View getGroupView(int groupPosition, boolean isExpanded, View convertView, 
      ViewGroup parent) { 
     View layout = convertView; 
     ViewHolder holder; 

     final Object item = (Object) getGroup(groupPosition); 

     if (layout == null) { 
      layout = inflater.inflate(R.layout.item_parent, parent, false); 
      holder = new ViewHolder(); 
      holder.title = (TextView) layout.findViewById(R.id.itemParentTitle); 
      layout.setTag(holder); 
     } else { 
      holder = (ViewHolder) layout.getTag(); 
     } 

     holder.title.setText(item.title.trim()); 

     return layout; 
    } 

    @Override 
    public void registerDataSetObserver(DataSetObserver observer) { 
     super.registerDataSetObserver(observer); 
    } 

    @Override 
    public void unregisterDataSetObserver(DataSetObserver observer) { 
     Log.d("SecondLevelAdapter", "Unregistering observer"); 
     if (observer != null) { 
      super.unregisterDataSetObserver(observer); 
     } 
    } 

    @Override 
    public boolean hasStableIds() { 
     return true; 
    } 

    @Override 
    public boolean isChildSelectable(int groupPosition, int childPosition) { 
     return true; 
    } 

    private static class ViewHolder { 
     TextView title; 
    } 

    private static class ChildViewHolder { 
     TextView title; 
    } 

} 

我希望这有助于!

更新

这是我如何调用上面的适配器的例子。

MainActivity:

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    final List<Object> objects = yourItems; 
    if (!objects.isEmpty()) { 
     final ExpandableListView elv = (ExpandableListView) findViewById(R.id.yourExpandableListView); 
     /* Item click listeners below */ 

     // First level items in the ExpandableListView 
     elv.setOnGroupClickListener(new ExpandableListView.OnGroupClickListener() { 
      @Override 
      public boolean onGroupClick(ExpandableListView eListView, View view, int groupPosition, 
        long id) { 
       // TODO: whatever you need 
       return false /* or true depending on what you need */; 
      } 
     }); 

     // Second level items in the ExpandableListView 
     ExpandableListView.OnGroupClickListener grpLst = new ExpandableListView.OnGroupClickListener() { 
      @Override 
      public boolean onGroupClick(ExpandableListView eListView, View view, int groupPosition, 
        long id) { 
       // TODO: whatever you need 
       return false /* or true depending on what you need */; 
      } 
     }; 

     // Third (and last) level items in the ExpandableListView 
     ExpandableListView.OnChildClickListener childLst = new ExpandableListView.OnChildClickListener() { 
      @Override 
      public boolean onChildClick(ExpandableListView eListView, View view, int groupPosition, 
        int childPosition, long id) { 
       // TODO: whatever you need 
       return false /* or true depending on what you need */; 
      } 
     }; 

     ExpandableListView.OnGroupExpandListener grpExpLst = new ExpandableListView.OnGroupExpandListener() { 
      @Override 
      public void onGroupExpand(int groupPosition) { 
       /* this one is not required of course, you can delete it from the RootAdapter Constructor 
       * it is just an example as to how to implement Listeners on the second level items */ 
      } 
     }; 

     final RootAdapter adapter = new RootAdapter(this, objects, grpLst, childLst, grpExpLst); 
     elv.setAdapter(adapter); 
    } 
} 

这是我Object类会是什么样子。

Object.java:

public class Object { 
    public String title; // use getters and setters instead 
    public List<Object> children; // same as above 

    public Object() { 
     children = new ArrayList<Object>(); 
    } 
} 
+0

你可以发布你的主要类。我不知道如何声明:Object root,ExpandableListView.OnGroupClickListener grpLst, ExpandableListView.OnChildClickListener childLst,ExpandableListView.OnGroupExpandListener grpExpLst – Cropper

+0

当然,我会更新答案,如何实例化和填充适配器。 – Tomap

+0

嗨tomap,我使用这个代码为我的expandablelistview,问题是第三级不扩大后点击几下..我怎么能离开这? –