2010-01-02 3 views
3

Comment utiliser le ResourceCursorTreeAdapter avec le constructeur suivant?Comment utiliser ResourceCursorTreeAdapter avec des vues de groupe étendues et réduites dans Android?

ResourceCursorTreeAdapter(Context context, Cursor cursor, int collapsedGroupLayout, int expandedGroupLayout, int childLayout) 

Je suis en train d'utiliser un comme suit:

_resultsCursorTreeAdapter = new ResourceCursorTreeAdapter(_resultsList.getContext(), _dbAdapter.getAllGroups(), 
     R.layout.timing_group_view_collapsed, R.layout.timing_group_view_expanded, R.layout.timing_result_view) { 

@Override 
protected Cursor getChildrenCursor(Cursor groupCursor) { 
    // Given the group, we return a cursor for all the children within that group 
    int groupId = groupCursor.getInt(0); 
    Cursor childCursor = _dbAdapter.getContractionsForGroup(groupId); 
    return childCursor; 
} 

@Override 
protected void bindGroupView(View groupView, Context context, Cursor cursor, 
    boolean isExpanded) { 

    TimingGroupView timingGroupItem = null; 
    if(groupView instanceof LinearLayout){ 
    Log.i("TimingGroupView", "Has Header"); 
    LinearLayout layout = (LinearLayout)groupView; 

    timingGroupItem = (TimingGroupView) layout.getChildAt(0); 
    } else{ 
    Log.i("TimingGroupView", "No Header"); 
    timingGroupItem = (TimingGroupView) groupView; 
    } 
... 

Si le nœud de groupe est développé, je veux le nœud du groupe pour inclure l'en-tête d'une table où chaque ligne est tenue à un noeud enfant. timing_group_view_expanded.xml et timing_group_view_collapsed.xml sont affichés en bas de cette question. Pour une raison quelconque, le group_view_expanded n'est jamais utilisé, que les nœuds du groupe soient développés ou réduits. Est-ce que j'utilise ce mauvais? Quelqu'un d'autre a-t-il pu faire fonctionner ResourceCursorTreeAdapter avec ce constructeur?

timing_group_view_expanded.xml est la suivante:

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout android:id="@+id/timing_group_view" 
android:orientation="vertical" android:layout_width="fill_parent" 
android:layout_height="wrap_content" xmlns:android="http://schemas.android.com/apk/res/android" 
android:background="@color/header_timing_color"> 

<com.contractiontracker.TimingGroupView 
    android:id="@+id/timing_group_item" xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="fill_parent" android:layout_height="wrap_content" 
    android:layout_marginLeft="30px" android:padding="10dp" 
    android:scrollbars="vertical" 
    android:fadingEdge="vertical" 
    android:background="@color/header_timing_color" 
    android:textColor="@color/text_color"/> 

<com.contractiontracker.RowLayout android:id="@+id/timing_group_view" 
    android:orientation="horizontal" android:layout_width="fill_parent" 
    android:layout_height="wrap_content" xmlns:android="http://schemas.android.com/apk/res/android" 
    android:background="@color/header_color" android:textColor="@color/text_color"> 

    <TextView android:id="@+id/interval_header" 
    android:layout_width="fill_parent" android:layout_height="wrap_content" 
    android:text="Interval" android:layout_weight="1" 
    android:layout_gravity="left|bottom" android:gravity="center" 
    android:textColor="@color/text_color"> 
    </TextView> 
    <TextView android:id="@+id/duration_header" 
    android:layout_width="fill_parent" android:layout_height="wrap_content" 
    android:text="Duration" android:layout_weight="1" 
    android:layout_gravity="center_horizontal|bottom" android:gravity="center" 
    android:textColor="@color/text_color" 
    > 
    </TextView> 
    <TextView android:id="@+id/intensity_header" 
    android:layout_width="fill_parent" android:layout_height="wrap_content" 
    android:text="Intensity" android:layout_weight="1" 
    android:layout_gravity="right|bottom" android:gravity="center" 
    android:textColor="@color/text_color" 
    > 
    </TextView> 
</com.contractiontracker.RowLayout> 
</LinearLayout> 

timing_group_view_collapsed.xml se présente comme suit:

<?xml version="1.0" encoding="utf-8"?> 
<com.contractiontracker.TimingGroupView 
    android:id="@+id/timing_group_item" 
xmlns:android="http://schemas.android.com/apk/res/android" 
android:layout_width="fill_parent" 
android:layout_height="wrap_content" 
android:layout_marginLeft="50px" 
android:padding="10dp" 
android:scrollbars="vertical" 
android:textColor="@color/text_color" 
android:fadingEdge="vertical"/> 

Répondre

0

Voici ma solution temporaire pour SimpleExpandableListAdapter:

public class LocalAdapter extends SimpleExpandableListAdapter { 
    private List<? extends Map<String, ?>> mGroupData; 
    private String[] mGroupFrom; 
    private int[] mGroupTo; 

    private List<? extends List<? extends Map<String, ?>>> mChildData; 

    private LayoutInflater mInflater; 

    public LocalAdapter(Context context, 
      List<? extends Map<String, ?>> groupData, int groupLayout, 
      String[] groupFrom, int[] groupTo, 
      List<? extends List<? extends Map<String, ?>>> childData, 
      int childLayout, String[] childFrom, int[] childTo) { 
     this(context, groupData, groupLayout, groupLayout, groupFrom, groupTo, childData, 
       childLayout, childLayout, childFrom, childTo); 
    } 

    public LocalAdapter(Context context, 
      List<? extends Map<String, ?>> groupData, int expandedGroupLayout, 
      int collapsedGroupLayout, String[] groupFrom, int[] groupTo, 
      List<? extends List<? extends Map<String, ?>>> childData, 
      int childLayout, String[] childFrom, int[] childTo) { 
     this(context, groupData, expandedGroupLayout, collapsedGroupLayout, 
       groupFrom, groupTo, childData, childLayout, childLayout, 
       childFrom, childTo); 
    } 

    public LocalAdapter(Context context, 
      List<? extends Map<String, ?>> groupData, int expandedGroupLayout, 
      int collapsedGroupLayout, String[] groupFrom, int[] groupTo, 
      List<? extends List<? extends Map<String, ?>>> childData, 
      int childLayout, int lastChildLayout, String[] childFrom, 
      int[] childTo) { 

     super(context, groupData, expandedGroupLayout, 
       collapsedGroupLayout, groupFrom, groupTo, childData, 
       childLayout, lastChildLayout, childFrom, childTo); 

     mGroupData = groupData; 
     mGroupFrom = groupFrom; 
     mGroupTo = groupTo; 
     mChildData = childData; 
     mInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
    }   

    private void bindView(View view, Map<String, ?> data, String[] from, int[] to) { 
     int len = to.length; 

     for (int i = 0; i < len; i++) { 
      TextView v = (TextView)view.findViewById(to[i]); 
      if (v != null) { 
       v.setText((String)data.get(from[i])); 
      } 
     } 
    } 

    @Override 
    public View getGroupView(int groupPosition, boolean isExpanded, View convertView, 
      ViewGroup parent) { 
     View v = newGroupView(isExpanded, parent); 
     bindView(v, mGroupData.get(groupPosition), mGroupFrom, mGroupTo); 
     return v; 
    } 
} 
+0

Je pense que vous devez vérifier 'convertview == null' ou bien chaque fois que de nouvelles groupview sera créé et le recyclage du concept élément de la liste ne fonctionnera pas causer ici le manque de performance de défilement, etc. – kAmol

6

Le problème est que ResourceCursorTreeAdaptercrée uniquement les mises en page correctes lors de la création d'une vue. Par conséquent, si un groupe est réduit ou développé, le newGroupView() est et n'est pas appelé de nouveau. Par conséquent, les différentes présentations de groupe transmises au constructeur ne sont pas utilisées comme prévu.

Le même problème existe avec les mises en page d'enfant lors de l'utilisation des différentes pour le normal et le dernier enfant. Cela arrive là sans même changer les données! Après avoir re-développé un groupe, le premier avait la disposition de bas de page et vice-versa. Totalement aléatoire et non basé sur la position dans la liste.

Comme Aleksander O a montré dans son exemple, on peut résoudre ce problème en appeler toujours newGroupView() dans la méthode getGroupView (et getChildView respectivement si différentes mises en page sont utilisés pour cela).

Pour éviter de créer toujours de nouvelles vues, j'ai essayé une approche différente qui fonctionne pour mon cas:

  • Ajouter différentes ids à l'élément racine des mises en page utilisées pour les vues groupe/enfant
  • magasin les vue-ids comme int membres de mon adaptateur:

    // Get the view ids for comparison 
    View view = newGroupView(mContext, null, false, null); 
    mCollapsedGroupLayoutViewId = view.getId(); 
    view = newGroupView(mContext, null, true, null); 
    mExpandedGroupLayoutViewId = view.getId(); 
    
    view = newChildView(mContext, null, false, null); 
    mChildLayoutViewId = view.getId(); 
    view = newChildView(mContext, null, true, null); 
    mLastChildLayoutViewId = view.getId(); 
    
  • mise en œuvre de getGroupView (et analogique avec getChildView):

    public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) { 
         Cursor cursor = getGroup(groupPosition); 
         if (cursor == null) { 
          throw new IllegalStateException("this should only be called when the cursor is valid"); 
         } 
    
         View v; 
         if (convertView == null 
          || (isExpanded && convertView.getId() == mCollapsedGroupLayoutViewId) 
          || (!isExpanded && convertView.getId() == mExpandedGroupLayoutViewId)) { 
          v = newGroupView(mContext, cursor, isExpanded, parent); 
         } 
         else { 
          v = convertView; 
         } 
         bindGroupView(v, mContext, cursor, isExpanded); 
         return v; 
    } 
    
+0

sunadorer et @ Dandre merci pour la réponse.Mais dans mon expérience, même 'getGroupView (...)' est _not_ appelé _quand j'appuie sur le groupe_ pour le développer/le réduire. Plutôt, il faudra un peu de défilement jusqu'à ce que finalement 'getGroupView (...)' soit appelé et met à jour 'groupView'. Est-ce que quelqu'un a réussi à ** immédiatement ** changer la disposition de 'groupView' quand il est tapé? – hadi

+0

@hadi Désolé pour ma réponse en retard. J'utilise toujours la solution indiquée dans ma réponse dans l'une de mes applications. Cela fonctionne bien pour changer de visibilités de disposition directement sur le clic sur le groupe avec cacher toutes les vues enfant. Peut-être que vous pourriez ouvrir une nouvelle question et montrer vos fragments de code et des informations sur les appareils testés sur lesquels il ne fonctionne pas immédiatement. – sunadorer

+0

Merci de votre solution, +1. Cependant, nous pouvons omettre la 2ème étape (stocker les identifiants en tant que membres de l'adaptateur), car nous ajoutons déjà des identifiants (@ + id/group_collapsed, @ + id/group_expanded, ... etc) dans le fichier xml de mise en page. Donc, à la 3ème étape, dans le code, il suffit de comparer convertView.getId() == R.id.group_collapsed, ... etc est ok. –

0

Solution facile avec un bon recyclage.

@Override 
public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) { 
    Cursor cursor = getGroup(groupPosition); 
    if (cursor == null) { 
     throw new IllegalStateException("this should only be called when the cursor is valid"); 
    } 

    View view; 
    if (convertView == null || convertView.getTag() != isExpanded) { 
     view = newGroupView(mActivity, cursor, isExpanded, parent); 
     view.setTag(isExpanded); 
    } else { 
     view = convertView; 
    } 
    bindGroupView(view, mActivity, cursor, isExpanded); 
    return view; 
} 
Questions connexes