Layout nelle visualizzazioni

Prova il metodo Scrivi
Jetpack Compose è il toolkit consigliato per la UI per Android. Scopri come utilizzare i layout in Compose.

Un layout definisce la struttura di un'interfaccia utente nella tua app, ad esempio in un attività. Tutti gli elementi in sono creati utilizzando una gerarchia View e ViewGroup di oggetti strutturati. In genere, l'elemento View disegna qualcosa che l'utente può vedere e interagire con loro. Un ViewGroup è un container invisibile che definisce la struttura del layout per View e altri ViewGroup degli oggetti, come mostrato nella Figura 1.

Figura 1. Illustrazione di una gerarchia di visualizzazione, che definisce un layout UI.

Gli oggetti View sono spesso chiamati widget e possono essere uno di molte sottoclassi, Button o TextView. La Gli oggetti ViewGroup sono generalmente chiamati layout e possono essere uno solo di molti tipi con una struttura di layout diversa, ad esempio: LinearLayout o ConstraintLayout.

Puoi dichiarare un layout in due modi:

  • Dichiara gli elementi UI in XML. Android fornisce un file XML semplice vocabolario che corrisponde alle classi e alle sottoclassi View, come quelli per widget e layout. Puoi anche usare il database di Android Studio Editor del layout per creare il tuo XML utilizzando un'interfaccia di trascinamento.

  • Crea un'istanza degli elementi di layout in fase di runtime. La tua app può creare View e ViewGroup oggetti e manipolano i relativi in modo programmatico.

Dichiarare la tua UI in XML ti consente di separare la presentazione della tua app da il codice che ne controlla il comportamento. L'utilizzo dei file XML semplifica inoltre fornire layout diversi a seconda delle dimensioni e degli orientamenti dello schermo. Questo è più avanti in Supporto di schermi diversi dimensioni.

Il framework Android offre la flessibilità di utilizzare una o entrambe per creare l'UI della tua app. Ad esempio, puoi dichiarare la proprietà i layout predefiniti in XML e poi modificare il layout in fase di runtime.

Scrivi il file XML

Utilizzando il vocabolario XML di Android, puoi progettare rapidamente i layout dell'interfaccia utente elementi della schermata che contengono, nello stesso modo in cui crei pagine web in HTML con una serie di elementi nidificati.

Ogni file di layout deve contenere esattamente un elemento radice, che deve essere un Oggetto View o ViewGroup. Dopo aver definito il cluster puoi aggiungere altri oggetti di layout o widget come elementi secondari creare gradualmente una gerarchia View che definisce il layout. Per ad esempio, ecco un layout XML che utilizza un LinearLayout verticale per contengono TextView e Button:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:orientation="vertical" >
    <TextView android:id="@+id/text"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:text="Hello, I am a TextView" />
    <Button android:id="@+id/button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Hello, I am a Button" />
</LinearLayout>

Dopo aver dichiarato il layout in XML, salva il file con il .xml nell'estensione res/layout/ del tuo progetto Android in modo che venga compilato correttamente.

Per ulteriori informazioni sulla sintassi di un file XML di layout, consulta Risorsa di layout.

Carica la risorsa XML

Quando compili la tua app, ogni file di layout XML viene compilato in un View risorsa. Carica la risorsa di layout nel Activity.onCreate() dell'implementazione della callback. Per farlo, chiama setContentView(), passando il riferimento alla risorsa di layout nel formato: R.layout.layout_file_name. Ad esempio, se il tuo file XML layout è salvato come main_layout.xml, caricalo per Activity come segue:

Kotlin

fun onCreate(savedInstanceState: Bundle) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.main_layout)
}

Java

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main_layout);
}

Il framework Android chiama il metodo di callback onCreate() Activity al lancio di Activity. Per ulteriori informazioni informazioni sui cicli di vita delle attività, vedi Introduzione ai attività.

Attributi

Ogni oggetto View e ViewGroup supporta il proprio una varietà di attributi XML. Alcuni attributi sono specifici di un View . Ad esempio, TextView supporta textSize . Tuttavia, questi attributi vengono ereditati anche da qualsiasi View che estendono questa classe. Alcuni sono comuni a tutti i View oggetti, poiché sono ereditati dalla classe principale View, come l'attributo id. Altri attributi sono considerati layout parametri, che sono attributi che descrivono determinati orientamenti del layout dell'oggetto View, come definito dal relativo elemento principale ViewGroup oggetto.

ID

