ViewBinding - Wie bekomme ich eine Bindung für die enthaltenen Layouts?

11

Während der Arbeit mit ViewBinding stoße ich auf einige nicht dokumentierte Fälle.

Erstens: Wie erhalte ich eine Bindung für die enthaltenen generischen Ansichtslayoutteile? Die Hauptbindung zeigt nur Elemente im Hauptlayout an.

Zweitens: Wie erhalte ich eine Bindung für enthaltene Layoutteile vom Typ "Zusammenführen"? Auch hier zeigt die Hauptbindung nur Elemente im Hauptlayout.

Artur Kasprzak
quelle

Antworten:

15

Im Falle von:

  1. Bei generischem Layout (nicht Zusammenführungsknoten) müssen wir dem eingeschlossenen Teil eine ID zuweisen. Auf diese Weise haben wir beim Binden Zugriff auf das eingeschlossene Unterteil
<include
    android:id="@+id/your_id"
    layout="@layout/some_layout" />

So in Ihrem Aktivitätscode:

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. Mit Zusammenführungsblock in externes Layout aufnehmen. Wir können keine ID hinzufügen, da der Zusammenführungsblock keine Ansicht ist. Nehmen wir an, wir haben ein solches ewiges Zusammenführungslayout (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>

Um ein solches Zusammenführungslayout richtig zu binden, müssen wir:

In Ihrem Aktivitätscode:

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
quelle
1
Dies scheint ein Fehler zu sein. Es sollte einfach funktionieren .
Miguel
7

Ihre erste Frage, die mit ViewBinding mit einem enthaltenen Layout funktioniert, kann so einfach gelöst werden.

Hier ist ein Beispiel main_fragment.xml Datei

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

Und MainFragment.java kann so sein

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

Jetzt haben Sie zwei Bindungen. Eine davon ist die Standardeinstellung und die nächste stammt aus dem enthaltenen Layout.

Emi Raz
quelle
1
Sehr einfache Antwort und verwendet die neue Syntax - alles funktioniert für mich in einer Nicht-Fragment-Aktivität mit ähnlicher Syntax in onCreate(). Vielen Dank. (Ich habe nur ein bisschen Probleme mit a DrawerLayout)
Fat Monk
0

Der andere einfache Weg wäre die Verwendung der Datenbindungsbibliothek. Umschließen Sie dann Ihr XML-Layout mit einem Tag, sodass bei Verwendung der Bibliothek automatisch die Klassen generiert werden, die zum Binden der Ansichten im Layout mit Ihren Datenobjekten erforderlich sind. Ehrlich gesagt denke ich, dass es der richtige Weg ist. Folgen Sie der Anleitung hier

Arun Gurung
quelle