#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. Как выглядит лямбда