ViewBinding - como obter vinculação para layouts incluídos?

11

Ao trabalhar com o ViewBinding, encontro alguns casos não documentados.

Primeiro: como obter encadernação para peças de layout de vista genéricas incluídas, a encadernação principal vê apenas os itens no layout principal?

Segundo: como obter encadernação para peças de layout de tipo de mesclagem incluídas, novamente a encadernação principal vê apenas os itens no layout principal?

Artur Kasprzak
fonte

Respostas:

15

No caso de:

  1. Incluir no layout genérico (não no nó de mesclagem), precisamos atribuir o ID à parte incluída, dessa forma, na ligação, teremos acesso à subparte incluída
<include
    android:id="@+id/your_id"
    layout="@layout/some_layout" />

Desta forma, no seu código de atividade:

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 com bloco de mesclagem no layout externo. Não podemos adicionar ID a ele porque o bloco de mesclagem não é uma visualização. Digamos que tenhamos um layout de mesclagem 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 vincular adequadamente esse layout de mesclagem, precisamos:

No seu código de atividade:

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
fonte
11
Isso parece um bug. Deveria funcionar .
miguel
7

Sua primeira pergunta, que é trabalhar com um layout incluído usando o ViewBinding, pode ser resolvida com tanta facilidade.

Aqui está um arquivo main_fragment.xml de amostra

<?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 pode ser assim

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

Agora, você tem duas ligações. um deles é o padrão e o próximo é do layout incluído.

Emi Raz
fonte
11
Resposta muito simples e usa a nova sintaxe - todos trabalhando para mim em uma Atividade que não seja um fragmento com sintaxe semelhante onCreate(). Obrigado. (Apenas tendo um pouco de dificuldade em usar para um DrawerLayout)
Fat Monk
0

A outra maneira simples seria usar a biblioteca de ligação de dados. Em seguida, enrole seu layout XML com a tag para que, se você estiver usando a biblioteca, gere automaticamente as classes necessárias para vincular as visualizações no layout aos seus objetos de dados. Honestamente, acho que é o caminho a percorrer. Siga o guia aqui

Arun Gurung
fonte