Можем ли мы заменить findViewById() с помощью привязки данных Android в этом конкретном сценарии?

#android #android-databinding #findviewbyid

#Android #android-привязка данных #findviewbyid

Вопрос:

После привязки данных Android от Google я удалил findViewById() в своем коде.

У меня есть представление recycler с прослушивателем щелчков для каждой кнопки в определенном представлении элемента. Я пытаюсь найти способ исключить findViewById() метод в этом конкретном случае.

Фрагмент кода из MainFragment.java файл:

 // Add touch listener for the recycler view
    mainFragmentBinding.mainFragmentFoodItemsRecyclerView.addOnItemTouchListener(
            new RecyclerTouchListener(
                    getContext(),
                    mainFragmentBinding.mainFragmentFoodItemsRecyclerView,
                    new ClickListener() {

                        @Override
                        public void onClick(View view, final int position) {


                            Button addButton = view.findViewById(R.id.food_add_button);

                            addButton.setOnClickListener(addButtonView -> {

                                // Notify user
                                Toast.makeText(getContext(), "Clicked on Add button",
                                        Toast.LENGTH_SHORT).show();
                            });

                            // Values are passing to activity amp; to fragment as well
                            Toast.makeText(
                                    getContext(),
                                    "Single Click on position : "   position,
                                    Toast.LENGTH_SHORT
                            ).show();
                        }

                        @Override
                        public void onLongClick(View view, int position) {

                            Toast.makeText(
                                    getContext(),
                                    "Long press on position : "   position,
                                    Toast.LENGTH_LONG
                            ).show();
                        }
                    }
            ));
  

Строка, которую я хочу изменить из приведенного выше фрагмента:

 Button addButton = view.findViewById(R.id.food_add_button);
  

Возможно ли это? Если да, может ли кто-нибудь помочь мне с тем же?
Или я должен оставить findViewById() метод как таковой?

Комментарии:

1. Это view в этой строке является частью привязки адаптера . Таким образом, если у вас есть привязка в адаптере, вы можете просто передать ее в onClick обратном вызове.

Ответ №1:

Да, вы можете заменить его, и вам, вероятно, следует.

Для этого сначала подготовьте макет вашего элемента для привязки данных и добавьте туда обратный вызов click:

 ?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <data>
        <variable
            name="item"
            type="com.example.your.item.Type"/>
        <variable
            name="parentViewModel"
            type="com.example.your.viewmodel.Type"/>
    </data>

    <YourLayout
        ...
        android:onClick="@{() -> parentViewModel.onItemClicked(item)}"
        ...
        YourLayout />

</layout>
  

В вашем view holder объявите свойство для хранения ссылки на ваш привязанный макет элемента:

 lateinit var binding: YoutItemLayoutBindable
  

В вашем адаптере внутри onCreateViewHolder(...) убедитесь, что вы увеличили макет элемента с помощью привязки данных:

 val inflater = LayoutInflater.from(parent.context)
val binding = DataBindingUtil.inflate<YoutItemLayoutBindable>(inflater, R.layout.your_item_layout, parent, false)
val viewHolder = ViewHolder(binding.root)

// Pass your activity/fragment as the lifeCycleOwner when creating the adapter
binding.lifecycleOwner = lifeCycleOwner

// Pass also your viewmodel as a parameter when creating the adapter
binding.parentViewModel = parentViewModel

viewHolder.binding = binding

return viewHolder
  

Затем внутри onBindViewHolder(...) установите элемент в качестве переменной для вашей привязки:

 val item = dataSet[position]
viewHolder.binding.item = item
viewHolder.binding.executePendingBindings()
  

И это все! Ваш код может отличаться от этого примера (возможно, вы даже не используете viewmodels), но я надеюсь, что вы сможете уловить идею.

Комментарии:

1. Где onItemClicked() определено?

2. В XML-коде через android:onClick . Макет YourLayout при нажатии вызывает метод onItemClicked() родительской viewmodel.

3. Как выглядит лямбда