O aplicativo para Android que estou desenvolvendo atualmente tem uma atividade principal que cresceu bastante. Isso ocorre principalmente porque ele contém um TabWidget
com 3 guias. Cada guia possui alguns componentes. A atividade tem que controlar todos esses componentes de uma só vez. Então, eu acho que você pode imaginar que essa Atividade tenha 20 campos (um campo para quase todos os componentes). Também contém muita lógica (clique em listeners, em lógica para preencher listas, etc.).
O que normalmente faço em estruturas baseadas em componentes é dividir tudo em componentes personalizados. Cada componente personalizado teria uma responsabilidade clara. Ele conteria seu próprio conjunto de componentes e todas as outras lógicas relacionadas a esse componente.
Tentei descobrir como isso pode ser feito e encontrei algo na documentação do Android que eles chamam de "Controle composto". (Consulte http://developer.android.com/guide/topics/ui/custom-components.html#compound e vá até a seção "Compound Controls"). Gostaria de criar esse componente com base em um arquivo XML que define o ver estrutura.
Na documentação, diz:
Observe que, assim como em uma Activity, você pode usar a abordagem declarativa (baseada em XML) para criar os componentes contidos ou pode aninhá-los programaticamente a partir do seu código.
Bem, isso é uma boa notícia! A abordagem baseada em XML é exatamente o que eu quero! Mas não diz como fazê-lo, exceto que é "como uma atividade" ... Mas o que faço em uma atividade é chamar setContentView(...)
para aumentar as visualizações do XML. Esse método não está disponível se você, por exemplo, subclasse LinearLayout
.
Então, eu tentei inflar o XML manualmente assim:
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);
}
}
Isso funciona, exceto pelo fato de que o XML que estou carregando foi LinearLayout
declarado como o elemento raiz. Isso resulta no inflado LinearLayout
ser um filho do MyCompoundComponent
qual ele já é um LinearLayout
!! Portanto, agora temos um LinearLayout redundante no meio MyCompoundComponent
e as visualizações de que ele realmente precisa.
Alguém pode me fornecer uma maneira melhor de abordar isso, evitando LinearLayout
instâncias redundantes ?
fonte
Respostas:
Use a marca de mesclagem como sua raiz XML
Veja este artigo.
fonte
Eu acho que da maneira que você deve fazer isso, é usar o nome da sua classe como o elemento raiz XML:
E, em seguida, faça com que sua classe seja derivada do layout que você deseja usar. Observe que, se você estiver usando esse método , não usará o inflator de layout aqui.
E então você pode usar sua visualização em layouts XML normalmente. Se você deseja fazer a visualização de forma programática, precisa inflá-la você mesmo:
Infelizmente, isso não permite que você faça isso,
v = new MyView(context)
porque não parece haver uma maneira de contornar o problema de layouts aninhados, portanto, essa não é realmente uma solução completa. Você pode adicionar um método como esteMyView
para torná-lo um pouco melhor:Disclaimer: Eu posso estar falando besteira completa.
fonte
<com.example.views.MyView />
e yoursetData
eonFinishInflate
calls e começa a lançar NPEs, e você não tem idéia do porquê.