¿Debo llamar a super () o llamar a esto () para los constructores de vista personalizada de Android?

Al crear una vista personalizada, he notado que muchas personas parecen hacerlo así:

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. } 

Mi problema con esto es que me impide hacer mis variables finales. ¿Alguna razón para no hacer lo siguiente?

 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 } 

He sido capaz de crear la vista muy bien a través de XML y código, pero no estoy seguro si hay algún inconveniente a este enfoque. ¿Funcionará esto en todos los casos?

Hay otra parte de esta pregunta

Está bien.

Cuando miramos el origen de TextView.java .

Han utilizado la misma jerarquía.

Así que estás bien con este enfoque.

El único inconveniente que puedo ver (que nadie parece haber mencionado) es que su segundo constructor pierde el defStyle de la superclase, porque lo puso a cero. Mira el código fuente de cualquiera de las clases de vista de Android, y te darás cuenta de que el segundo constructor siempre tiene definido un defStyle específico.

Por ejemplo, este es el segundo constructor de ListView:

 public ListView(Context context, AttributeSet attrs) { this(context, attrs, com.android.internal.R.attr.listViewStyle); } 

Si extendieras ListView usando el segundo enfoque que describes, com.android.internal.R.attr.listViewStyle ya no sería el defStyle , porque estarías omitiendo ese segundo súper constructor y haciéndolo cero en su lugar. Supongo que podría resolver esto usando el mismo defstyle como ListView, así:

 public MyView(Context context, AttributeSet attrs) { this(context, attrs, android.R.attr.listViewStyle); } 

Pero no es exactamente la forma "purista", porque estás forzándola artificialmente a tener el mismo defStyle que ListView.

Por lo tanto, al contrario de lo que dijeron los demás, en realidad creo que es mejor usar el primer enfoque doAdditionalConstructorWork() descrito en su publicación, porque al menos se asegura de que defStyle esté configurado correctamente.

Copiado esto de mi respuesta para una pregunta similar.

Si anula los tres constructores, por favor NO CASCADE this(...) LLAMADAS. Deberías estar haciendo esto:

 public MyView(Context context) { super(context); init(context, null, 0); } public MyView(Context context, AttributeSet attrs) { super(context,attrs); init(context, attrs, 0); } public MyView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(context, attrs, defStyle); } private void init(Context context, AttributeSet attrs, int defStyle) { // do additional work } 

La razón es que la clase padre podría incluir atributos predeterminados en sus propios constructores que podría estar sobrepasando accidentalmente. Por ejemplo, este es el constructor de TextView :

 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); } 

Si no R.attr.textViewStyle super(context) , no R.attr.textViewStyle establecido correctamente R.attr.textViewStyle como el estilo attr.

Sí, eso es un patrón razonable de usar para que no tenga que repetir el trabajo personalizado en cada uno de sus constructores. Y no, no parece haber ningún inconveniente en el método.

Depende puramente de su requisito. Digamos que si quieres usar cualquier método en la clase padre sin reemplazar su funcionalidad en tu vista personalizada, entonces necesitas usar super () y instanciar la clase padre. Si no necesita invocar ningún método en la clase padre, todas las implementaciones se anularán en su vista personalizada y, a continuación, no será necesario. Lea una sección de ejemplo de vista personalizada en este enlace .

  • Soporte para diferentes resoluciones android
  • Cómo leer atributos personalizados en Android
  • Lona transparente para Android con transparencia
  • Vista circular personalizada
  • Android dibujar círculo con 2 colores (gráfico circular)
  • Android: Añadir un botón personalizado a SearchView Widget en Actionbar
  • No se encontró ningún recurso que coincida con el nombre dado '@ style / Widget.RatingBar.Small'
  • CastClassException en vista personalizada
  • No se encontró ningún identificador de recurso para el atributo '' in package 'com.app ...'
  • Cómo fijar la aplicación no responde?
  • Crear subviews de Android como subvisiones de iOS
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.