2017-08-22 1 views
2

J'ai une mise en page complexe à implémenter. Il dispose de 19 sections qui peuvent être affichées ou non en fonction de nombreux paramètres préalablement saisis par l'utilisateur. Afin de simplifier le code et de ne pas afficher les sections inutilisées, la mise en page est créée dynamiquement.Restaurer un fragment avec deux vues ayant le même identifiant

Tout est à l'intérieur d'un fragment. Le fragment a un LinearLayout utilisé comme conteneur et, lorsque le fragment est créé, je génère toutes les sections nécessaires.

Chaque section est gérée par son propre adaptateur local qui est chargé de gonfler la disposition de cette section et de l'ajouter dans le conteneur.

Tout fonctionne parfaitement bien. Le problème est que 2 sections ont exactement la même structure afin qu'ils partagent la même mise en page xml. Pour cette raison, les vues internes des deux sections ont le même identifiant. Ce n'est pas un problème car la section est gérée localement dans son adaptateur. Le problème apparaît lorsque je passe au fragment suivant et que je reviens à celui-ci. Le système tente de récupérer l'état précédent de la vue et, comme ces deux sections ont les mêmes ID, lorsque la seconde section est restaurée, ses valeurs sont également définies sur la première.

Y a-t-il une solution pour gérer cela ou pour dire au fragment de ne pas restaurer son état (puisque tout est rechargé manuellement de toute façon).

Voici un exemple de la lumière de la structure actuelle:

fragment xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/container" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent"/> 

section xml

<EditText xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/section_text" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content"/> 

code fragment

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, 
         Bundle savedInstanceState) { 
    // Inflate the layout for this fragment 
    View view = inflater.inflate(R.layout.fragment_layout, container, false); 

    if (<condition>) 
     createSection1(getContext(),view); 

    if (<condition>)   
     createSection2(getContext(),view); 

    return view; 
} 


private void createSection1(Context context, ViewGroup root){ 
    Section1Adapter adapter = new Section1Adapter(context, root); 
    // ... 
} 

private void createSection2(Context context, ViewGroup root){ 
    Section2Adapter adapter = new Section2Adapter(context, root); 
    // ... 
} 

code adaptateur (même idée pour les deux)

public Section2Adapter(LayoutInflater inflater, ViewGroup root) { 

    View view = LayoutInflater.from(context).inflate(R.layout.section_layout, root, false); 

    initView(view); 

    root.addView(view); 
} 

Répondre

2

Votre question, comme vous le dites bien, est que, fondamentalement, vous êtes dans cet état: enter image description here

Qu'est-ce que vous avez besoin faire, est de dire à Android vous-même à quelle touche dans le SparseArray pour enregistrer l'état EditText. En gros, vous devez arriver à ceci:

enter image description here

Le mécanisme par lequel vous atteindre cet objectif est très bien expliqué dans this amazing article, par Pacha Dudka. (crédits à lui pour les belles images, aussi)

Il suffit de chercher "Voir les ID doit être unique" dans l'article, et vous aurez votre réponse.

L'essentiel de la solution pour votre situation particulière est une des opérations suivantes:

  • vous pouvez sous-classe LinearLayout S.T.votre CustomLinearLayout connaîtra la section à laquelle un enfant appartient, quand son état. De cette façon, vous pouvez enregistrer tous les états de l'enfant dans une section à un SparseArray dédié juste pour cette section, et ajoutez dédié SparseArray à la mondialeSparseArray (comme dans l'image)
  • vous pouvez sous-classe EditText, S.T. votre CustomEditText sais dans quelle section il appartient, et sauvegardera son état à une touche personnalisée dans le SparseArray - par exemple. section_text_Section1 pour la première section, et section_text_Section2 pour le second

Personnellement, je préfère la première version, car il fonctionnera même si vous ajoutez ultérieurement plus vues à vos articles. La seconde ne fonctionnera pas avec plus de vues, puisque dans la seconde, ce n'est pas le parent qui sauvegarde l'état intelligent, mais la vue elle-même.

Espérons que cela aide.

+0

Wahoo! Réponse incroyable! Merci beaucoup car je ne savais pas à ce sujet. C'est exactement ce que je cherchais. – Eselfar