L'application Android que je développe actuellement a une activité principale qui est devenue assez importante. C'est principalement parce qu'il contient un TabWidget
avec 3 onglets. Chaque onglet contient plusieurs composants. L'activité doit contrôler tous ces composants à la fois. Donc, je pense que vous pouvez imaginer que cette activité a comme 20 champs (un champ pour presque chaque composant). En outre, il contient beaucoup de logique (écouteurs de clic, logique pour remplir les listes, etc.).
Ce que je fais normalement dans les frameworks basés sur des composants, c'est de tout diviser en composants personnalisés. Chaque composant personnalisé aurait alors une responsabilité claire. Il contiendrait son propre ensemble de composants et toute autre logique liée à ce composant.
J'ai essayé de comprendre comment cela pouvait être fait, et j'ai trouvé quelque chose dans la documentation Android ce qu'ils aiment appeler un «contrôle composé». (Voir http://developer.android.com/guide/topics/ui/custom-components.html#compound et faites défiler jusqu'à la section "Contrôles composés") Je voudrais créer un tel composant basé sur un fichier XML définissant le voir la structure.
Dans la documentation, il est dit:
Notez que tout comme avec une activité, vous pouvez utiliser soit l'approche déclarative (basée sur XML) pour créer les composants contenus, soit les imbriquer par programme à partir de votre code.
Eh bien, c'est une bonne nouvelle! L'approche basée sur XML est exactement ce que je veux! Mais il ne dit pas comment le faire, sauf que c'est "comme avec une activité" ... Mais ce que je fais dans une activité, c'est appeler setContentView(...)
à gonfler les vues depuis XML. Cette méthode n'est pas disponible si vous par exemple sous-classez LinearLayout
.
J'ai donc essayé de gonfler le XML manuellement comme ceci:
public class MyCompoundComponent extends LinearLayout {
public MyCompoundComponent(Context context, AttributeSet attributeSet) {
super(context, attributeSet);
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
inflater.inflate(R.layout.my_layout, this);
}
}
Cela fonctionne, à l'exception du fait que le XML que je charge a été LinearLayout
déclaré comme élément racine. Il en résulte que le gonflé LinearLayout
est un enfant MyCompoundComponent
dont lui-même est déjà un LinearLayout
!! Nous avons donc maintenant un LinearLayout redondant entre MyCompoundComponent
les vues dont il a réellement besoin.
Quelqu'un peut-il me fournir une meilleure façon d'aborder cela, en évitant d'avoir une LinearLayout
instance redondante ?
la source
Réponses:
Utilisez la balise de fusion comme racine XML
Consultez cet article.
la source
Je pense que la façon dont vous êtes censé le faire est d'utiliser le nom de votre classe comme élément racine XML:
Et puis faites dériver votre classe de la disposition que vous souhaitez utiliser. Notez que si vous utilisez cette méthode, vous ne le gonfleur de mise en page ici.
Et puis, vous pouvez utiliser votre vue dans les mises en page XML comme d'habitude. Si vous souhaitez créer la vue par programmation, vous devez la gonfler vous-même:
Malheureusement, cela ne vous permet pas de le faire
v = new MyView(context)
car il ne semble pas y avoir de moyen de contourner le problème des dispositions imbriquées, ce n'est donc pas vraiment une solution complète. Vous pouvez ajouter une méthode comme celle-ciMyView
pour la rendre un peu plus agréable:Avertissement: Je parle peut-être de conneries complètes.
la source
<com.example.views.MyView />
et vos appelssetData
etonFinishInflate
commencent à lancer des NPE, et vous ne savez pas pourquoi.