12
votes

Devrais-je appeler super () ou appeler ceci () pour les constructeurs de visuels personnalisés Android?

Lors de la création d'une vue personnalisée, j'ai remarqué que beaucoup de gens semblent le faire comme ceci:

public MyView(Context context) {
  this(context, null);
  // this constructor used when programmatically creating view
}

public MyView(Context context, AttributeSet attrs) {
  this(context, attrs, 0);
  // this constructor used when creating view through XML
}

public MyView(Context context, AttributeSet attrs, int defStyle) {
  super(context, attrs, defStyle);
  // this constructor used where?
  // init variables
}


2 commentaires

Appelant Ceci invoque un autre constructeur de la classe actuelle. Je pense que c'est quelque chose que vous n'avez pas réalisé. Ainsi ceci (contexte, null); appels public myView (contexte context, attributset attrsses) { qui à tour appelle public myview (contexte context, attributset attrs, int Defstyle) {. Ces invocations de constructeur ne sont pas très courantes dans la langue Java, mais je ne vois aucune raison pour ne pas fonctionner.


Je me suis rendu compte que, j'étais juste préoccupé par les paramètres. :)


5 Réponses :


-2
votes

Yup, c'est un modèle raisonnable à utiliser pour que vous ne vous ne devez pas répéter le travail personnalisé dans chacun de vos constructeurs. Et non, il ne semble pas être des inconvénients à la méthode.


0 commentaires

-6
votes

EDIT:

Ce n'est pas correct. Voir d'autres réponses à cette question pour des raisons.


Réponse originale:

C'est OK.

Lorsque nous examinons la source de textview.java .

Ils ont utilisé la même hiérarchie. Donc, vous allez bien avec cette approche.


3 commentaires

Les gens enlèvent le vote, s'il vous plaît mentionner aussi la raison. J'ai également ajouté la propre référence de mise en œuvre de Android. Cette réponse est correcte avec le scénario donné de OP.


Vous avez probablement été évacué pour des raisons apparentes des autres réponses, comme celle-ci: Stackoverflow.com/a/36585383/504611


Merci @vickychijwani je l'obtiens.



-2
votes

Cela dépend purement de votre exigence. Disons que si vous souhaitez utiliser des méthodes de classe parent sans remplacer leur fonctionnalité dans votre vue personnalisée, vous devez utiliser Super () et instancier la classe mère. Si vous n'avez pas besoin d'invoquer des méthodes de classe parent, toutes les implémentations sont remplacées dans votre vue personnalisée, vous n'avez pas besoin. Lire un exemple de vue personnalisé Section de ce Lien .


0 commentaires

9
votes

Le seul inconvénient que je peux voir (que personne ne semble avoir mentionné) est que votre deuxième constructeur perd le DEFSTYLE de la superclasse, car vous le définissez à zéro. Regardez le code source de l'une des classes d'affichage d'Android et vous remarquerez que le deuxième constructeur dispose toujours d'un défstyle spécifique (code> défini par exemple.

Par exemple, il s'agit du deuxième constructeur de listeView: < / p> xxx

Si vous deviez étendre listeView à l'aide de la deuxième approche que vous décrivez, com.android.internal.r.attr.listviewstyle ne serait plus Le DEFSTYLE , car vous ignoriez ce deuxième super constructeur et le rendant à zéro. Je suppose que vous pouvez résoudre ce problème en utilisant le même DEFSTYLE comme listeView, comme: xxx

mais ce n'est pas exactement la voie "Purist", car Vous l'obligeez artificiellement à avoir le même defstyle comme listeView.

Donc, contrairement à ce que les autres ont dit, je pense que vous préférez bien utiliser le premier DoAdditionalConstructorwork () décrit dans votre message, car cela garantit au moins que Le DévSTyle est réglé correctement.


1 commentaires

Mais en regardant le code code source, nous pouvons voir qu'il définit de rapstyle à 0: vue publique (contexte context, attributset attrsses) {ceci (contexte, attrais, 0); }



6
votes

copié cela de ma réponse à une question similaire.

Si vous remplacez les trois constructeurs, veuillez ne pas cascade ceci (...) code> appels. Vous devriez plutôt faire cela: p>

public TextView(Context context) {
    this(context, null);
}

public TextView(Context context, @Nullable AttributeSet attrs) {
    this(context, attrs, com.android.internal.R.attr.textViewStyle);
}

public TextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
    this(context, attrs, defStyleAttr, 0);
}


0 commentaires