Visualizza associazione Parte di Android Jetpack.

L'associazione delle visualizzazioni è una funzionalità che semplifica la scrittura del codice che interagisce con le viste. Una volta abilitata in un modulo, la vista di vista genera una classe di associazione per ogni file di layout XML presente in quel modulo. Un'istanza di una classe di associazione contiene riferimenti diretti a tutte le viste che hanno un ID nel layout corrispondente.

Nella maggior parte dei casi, l'associazione delle visualizzazioni sostituisce findViewById.

Configurazione

L'associazione delle visualizzazioni viene attivata a livello di singolo modulo. Per abilitare l'associazione di visualizzazione in un modulo, imposta l'opzione di build viewBinding su true nel file build.gradle a livello di modulo, come mostrato nell'esempio seguente:

Trendy

android {
    ...
    buildFeatures {
        viewBinding true
    }
}

Kotlin

android {
    ...
    buildFeatures {
        viewBinding = true
    }
}

Se vuoi che un file di layout venga ignorato durante la generazione delle classi di associazione, aggiungi l'attributo tools:viewBindingIgnore="true" alla visualizzazione principale del file di layout:

<LinearLayout
        ...
        tools:viewBindingIgnore="true" >
    ...
</LinearLayout>

Utilizzo

Se l'associazione Visualizza è abilitata per un modulo, viene generata una classe di associazione per ogni file di layout XML contenuto nel modulo. Ogni classe di associazione contiene riferimenti alla vista radice e a tutte le viste che hanno un ID. Il nome della classe di associazione viene generato convertendo il nome del file XML in formato Pascal e aggiungendo la parola "Associazione" alla fine.

Ad esempio, valuta un file di layout chiamato result_profile.xml contenente i seguenti elementi:

<LinearLayout ... >
    <TextView android:id="@+id/name" />
    <ImageView android:cropToPadding="true" />
    <Button android:id="@+id/button"
        android:background="@drawable/rounded_button" />
</LinearLayout>

La classe di associazione generata è denominata ResultProfileBinding. Questa classe ha due campi: TextView chiamato name e Button chiamato button. ImageView nel layout non ha ID, pertanto non è presente alcun riferimento alla classe nella classe di associazione.

Ogni classe di associazione include anche un metodo getRoot(), che fornisce un riferimento diretto per la visualizzazione principale del file di layout corrispondente. In questo esempio, il metodo getRoot() nella classe ResultProfileBinding restituisce la visualizzazione principale LinearLayout.

Le seguenti sezioni mostrano l'uso delle classi di associazione generate in attività e frammenti.

Utilizzare l'associazione di visualizzazioni nelle attività

Per configurare un'istanza della classe di associazione da utilizzare con un'attività, esegui questi passaggi nel metodo onCreate() dell'attività:

  1. Chiama il metodo inflate() statico incluso nella classe di associazione generata. In questo modo viene creata un'istanza della classe di associazione dell'attività da utilizzare.
  2. Recupera un riferimento alla visualizzazione principale chiamando il metodo getRoot() o utilizzando la sintassi delle proprietà Kotlin.
  3. Passa la visualizzazione radice a setContentView() in modo che sia quella attiva sullo schermo.

Questi passaggi sono illustrati nell'esempio seguente:

Kotlin

private lateinit var binding: ResultProfileBinding

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    binding = ResultProfileBinding.inflate(layoutInflater)
    val view = binding.root
    setContentView(view)
}

Java

private ResultProfileBinding binding;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    binding = ResultProfileBinding.inflate(getLayoutInflater());
    View view = binding.getRoot();
    setContentView(view);
}

Ora puoi utilizzare l'istanza della classe di associazione per fare riferimento a una qualsiasi delle viste:

Kotlin

binding.name.text = viewModel.name
binding.button.setOnClickListener { viewModel.userClicked() }

Java

binding.name.setText(viewModel.getName());
binding.button.setOnClickListener(new View.OnClickListener() {
    viewModel.userClicked()
});

Usare l'associazione di visualizzazioni in frammenti

Per configurare un'istanza di classe di associazione da utilizzare con un frammento, segui questi passaggi nel metodo onCreateView() del frammento:

  1. Chiama il metodo inflate() statico incluso nella classe di associazione generata. Questa operazione crea un'istanza della classe di associazione che il frammento può utilizzare.
  2. Recupera un riferimento alla visualizzazione principale chiamando il metodo getRoot() o utilizzando la sintassi delle proprietà Kotlin.
  3. Restituisci la visualizzazione principale dal metodo onCreateView() per renderla attiva.

Kotlin

private var _binding: ResultProfileBinding? = null
// This property is only valid between onCreateView and
// onDestroyView.
private val binding get() = _binding!!

override fun onCreateView(
    inflater: LayoutInflater,
    container: ViewGroup?,
    savedInstanceState: Bundle?
): View? {
    _binding = ResultProfileBinding.inflate(inflater, container, false)
    val view = binding.root
    return view
}

override fun onDestroyView() {
    super.onDestroyView()
    _binding = null
}

Java

private ResultProfileBinding binding;

@Override
public View onCreateView (LayoutInflater inflater,
                          ViewGroup container,
                          Bundle savedInstanceState) {
    binding = ResultProfileBinding.inflate(inflater, container, false);
    View view = binding.getRoot();
    return view;
}

