Ai-je besoin tous les trois constructeurs pour Android affichage personnalisé?
Lors de la création d'un affichage personnalisé, j'ai remarqué que beaucoup de gens semblent le faire comme ceci:
public MyView(Context context) {
super(context);
//this constructor used when programmatically creating view
doAdditionalConstructorWork();
}
public MyView(Context context, AttributeSet attrs) {
super(context, attrs);
//this constructor used when creating view through XML
doAdditionalConstructorWork();
}
private void doAdditionalConstructorWork() {
//init variables etc.
}
Ma première question est, quel est le constructeur MyView(Context context, AttributeSet attrs, int defStyle)
? Je ne suis pas sûr de l'endroit où il est utilisé, mais je le vois dans la super-classe. J'ai besoin de lui, et où est-il utilisé?
Il y a une autre partie à cette question.
Vous devez vous connecter pour publier un commentaire.
Si vous allez ajouter votre personnalisé
View
dexml
aussi :vous aurez besoin du constructeur
public MyView(Context context, AttributeSet attrs)
, sinon vous aurez unException
quand Android tente de gonfler votreView
.Si vous ajoutez votre
View
dexml
et de spécifier leandroid:style
attribut comme :le 2ème constructeur sera appelé par défaut et le style de
MyCustomStyle
avant d'appliquer explicite des attributs XML.Le troisième constructeur est généralement utilisé lorsque vous voulez toutes les Vues de votre application afin d'avoir le même style.
View
de code.Si vous remplacez tous les trois constructeurs, s'il vous plaît NE PAS CASCADE
this(...)
APPELS. Vous devriez plutôt faire ceci:La raison en est que la classe parent peut inclure des attributs par défaut dans ses propres constructeurs que vous avez peut-être accidentellement primordial. Par exemple, c'est le constructeur de
TextView
:Si vous n'avez pas appeler
super(context)
, vous n'auriez pas correctement configuréR.attr.textViewStyle
que le style attr.Mavue(Context context)
Utilisé lors de la instanciating Vues par programmation.
Mavue(Context context, AttributeSet attrs)
Utilisé par le
LayoutInflater
pour appliquer des attributs xml. Si un de cet attribut est nomméstyle
, les attributs seront regardé le style avant de chercher les valeurs explicites dans la mise en page du fichier xml.Mavue(Context context, AttributeSet attrs, int defStyleAttr)
Supposons que vous souhaitez appliquer un style par défaut pour tous les widgets sans avoir à spécifier
style
dans chaque fichier de mise en page. Pour un exemple de prendre toutes les cases de rose par défaut. Vous pouvez faire cela avec defStyleAttr et le cadre de recherche le style par défaut dans votre thème.Noter que
defStyleAttr
a été nommé incorrectementdefStyle
il y a quelques temps et il y a une discussion sur la question de savoir si ce constructeur est vraiment nécessaire ou pas. Voir https://code.google.com/p/android/issues/detail?id=12683Mavue(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes)
Le 3ème constructeur fonctionne bien si vous avez le contrôle sur le thème de base des applications. Qui travaille pour google, car ils expédient leurs widgets sur le côté de la Thèmes par défaut. Mais supposons que vous êtes en train de rédiger une bibliothèque de widgets et que vous voulez un style par défaut pour fixer vos utilisateurs d'avoir à ajuster leur thème. Vous pouvez désormais le faire à l'aide de
defStyleRes
en paramètre à la valeur par défaut dans les 2 premiers constructeurs:Dans l'ensemble
Si vous êtes à la mise en œuvre de votre propre point de vue, seuls les 2 premiers constructeurs ne devrait être nécessaire et peut être appelée par le framework.
Si vous voulez que votre point de Vue pour être extensible, vous pourriez mettre en œuvre le 4ème constructeur pour les enfants de votre classe afin d'être en mesure d'utiliser le style.
Je ne vois pas un réel cas d'utilisation pour la 3ème constructeur. Peut-être un raccourci, si vous ne fournissez pas un style par défaut pour votre widget, mais encore envie à vos utilisateurs d'être en mesure de le faire. Ne devrait pas se produire tant que ça.
Kotlin semble prendre énormément de cette douleur:
@JvmOverloads va générer tous tenus de constructeurs (voir cette annotation est la documentation), chacun de qui sans doute des appels à super(). Ensuite, il suffit de remplacer votre méthode d'initialisation avec un Kotlin init {} bloc. Code réutilisable disparu!
Le troisième constructeur est beaucoup plus compliqué.Permettez-moi de tenir un exemple.
Soutien-v7
SwitchCompact
package prend en chargethumbTint
ettrackTint
attribut depuis le 24 version 23 version ne prend pas en charge.Maintenant, vous voulez les soutenir dans 23 version et comment allez-vous faire pour y parvenir?Nous supposons pour utiliser la Vue personnalisée
SupportedSwitchCompact
s'étendSwitchCompact
.C'est un code traditionnel de style.Remarque nous passer de 0 à la troisième param ici. Lorsque vous exécutez le code, vous trouverez
getThumbDrawable()
toujours retourner la valeur null comment c'est étrange parce que la méthodegetThumbDrawable()
est sa super classeSwitchCompact
s'méthode.Si vous passez
R.attr.switchStyle
à la troisième param, tout va bien.Alors pourquoi?Le troisième paramètre est un simple attribut. Les points d'attributs à un style de ressources.Dans le cas ci-dessus, le système trouverez
switchStyle
attribut dans le thème actuel heureusement système trouve.Dans
frameworks/base/core/res/res/values/themes.xml
, vous verrez:Si vous devez inclure trois constructeurs comme celui en discussion maintenant, vous pouvez faire cela aussi.