A qualsiasi oggetto View può essere associato un ID intero per identificare in modo univoco View all'interno dell'albero. Quando l'app è viene compilato, viene fatto riferimento a questo ID come un numero intero, ma in genere l'ID viene assegnato nel file XML di layout come stringa nell'attributo id. Si tratta di un Attributo XML comune a tutti gli oggetti View ed è definito dal View corso. Lo usi molto spesso. La sintassi di un ID all'interno di un Il tag XML è il seguente:

android:id="@+id/my_button"

Il simbolo at (@) all'inizio della stringa indica che il parser XML analizza ed espande il resto della stringa ID e la identifica come di una risorsa ID. Il simbolo più (+) indica che si tratta di un nuovo nome risorsa che devono essere creati e aggiunti alle tue risorse in R.java .

Il framework Android offre molte altre risorse ID. Quando si fa riferimento a un ID risorsa Android, non è necessario il simbolo più, ma devi aggiungere il carattere Spazio dei nomi del pacchetto android, come segue:

android:id="@android:id/empty"

Lo spazio dei nomi del pacchetto android indica che fai riferimento un ID della classe delle risorse android.R, anziché la risorsa risorse.

Per creare visualizzazioni e farvi riferimento dalla tua app, puoi utilizzare una comune come segue:

  1. Definisci una vista nel file di layout e assegnale un ID univoco, ad esempio nell'esempio seguente:
    <Button android:id="@+id/my_button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/my_button_text"/>
    
  2. Crea un'istanza dell'oggetto view e acquisiscila dal layout, di solito nel onCreate() , come illustrato nell'esempio seguente:

    Kotlin

    val myButton: Button = findViewById(R.id.my_button)
    

    Java

    Button myButton = (Button) findViewById(R.id.my_button);
    

La definizione degli ID per gli oggetti vista è importante quando si crea una RelativeLayout. In un layout relativo, le visualizzazioni gemelle possono definire il proprio layout rispetto a un'altra vista di pari livello, a cui fa riferimento l'ID univoco.

Un ID non deve essere necessariamente univoco in tutta la struttura ad albero, ma deve essere univoci nella parte dell'albero che cerchi. Spesso potrebbe trattarsi dell'intero quindi è meglio renderla unica, se possibile.

Parametri di layout

Definiscono gli attributi di layout XML denominati layout_something i parametri di layout per View che siano appropriati per ViewGroup in cui risiede.

Ogni classe ViewGroup implementa una classe nidificata che si estende ViewGroup.LayoutParams. Questa sottoclasse contiene tipi di proprietà che definiscono le dimensioni e la posizione di ogni vista secondaria, in base alle esigenze del gruppo di visualizzazione. Come mostrato nella figura 2, l'elemento principale Il gruppo di viste definisce i parametri di layout per ogni vista secondaria, inclusa quella secondaria visualizza gruppo.

Figura 2. Visualizzazione di una gerarchia di visualizzazioni con layout associati a ciascuna vista.

Ogni sottoclasse LayoutParams ha la propria sintassi per l'impostazione e i relativi valori. Ogni elemento secondario deve definire un LayoutParams che sia appropriato per l'elemento principale, anche se potrebbe anche definire un LayoutParams per i propri figli.

Tutti i gruppi di visualizzazioni includono larghezza e altezza, utilizzando layout_width e layout_height e ogni vista è necessaria per definirli. Molti LayoutParams includono margini e bordi facoltativi.

Puoi specificare la larghezza e l'altezza con misure esatte, ma non voglio farlo spesso. Molto spesso, si utilizza una di queste costanti per impostare per larghezza o altezza:

  • wrap_content: indica alla visualizzazione di ridimensionarsi dimensioni richieste dai suoi contenuti.
  • match_parent: indica che la visualizzazione deve diventare grande quanto l'elemento principale gruppo di visualizzazioni lo consente.

In generale, sconsigliamo di specificare la larghezza e l'altezza del layout utilizzando come i pixel. Un approccio migliore consiste nell'utilizzare misurazioni relative, come ad esempio unità pixel indipendenti dalla densità (dp), wrap_content o match_parent, perché consente alla tua app di essere visualizzata correttamente su un di schermi di dispositivi di varie dimensioni. I tipi di misurazione accettati sono definiti in Risorsa di layout.

Posizione layout

Una vista ha una geometria rettangolare. Ha una posizione, espressa come coppia Coordinate di left e top e due dimensioni, espresse come e larghezza e altezza. L'unità di misura per posizione e dimensioni è il pixel.

