ViewBinding - як отримати прив'язку для включених макетів?


11

Працюючи з ViewBinding, я натрапив на кілька не задокументованих випадків.

По-перше: як отримати прив'язку для включених частин макета загального виду, основні прив'язки бачать лише елементи в основному макеті?

По-друге: Як отримати прив'язку для включених частин макета типу злиття, знову ж таки основні прив'язки бачать лише елементи в основному макеті?

Відповіді:


14

У випадку:

  1. Включаючи загальний макет (не вузол злиття), нам потрібно призначити ідентифікатор включеній частині, таким чином при прив'язці ми матимемо доступ до включеної підчастини
<include
    android:id="@+id/your_id"
    layout="@layout/some_layout" />

Таким чином у коді вашої діяльності:

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. Включити з блоком злиття у зовнішній макет. Ми не можемо додати до нього ідентифікатор, оскільки блок злиття не є переглядом. Скажімо, у нас є така вічна схема злиття (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>

Щоб правильно зв'язати такий макет злиття, нам потрібно:

У коді вашої діяльності:

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
Це здається помилкою. Це має просто працювати .
Мігель

7

Ваше перше питання, що працювати з включеним макетом за допомогою ViewBinding, можна вирішити так легко.

Ось зразок файлу 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>

І MainFragment.java може бути таким

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

Тепер у вас дві прив’язки. один із них є типовим, а наступний - із включеного макета.


1
Дуже проста відповідь і використовується новий синтаксис - все це працює для мене в нефрагментарній діяльності із подібним синтаксисом в onCreate(). Дякую. (Просто у вас виникли проблеми з використанням а DrawerLayout)
Fat Monk

0

Іншим простим способом було б використання бібліотеки прив'язки даних. Потім обгорніть ваш макет XML тегом, щоб, якщо ви використовуєте бібліотеку, автоматично генерували класи, необхідні для зв’язування поглядів у макеті з вашими об’єктами даних. Чесно кажучи, я думаю, що це шлях. Дотримуйтесь посібника тут

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.