Ao criar uma exibição personalizada, notei que muitas pessoas parecem fazer assim:
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.
}
Minha primeira pergunta é: e o construtor MyView(Context context, AttributeSet attrs, int defStyle)
? Não tenho certeza de onde é usado, mas vejo isso na super classe. Preciso e onde é usado?
fonte
Se você substituir todos os três construtores, por favor, não faça chamadas
this(...)
. Você deveria fazer o seguinte:O motivo é que a classe pai pode incluir atributos padrão em seus próprios construtores que você pode substituir acidentalmente. Por exemplo, este é o construtor para
TextView
:Se você não ligou
super(context)
, não teria definido corretamenteR.attr.textViewStyle
como o atributo attr.fonte
MyView (contexto de contexto)
Usado ao instanciar vistas de maneira programática.
MyView (contexto de contexto, AttributeSet attrs)
Usado pelo
LayoutInflater
para aplicar atributos xml. Se um desses atributos for nomeadostyle
, os atributos serão procurados no estilo antes de procurar valores explícitos no arquivo xml de layout.MyView (contexto de contexto, AttributeSet attrs, int defStyleAttr)
Suponha que você queira aplicar um estilo padrão a todos os widgets sem precisar especificar
style
em cada arquivo de layout. Por exemplo, torne todas as caixas de seleção rosa por padrão. Você pode fazer isso com o defStyleAttr e a estrutura pesquisará o estilo padrão no seu tema.Observe que
defStyleAttr
foi nomeado incorretamentedefStyle
há algum tempo e há alguma discussão sobre se esse construtor é realmente necessário ou não. Consulte https://code.google.com/p/android/issues/detail?id=12683MyView (contexto de contexto, AttributeSet attrs, int defStyleAttr, int defStyleRes)
O terceiro construtor funciona bem se você tiver controle sobre o tema base dos aplicativos. Isso funciona para o google porque eles enviam seus widgets ao lado dos temas padrão. Mas suponha que você esteja escrevendo uma biblioteca de widgets e deseje que um estilo padrão seja definido sem que os usuários precisem ajustar o tema. Agora você pode fazer isso usando
defStyleRes
o valor padrão nos 2 primeiros construtores:Contudo
Se você estiver implementando suas próprias visualizações, apenas os 2 primeiros construtores devem ser necessários e podem ser chamados pela estrutura.
Se você deseja que seu Views seja extensível, implemente o quarto construtor para que os filhos da sua classe possam usar o estilo global.
Não vejo um caso de uso real para o terceiro construtor. Talvez um atalho se você não fornecer um estilo padrão para o seu widget, mas ainda assim desejar que seus usuários possam fazê-lo. Não deveria acontecer tanto assim.
fonte
Kotlin parece aliviar muita dor:
O @JvmOverloads irá gerar todos os construtores necessários (consulte a documentação da anotação ), cada um dos quais presumivelmente chama super (). Em seguida, substitua seu método de inicialização por um bloco Kotlin init {}. Código do Boilerplate desaparecido!
fonte
O terceiro construtor é muito mais complicado. Deixe-me dar um exemplo.
O
SwitchCompact
pacote Support-v7 suportathumbTint
etrackTint
atribui desde a versão 24, enquanto a versão 23 não os suporta. Agora você deseja apoiá-los na versão 23 e como fará para conseguir isso?Assumimos usar personalizado Ver
SupportedSwitchCompact
estendeSwitchCompact
.É um estilo de código tradicional. Observe que passamos 0 para o terceiro parâmetro aqui . Ao executar o código, você
getThumbDrawable()
sempre retornará nulo o quão estranho é, porque o métodogetThumbDrawable()
é o método de sua superclasseSwitchCompact
.Se você passar
R.attr.switchStyle
para o terceiro parâmetro, tudo vai bem.O terceiro parâmetro é um atributo simples. O atributo aponta para um recurso de estilo. No caso acima, o sistema encontrará o
switchStyle
atributo no tema atual, felizmente, o sistema o encontrará.Em
frameworks/base/core/res/res/values/themes.xml
, você verá:fonte
Se você precisar incluir três construtores como o que está sendo discutido agora, poderá fazer isso também.
fonte