Puoi recuperare la posizione di una vista richiamando i metodi getLeft() e getTop(). Il primo restituisce la coordinata di sinistra (x) del rettangolo che rappresenta la vista. Quest'ultimo restituisce la coordinata superiore (y) del rettangolo che rappresenta la vista. Questi metodi restituiscono la posizione della vista in relazione a per l'elemento principale. Ad esempio, se getLeft() restituisce 20, significa che la si trova a 20 pixel a destra del bordo sinistro della sua principale.

Inoltre, esistono metodi pratici per evitare calcoli non necessari: ossia getRight() e getBottom(). Questi metodi restituiscono le coordinate dei bordi destro e inferiore del rettangolo che rappresenta la vista. Ad esempio, la chiamata a getRight() simile al seguente calcolo: getLeft() + getWidth().

Dimensioni, spaziatura interna e margini

Le dimensioni di una visualizzazione sono espresse con larghezza e altezza. Una vista ha due coppie di valori di larghezza e altezza.

La prima coppia è nota come larghezza misurata e altezza misurata. Queste dimensioni definiscono le dimensioni di una visualizzazione all'interno di quella principale. Puoi ottenere le dimensioni misurate richiamando getMeasuredWidth() e getMeasuredHeight().

La seconda coppia è nota come width e height o a volte larghezza del disegno e altezza del disegno. Queste dimensioni definiscono dimensioni effettive della visualizzazione sullo schermo, al momento del disegno e dopo il layout. Questi possono differire, ma non necessariamente, dalla larghezza e dall'altezza misurate. Tu ottenere la larghezza e l'altezza richiamando getWidth() e getHeight().

Per misurare le dimensioni, una vista prende in considerazione la spaziatura interna. Spaziatura interna è espresso in pixel per le parti sinistra, superiore, destra e inferiore della visualizzazione. Puoi utilizzare la spaziatura interna per compensare i contenuti della visualizzazione in base a un numero specifico di pixel. Ad esempio, una spaziatura interna sinistra di due spinge il contenuto della visualizzazione di due pixel. a destra del bordo sinistro. Puoi impostare la spaziatura interna utilizzando setPadding(int, int, int, int) ed eseguirvi query richiamando getPaddingLeft(), getPaddingTop(), getPaddingRight(), e getPaddingBottom().

Sebbene una vista possa definire una spaziatura interna, non supporta i margini. Tuttavia, non supportano i margini. Consulta ViewGroup e ViewGroup.MarginLayoutParams per ulteriori informazioni.

Per ulteriori informazioni sulle dimensioni, consulta Dimensione.

Oltre a impostare in modo programmatico i margini e la spaziatura interna, puoi anche impostarli nei layout XML, come mostrato nell'esempio seguente:

  <?xml version="1.0" encoding="utf-8"?>
  <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:orientation="vertical" >
      <TextView android:id="@+id/text"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_margin="16dp"
                android:padding="8dp"
                android:text="Hello, I am a TextView" />
      <Button android:id="@+id/button"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:layout_marginTop="16dp"
              android:paddingBottom="4dp"
              android:paddingEnd="8dp"
              android:paddingStart="8dp"
              android:paddingTop="4dp"
              android:text="Hello, I am a Button" />
  </LinearLayout>
  

L'esempio precedente mostra l'applicazione di margine e spaziatura interna. La TextView presenta margini e spaziatura interna uniformi applicati tutt'intorno e la Button mostra come applicarli in modo indipendente a i bordi.

Layout comuni

Ogni sottoclasse della classe ViewGroup fornisce un modo unico per mostrare le viste nidificate al suo interno. Il tipo di layout più flessibile e quello che offre i migliori strumenti per mantenere la gerarchia del layout superficiale, ConstraintLayout.

Di seguito sono riportati alcuni dei tipi di layout comuni integrati in Android. completamente gestita.

Creare un layout lineare

Organizza i relativi elementi secondari in una singola riga orizzontale o verticale e crea Una barra di scorrimento se la lunghezza della finestra supera quella dello schermo.

Creare app web in WebView

Visualizza le pagine web.

Creare elenchi dinamici

Se i contenuti del layout sono dinamici o non predeterminati, puoi utilizzare RecyclerView o una sottoclasse AdapterView. RecyclerView è generalmente l'opzione migliore perché utilizza la memoria in modo più efficiente rispetto a AdapterView.

Layout comuni possibili con RecyclerView e AdapterView include:

Elenco

Visualizza un elenco scorrevole di colonne singole.

Griglia

Visualizza una griglia a scorrimento di colonne e righe.

RecyclerView offre più possibilità l'opzione per crea un'immagine personalizzata Gestione layout.

Riempire una vista adattatore con i dati

