Pergunta

O aplicativo Android Estou actualmente a desenvolver tem uma actividade principal que tem crescido bastante grande. Isto é principalmente porque contém um TabWidget com 3 abas. Cada guia tem muito poucos componentes. A actividade tem de controlar de todos os componentes de uma só vez. Então eu acho que você pode imaginar que esta actividade tem como 20 campos (um campo para quase todos os componentes). Também contém uma grande quantidade de lógica (clique ouvintes, lógica para listas de preenchimento, etc).

O que eu faço normalmente em estruturas baseada em componentes é dividir tudo em componentes personalizados. Cada componente personalizado teria, então, uma clara responsabilidade. Seria conter o seu próprio conjunto de componentes e todos os outros lógica relacionada a esse componente.

Eu tentei descobrir como isso pode ser feito, e eu encontrei algo na documentação do Android que eles gostam de chamar de "Controle Composto". (Veja http://developer.android.com/guide/topics /ui/custom-components.html#compound e vá até a seção "Composto Controls") gostaria de criar um tal componente baseado em um arquivo XML que define a estrutura vista.

Na documentação diz:

Note que, assim como com uma atividade, você pode usar a declarativa abordagem para a criação da (baseado em XML) continha componentes, ou você pode aninhar -los programaticamente 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 ele é "como com uma atividade" ... Mas o que eu faço em uma atividade é chamada setContentView(...) para inflar as vistas 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 eu sou a carga tem LinearLayout declarado como o elemento raiz. Isto resulta na LinearLayout inflado ser um filho de MyCompoundComponent que se já é um LinearLayout !! Portanto, agora temos um LinearLayout redundante entre MyCompoundComponent ea vista que ele realmente precisa.

Pode alguém por favor me fornecer uma melhor maneira de abordar esta questão, evitando ter um LinearLayout redundante instanciado?

Foi útil?

Solução

Use merge tag

como seu raiz XML

<merge xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Your Layout -->
</merge>

Confira este artigo.

Outras dicas

Eu acho que a maneira que você é suposto fazer isso, é usar o nome da classe como o elemento raiz XML:

<com.example.views.MyView xmlns:....
       android:orientation="vertical" etc.>
    <TextView android:id="@+id/text" ... />
</com.example.views.MyView>

E, em seguida, ter a sua classe derivada de qualquer layout que você deseja usar. Note que se você estiver usando este método você não usar o inflater disposição aqui.

public class MyView extends LinearLayout
{
    public ConversationListItem(Context context, AttributeSet attrs)
    {
        super(context, attrs);
    }
    public ConversationListItem(Context context, AttributeSet attrs, int defStyle)
    {
        super(context, attrs, defStyle);
    }


    public void setData(String text)
    {
        mTextView.setText(text);
    }

    private TextView mTextView;

    @Override
    protected void onFinishInflate()
    {
        super.onFinishInflate();

        mTextView = (TextView)findViewById(R.id.text);
    }
}

E, em seguida, você pode usar a sua visão em layouts XML como normal. Se você quiser fazer o ponto de vista de programação que você tem a inflar-se:

MyView v = (MyView)inflater.inflate(R.layout.my_view, parent, false);

Infelizmente, este não deixa você fazer v = new MyView(context) porque não parece ser uma maneira de contornar o problema layouts aninhadas, de modo que este não é realmente uma solução completa. Você poderia adicionar um método como este para MyView para torná-lo um agradável pouco:

public static MyView create(Context context)
{
    return (MyView)LayoutInflater.fromContext(context).inflate(R.layout.my_view, null, false);
}

Disclaimer:. Posso estar falando besteira completa

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top