ViewBinding: come ottenere il binding per i layout inclusi?


11

Mentre lavoro con ViewBinding mi imbatto in alcuni casi non documentati.

Primo: come ottenere la rilegatura per le parti del layout della vista generiche incluse, la rilegatura principale vede solo gli elementi nel layout principale?

Secondo: come ottenere la rilegatura per le parti del layout del tipo di unione incluse, ancora la rilegatura principale vede solo gli elementi nel layout principale?

Risposte:


15

In caso di:

  1. Includi con layout generico (non unisci nodo), dobbiamo assegnare l'ID alla parte inclusa, in questo modo in associazione avremo accesso alla parte inclusa
<include
    android:id="@+id/your_id"
    layout="@layout/some_layout" />

In questo modo nel codice attività:

private lateinit var exampleBinding: ActivityExampleBinding  //activity_example.xml layout

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    exampleBinding = ActivityExampleBinding.inflate(layoutInflater)
    setContentView(exampleBinding.root)
    //we will be able to access included layouts view like this
    val includedView: View = exampleBinding.yourId.idOfIncludedView
//[...]
}
  1. Includi con unisci blocco nel layout esterno. Non è possibile aggiungere ID perché il blocco unione non è una vista. Diciamo che abbiamo un tale layout di unione eterna (merge_layout.xm):
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    tools:showIn="@layout/activity_example">

    <TextView
        android:id="@+id/some_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World" />
</merge>

Per associare correttamente tale layout di unione è necessario:

Nel tuo codice attività:

private lateinit var exampleBinding: ActivityExampleBinding  //activity_example.xml layout
private lateinit var mergeBinding: MergeLayoutBinding  //merge_layout.xml layout

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    exampleBinding = ActivityExampleBinding.inflate(layoutInflater)
    //we need to bind the root layout with our binder for external layout
    mergeBinding = MergeLayoutBinding.bind(exampleBinding.root)
    setContentView(exampleBinding.root)
    //we will be able to access included in merge layout views like this
    val mergedView: View = mergeBinding.someView
//[...]
}

1
Sembra un bug. Dovrebbe solo funzionare .
miguel

7

La tua prima domanda, che funziona con un layout incluso usando ViewBinding, può essere risolta così facilmente.

Ecco un esempio di file main_fragment.xml

<?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">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recycler_view_main"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1" />

    <include
        android:id="@+id/toolbar"
        layout="@layout/toolbar" />

</LinearLayout>

E MainFragment.java può essere così

public class MeaningFragment extends Fragment {

    private MainFragmentBinding binding;
    private ToolbarBinding toolbarBinding;

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {

        binding = MainFragmentBinding.inflate(inflater, container, false);
        toolbarBinding = binding.toolbar;

        return binding.getRoot();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();

        toolbarBinding = null;
        binding = null;
    }
}

Ora hai due attacchi. uno di questi è il valore predefinito e il successivo è dal layout incluso.


1
Risposta molto semplice e utilizza la nuova sintassi - tutto funziona per me in un'attività non frammentata con sintassi simile in onCreate(). Grazie. (Ho solo un po 'di problemi a usare per a DrawerLayout)
Fat Monk

0

L'altro modo semplice sarebbe utilizzare la libreria di associazione dei dati. Quindi avvolgere il layout XML con tag in modo che se si sta utilizzando la libreria generi automaticamente le classi richieste per associare le viste nel layout con i propri oggetti dati. Onestamente, penso che sia la strada da percorrere. Segui la guida qui

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.