Come aggiungere le visualizzazioni a livello di programmazione


179

Diciamo che ho un LinearLayout, e voglio aggiungere una vista, nel mio programma dal codice Java. Quale metodo viene utilizzato per questo? Non sto chiedendo come sia fatto in XML, che conosco, ma piuttosto, come posso fare qualcosa sulla falsariga di questo codice di esempio?

(One View).add(Another View)

Come si può fare in Swing.

Risposte:


248

La chiamata addViewè la risposta corretta, ma è necessario fare un po 'di più per farlo funzionare.

Se crei una vista tramite un costruttore (ad esempio, Button myButton = new Button();), dovrai chiamaresetLayoutParams la vista appena costruita, passando un'istanza della classe interna LayoutParams della vista padre, prima di aggiungere il figlio di nuova costruzione alla vista padre.

Ad esempio, potresti avere il seguente codice nella tua onCreate()funzione supponendo che LinearLayout abbia un 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);

Assicurarsi di impostare LayoutParams è importante. Ogni vista richiede almeno un layout_width e un parametro layout_height. Anche ottenere la giusta classe interiore è importante. Ho avuto difficoltà a ottenere visualizzazioni aggiunte a un TableRow per visualizzare correttamente fino a quando non ho capito che non stavo passando un'istanza di TableRow.LayoutParams al setLayoutParams della vista figlio.


5
Come creeresti la vista a livello di codice ma utilizzando un file di layout XML che hai scritto in modo specifico per questa nuova vista?
SK9,

9
@ SK9 Dovresti utilizzare un LayoutInflater, che puoi ottenere da un contesto, di solito l'attività corrente. Qualcosa come: LayoutInflater myInflater = getLayoutInflater; Visualizza myView = myInflater.inflate (R.layout.myLayout, parent, false);
Brian Cooley,

1
In realtà getLayoutInflater () proviene dalla classe Window (non dal contesto) ed è un metodo pratico in Attività.
Brian Cooley,

2
Come pratica di codifica, su findViewById, esegui il cast in ViewGroup o sempre nella forma più generica di un oggetto in modo che, se passa da un LinearLayout a un RelativeLayout, non hai alcun refactoring.
Joel Teply,

1
Questi sono alcuni dettagli: D
Vivek Solanki,

51

per chiunque sia ancora interessato:

il modo migliore che ho trovato è di utilizzare il metodo statico inflazionare di View.

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

dove yourViewXML è qualcosa come R.layout.myView

ti preghiamo di notare che hai bisogno di un ViewGroup per aggiungere una vista (che è qualsiasi layout ti venga in mente)

quindi, ad esempio, supponiamo che tu abbia un frammento che è già stato gonfiato e sai che la vista radice è un layout e che vuoi aggiungere una vista:

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

Potresti anche scrivere un metodo statico, qualcosa del genere addView(View v){ // your code after get view }prenderebbe una visione trovata usando findViewById(int resourceID)o gonfiata come la tua inflatedView... solo per espandere il tuo esempio di frammento.
zgc7009,

22

Questo è in ritardo, ma questo può aiutare qualcuno :) :) Per aggiungere la vista a livello di programmazione, prova come

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

Questo creerà l'intera vista a livello di programmazione. Puoi aggiungere qualsiasi numero di vista come lo stesso. Spero che questo possa aiutare. :)



3

Un altro modo per aggiungere la vista dall'attività

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

0

L'idea di impostare i vincoli a livello di programmazione può essere noiosa. Questa soluzione di seguito funzionerà per qualsiasi layout sia vincolo, lineare, ecc. Il modo migliore sarebbe quello di impostare un segnaposto, ad esempio un FrameLayout con vincoli adeguati (o il posizionamento corretto in altri layout come lineare) nella posizione in cui ci si aspetterebbe la vista creata programmaticamente avere.

Tutto quello che devi fare è gonfiare la vista a livello di codice e da bambino a FrameLayout usando il addChild()metodo Quindi durante il runtime la tua vista verrebbe gonfiata e posizionata nella giusta posizione. Secondo i consigli di Android, è necessario aggiungere solo un childView a FrameLayout [link] .

Ecco come sarebbe il tuo codice, supponendo che desideri creare TextView a livello di programmazione in una posizione particolare:

Passo 1:

Nel layout che contiene la vista da gonfiare, posizionare un FrameLayout nella posizione corretta e dargli un ID, ad esempio "contenitore".

Passaggio 2 Creare un layout con l'elemento radice come vista che si desidera gonfiare durante il runtime, chiamare il file di layout come "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>

A proposito, imposta i parametri di layout del tuo frameLayout su wrap_content, altrimenti il ​​layout del frame diventerà grande quanto il genitore, ovvero l'attività, ovvero lo schermo del telefono.

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

Se non impostato, perché una vista figlio della cornice, per impostazione predefinita, va nella parte superiore sinistra del layout della cornice, quindi la vista volerà semplicemente nella parte superiore sinistra dello schermo.

Passaggio 3

Nel tuo metodo oncreate, procedi come segue:

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

(Si noti che l'impostazione dell'ultimo parametro di findViewByIdto nulle l'aggiunta della vista richiamando la addView()vista contenitore (frameLayout) equivale a collegare semplicemente la vista gonfiata passando il trueterzo parametro di findViewById(). Per ulteriori informazioni, vedere questo .)


0

Ragazzi dovreste anche assicurarvi che quando si esegue l'override onLayoutDOVETE chiamare super.onLayoutcon tutte le proprietà, altrimenti la vista non sarà gonfiata!

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.