Puoi compilare AdapterView come ListView o GridView di associando l'istanza AdapterView a un Adapter, che recupera i dati da un'origine esterna e crea un View che rappresenta ogni voce di dati.

Android offre diverse sottoclassi di Adapter utili per recuperare diversi tipi di dati e creare viste per un AdapterView. I due adattatori più comuni sono:

ArrayAdapter
Utilizza questo adattatore se l'origine dati è un array. Per impostazione predefinita, ArrayAdapter crea una vista per ogni elemento dell'array richiamando toString() su ogni elemento e inserendo i contenuti in un TextView.

Ad esempio, se hai un array di stringhe da visualizzare in un ListView, inizializza un nuovo ArrayAdapter utilizzando un per specificare il layout per ogni stringa e l'array di stringhe:

Kotlin

    val adapter = ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, myStringArray)
    

Java

    ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
            android.R.layout.simple_list_item_1, myStringArray);
    

Gli argomenti per questo costruttore sono i seguenti:

  • La tua app Context
  • Il layout che contiene un valore TextView per ogni stringa nel array
  • L'array di stringhe

Quindi chiama setAdapter() su ListView:

Kotlin

    val listView: ListView = findViewById(R.id.listview)
    listView.adapter = adapter
    

Java

    ListView listView = (ListView) findViewById(R.id.listview);
    listView.setAdapter(adapter);
    

Per personalizzare l'aspetto di ogni elemento, puoi eseguire l'override delle toString() per gli oggetti nell'array. Oppure, per creare una visualizzazione per ogni elemento che è diverso da una TextView, ad esempio, se vuoi che ImageView per ogni elemento dell'array: estendi la classe ArrayAdapter eseguire l'override getView() per restituire il tipo di visualizzazione desiderato.

SimpleCursorAdapter
Usa questo adattatore quando i dati provengono da una Cursor. Quando usi SimpleCursorAdapter, specifica un layout per ogni riga in Cursor e quali colonne Cursor da inserire nelle visualizzazioni del layout desiderato. Ad esempio, se vuoi creare un elenco di nomi e numeri di telefono numeri, puoi eseguire una query che restituisce un Cursor contenente una riga per ogni persona e colonne per i nomi e i numeri. Tu e poi creare un array di stringhe che specifichi quali colonne Cursor che vuoi nel layout per ogni risultato e un numero intero che specifichi le viste corrispondenti che ogni colonna deve posizionato:

Kotlin

    val fromColumns = arrayOf(ContactsContract.Data.DISPLAY_NAME,
                              ContactsContract.CommonDataKinds.Phone.NUMBER)
    val toViews = intArrayOf(R.id.display_name, R.id.phone_number)
    

Java

    String[] fromColumns = {ContactsContract.Data.DISPLAY_NAME,
                            ContactsContract.CommonDataKinds.Phone.NUMBER};
    int[] toViews = {R.id.display_name, R.id.phone_number};
    

Quando crei un'istanza per SimpleCursorAdapter, passa il parametro layout da usare per ogni risultato, il valore Cursor contenente il dei risultati, e questi due array:

Kotlin

    val adapter = SimpleCursorAdapter(this,
            R.layout.person_name_and_number, cursor, fromColumns, toViews, 0)
    val listView = getListView()
    listView.adapter = adapter
    

Java

    SimpleCursorAdapter adapter = new SimpleCursorAdapter(this,
            R.layout.person_name_and_number, cursor, fromColumns, toViews, 0);
    ListView listView = getListView();
    listView.setAdapter(adapter);
    

SimpleCursorAdapter crea quindi una vista per ogni riga in Cursor utilizzando il layout fornito inserendo ogni fromColumns elemento nel toViews corrispondente vista.

Se nel corso della vita dell'app modifichi i dati sottostanti che viene letto dall'adattatore, richiama notifyDataSetChanged(). La vista allegata viene informata che i dati sono stati modificati e l'aggiornamento viene eseguito per trovare le regole.

Gestire gli eventi di clic

Puoi rispondere agli eventi di clic su ciascun elemento in AdapterView implementando AdapterView.OnItemClickListener a riga di comando. Ad esempio:

Kotlin

listView.onItemClickListener = AdapterView.OnItemClickListener { parent, view, position, id ->
    // Do something in response to the click.
}

Java

// Create a message handling object as an anonymous class.
private OnItemClickListener messageClickedHandler = new OnItemClickListener() {
    public void onItemClick(AdapterView parent, View v, int position, long id) {
        // Do something in response to the click.
    }
};

listView.setOnItemClickListener(messageClickedHandler);

Risorse aggiuntive

Scopri come vengono utilizzati i layout Girasole app demo su GitHub.