@Override
public void onDestroyView() {
    super.onDestroyView();
    binding = null;
}

Ora puoi utilizzare l'istanza della classe di associazione per fare riferimento a una qualsiasi delle viste:

Kotlin

binding.name.text = viewModel.name
binding.button.setOnClickListener { viewModel.userClicked() }

Java

binding.name.setText(viewModel.getName());
binding.button.setOnClickListener(new View.OnClickListener() {
    viewModel.userClicked()
});

Fornisci suggerimenti per diverse configurazioni

Quando dichiari le viste in più configurazioni, a volte ha senso utilizzare un tipo di vista diverso a seconda del layout. Il seguente snippet di codice ne mostra un esempio:

# in res/layout/example.xml

<TextView android:id="@+id/user_bio" />

# in res/layout-land/example.xml

<EditText android:id="@+id/user_bio" />

In questo caso, potresti aspettarti che la classe generata mostri un campo userBio di tipo TextView, perché TextView è la classe base comune. A causa di limitazioni tecniche, il generatore di codice di associazione della vista non può determinarlo e genera invece un campo View. Devi trasmettere il campo in un secondo momento con binding.userBio as TextView.

Per ovviare a questo limite, l'associazione vista supporta un attributo tools:viewBindingType, che consente di indicare al compilatore quale tipo utilizzare nel codice generato. Nell'esempio precedente, puoi utilizzare questo attributo per fare in modo che il compilatore generi il campo come un TextView:

# in res/layout/example.xml (unchanged)

<TextView android:id="@+id/user_bio" />

# in res/layout-land/example.xml

<EditText android:id="@+id/user_bio" tools:viewBindingType="TextView" />

In un altro esempio, supponiamo di avere due layout, uno contenente BottomNavigationView e l'altro contenente NavigationRailView. Entrambe le classi estendono NavigationBarView, che contiene la maggior parte dei dettagli di implementazione. Se il codice non ha bisogno di sapere esattamente quale sottoclasse è presente nel layout attuale, puoi utilizzare tools:viewBindingType per impostare il tipo generato su NavigationBarView in entrambi i layout:

# in res/layout/navigation_example.xml

<BottomNavigationView android:id="@+id/navigation" tools:viewBindingType="NavigationBarView" />

# in res/layout-w720/navigation_example.xml

<NavigationRailView android:id="@+id/navigation" tools:viewBindingType="NavigationBarView" />

L'associazione View non può convalidare il valore di questo attributo quando si genera codice. Per evitare errori di compilazione e del tempo di esecuzione, il valore deve soddisfare le seguenti condizioni:

  • Il valore deve essere una classe che eredita da android.view.View.
  • Il valore deve essere una superclasse del tag in cui viene posizionato. Ad esempio, i seguenti valori non funzionano:

      <TextView tools:viewBindingType="ImageView" /> <!-- ImageView is not related to TextView. -->
      <TextView tools:viewBindingType="Button" /> <!-- Button is not a superclass of TextView. -->
    
  • Il tipo finale deve risolversi in modo coerente tra tutte le configurazioni.

Differenze da FindViewById

L'associazione Visualizza offre importanti vantaggi rispetto all'uso di findViewById:

  • Sicurezza nulla: poiché l'associazione delle viste crea riferimenti diretti alle viste, non esiste il rischio di un'eccezione di puntatore nullo a causa di un ID vista non valido. Inoltre, quando una vista è presente solo in alcune configurazioni di un layout, il campo contenente il riferimento nella classe di associazione è contrassegnato con @Nullable.
  • Sicurezza del tipo: i campi di ogni classe di associazione presentano tipi corrispondenti alle viste a cui fanno riferimento nel file XML. Ciò significa che non sussiste il rischio di un'eccezione alla trasmissione del corso.

Queste differenze significano incompatibilità tra il layout e il codice e, di conseguenza, la creazione della tua build potrebbe non andare a buon fine al momento della compilazione e non in fase di esecuzione.

Confronto con l'associazione di dati

Le associazioni di viste e di dati generano entrambe classi di associazione che puoi utilizzare per fare riferimento direttamente alle viste. Tuttavia, l'associazione delle visualizzazioni è pensata per gestire casi d'uso più semplici e offre i seguenti vantaggi rispetto all'associazione dei dati:

  • Compilazione più rapida: l'associazione delle visualizzazioni non richiede l'elaborazione delle annotazioni, pertanto i tempi di compilazione sono più rapidi.
  • Facilità d'uso: l'associazione delle visualizzazioni non richiede file con layout XML con tag speciale, quindi è più veloce da adottare nelle tue app. Una volta abilitata, l'associazione vista in un modulo viene applicata automaticamente a tutti i layout del modulo.

D'altra parte, l'associazione delle viste presenta le seguenti limitazioni rispetto all'associazione di dati:

Sulla base di queste considerazioni, in alcuni casi è preferibile utilizzare in entrambi i casi l'associazione di viste e l'associazione di dati. Puoi utilizzare l'associazione di dati nei layout che richiedono funzionalità avanzate e l'associazione di visualizzazioni nei layout che non lo fanno.

Risorse aggiuntive

Per scoprire di più sull'associazione delle visualizzazioni, consulta le seguenti risorse aggiuntive:

Samples

Blog

Video