ViewBinding: ¿cómo obtener el enlace para los diseños incluidos?

11

Mientras trabajo con ViewBinding me encuentro con pocos casos no documentados.

Primero: ¿Cómo obtener el enlace para las partes de diseño de vista genérica incluidas, el enlace principal solo ve los elementos en el diseño principal?

Segundo: ¿Cómo obtener el enlace para las partes de diseño de tipo de fusión incluidas, nuevamente el enlace principal ve solo los elementos en el diseño principal?

Artur Kasprzak
fuente

Respuestas:

15

En caso de:

  1. Incluir con diseño genérico (no nodo de fusión), necesitamos asignar ID a la parte incluida, de esta manera en el enlace tendremos acceso a la subparte incluida
<include
    android:id="@+id/your_id"
    layout="@layout/some_layout" />

De esta manera en su código de actividad:

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. Incluir con bloque de fusión en diseño externo. No podemos agregarle ID porque el bloque de fusión no es una vista. Digamos que tenemos un diseño de fusión eterno (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>

Para enlazar correctamente dicho diseño de combinación, necesitamos:

En su código de actividad:

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
//[...]
}
Artur Kasprzak
fuente
1
Esto parece un error. Simplemente debería funcionar .
miguel
7

Su primera pregunta, que es trabajar con un diseño incluido usando ViewBinding, puede resolverse tan fácilmente.

Aquí hay un archivo de ejemplo 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>

Y MainFragment.java puede ser así

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

Ahora, tienes dos enlaces. uno de ellos es el predeterminado y el siguiente es del diseño incluido.

Emi Raz
fuente
1
Respuesta muy simple y utiliza la nueva sintaxis: todo funciona para mí en una actividad sin fragmentos con una sintaxis similar onCreate(). Gracias. (Solo me cuesta un poco usarlo para a DrawerLayout)
Fat Monk
0

La otra forma simple sería usar la biblioteca de enlace de datos. Luego, ajuste su diseño XML con una etiqueta para que, si está utilizando la biblioteca, genere automáticamente las clases necesarias para vincular las vistas en el diseño con sus objetos de datos. Honestamente, creo que es el camino a seguir. Sigue la guía aquí

Arun Gurung
fuente