Como adicionar programaticamente modos de exibição a modos de exibição

179

Digamos que eu tenho um LinearLayoute quero adicionar um modo de exibição no meu programa a partir do código Java. Que método é usado para isso? Não estou perguntando como isso é feito em XML, o que eu sei, mas como posso fazer algo ao longo desse código de exemplo?

(One View).add(Another View)

Como se pode fazer no Swing.

Moki
fonte

Respostas:

248

Ligar addViewé a resposta correta, mas você precisa fazer um pouco mais do que isso para fazê-lo funcionar.

Se você criar uma View através de um construtor (por exemplo, Button myButton = new Button();), precisará acessar setLayoutParamsa visualização recém-construída, passando uma instância da classe interna LayoutParams da visualização pai, antes de adicionar seu filho recém-construído à visualização pai.

Por exemplo, você pode ter o seguinte código em sua onCreate()função, assumindo que seu LinearLayout possui o ID R.id.main:

LinearLayout myLayout = findViewById(R.id.main);

Button myButton = new Button(this);
myButton.setLayoutParams(new LinearLayout.LayoutParams(
                                     LinearLayout.LayoutParams.MATCH_PARENT,
                                     LinearLayout.LayoutParams.MATCH_PARENT));

myLayout.addView(myButton);

Certifique-se de definir o LayoutParams é importante. Toda visualização precisa de pelo menos um parâmetro layout_width e layout_height. Também é importante obter a classe interna certa. Eu lutei para obter Views adicionadas a um TableRow para exibir corretamente até descobrir que não estava passando uma instância de TableRow.LayoutParams para setLayoutParams da exibição filho.

Brian Cooley
fonte
5
Como você criaria a exibição programaticamente, mas usando um arquivo de layout XML que você escreveu especificamente para essa nova exibição?
SK9
9
@ SK9 Você usaria um LayoutInflater, que você pode obter de um Contexto, geralmente a Atividade atual. Algo como: LayoutInflater myInflater = getLayoutInflater; Veja myView = myInflater.inflate (R.layout.myLayout, pai, falso);
Brian Cooley
1
Na verdade, getLayoutInflater () vem da classe Window (não Context) e é um método de conveniência em Activity.
Brian Cooley
2
Como prática de codificação, em findViewById, transmita para ViewGroup ou sempre a forma mais genérica de um objeto, para que, se ele mudar de um LinearLayout para um RelativeLayout, você não tenha refatoração.
Joel Teply
1
Estes são alguns detalhes: D
Vivek Solanki
51

para quem ainda estiver interessado:

a melhor maneira que encontrei é usar o método estático inflável do View.

View inflatedView = View.inflate(context, yourViewXML, yourLinearLayout);

onde yourViewXML é algo como R.layout.myView

observe que você precisa de um ViewGroup para adicionar uma visualização (que é qualquer layout que você possa imaginar)

Assim, como exemplo, digamos que você tenha um fragmento que a visualização já foi inflada e saiba que a visualização raiz é um layout e deseja adicionar uma visualização:

    View view = getView(); // returns base view of the fragment
    if (view == null)
        return;
    if (!(view instanceof ViewGroup))
        return;

    ViewGroup viewGroup = (ViewGroup) view;
    View popup = View.inflate(viewGroup.getContext(), R.layout.someView, viewGroup);
ndori
fonte
Você também pode escrever um método estático, algo assim addView(View v){ // your code after get view }seria uma visão encontrada usando findViewById(int resourceID)ou inflada como a sua inflatedView... apenas para expandir seu exemplo de fragmento.
Zgc7009 09/10
22

Isso é tarde, mas isso pode ajudar alguém :) :) Para adicionar a exibição programaticamente, tente como

LinearLayout rlmain = new LinearLayout(this);      
LinearLayout.LayoutParams llp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT,LinearLayout.LayoutParams.FILL_PARENT);          
LinearLayout   ll1 = new LinearLayout (this);

ImageView iv = new ImageView(this);
iv.setImageResource(R.drawable.logo);              
LinearLayout .LayoutParams lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);

iv.setLayoutParams(lp);
ll1.addView(iv);
rlmain.addView(ll1);              
setContentView(rlmain, llp);

Isso criará toda a sua exibição programaticamente. Você pode adicionar qualquer número de visualizações da mesma forma. Espero que isso possa ajudar. :)

AndroidOptimist
fonte
3

Mais uma maneira de adicionar a visualização da Atividade

ViewGroup rootLayout = findViewById(android.R.id.content);
rootLayout.addView(view);
yoAlex5
fonte
0

A ideia de definir restrições programaticamente pode ser cansativa. Esta solução abaixo funcionará para qualquer layout, seja de restrição, linear, etc. Ter.

Tudo o que você precisa fazer é aumentar a exibição de forma programática e, quando criança, para o FrameLayout usando o addChild()método Então, durante o tempo de execução, sua visualização seria inflada e colocada na posição correta. Por recomendação do Android, você deve adicionar apenas um childView ao FrameLayout [link] .

Aqui está a aparência do seu código, supondo que você deseje criar o TextView programaticamente em uma posição específica:

Passo 1:

No layout que conteria a vista a ser inflada, coloque um FrameLayout na posição correta e dê um ID, por exemplo, "container".

Etapa 2 Crie um layout com elemento raiz como a visualização que você deseja aumentar durante o tempo de execução, chame o arquivo de layout como "textview.xml":

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent" android:layout_height="match_parent">

</TextView>

BTW, defina os parâmetros de layout do seu frameLayout como wrap_content, sempre o layout do quadro se tornará tão grande quanto o pai, ou seja, a atividade, ou seja, a tela do telefone.

android:layout_width="wrap_content"
android:layout_height="wrap_content"

Se não estiver definido, porque uma visualização filho do quadro, por padrão, vai para a parte superior esquerda do layout do quadro, portanto, sua visualização simplesmente voará para a parte superior esquerda da tela.

etapa 3

No seu método oncreate, faça o seguinte:

FrameLayout frameLayout = findViewById(R.id.container);
                TextView textView = (TextView) View.inflate(this, R.layout.textview, null);
                frameLayout.addView(textView);

(Nota que a criação último parâmetro findViewByIdpara nulle adicionando vista chamando addView()em vista recipiente (FrameLayout) é o mesmo que simplesmente unindo a visão inflada pela passagem trueem terceiro parâmetro findViewById(). Para mais, veja este .)

kush
fonte
0

Vocês também devem se certificar de que, quando você substituir, onLayoutTEM DE telefonar super.onLayoutcom todas as propriedades, ou a visualização não será inflada!

Oz Shabat
fonte