Событие OnClick не запускается во фрагменте внутри ViewPager
У меня есть фрагменты внутри ViewPager
и я хотел бы, чтобы в одном из них был доступен RelativeLayout
с возможностью клика. Я использую привязку данных:
<data>
<variable
name="handlers"
type="com.matip.presenters.MyPresenter" />
</data>
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="@{() -> handlers.onLayoutClick()}">
...
...
...
</RelativeLayout>
Мои фрагменты onCreateView:
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
mBind = DataBindingUtil.inflate(inflater, R.layout.fragment_layout, container, false);
presenter = new MyPresenter();
mBind.includedLayout.setHandlers(presenter);
return mBind.getRoot();
}
Но onLayoutClick
не вызывается. Это имеет какое-то отношение к ViewPager? Требуется ли клик, а не фрагмент внутри него? Если да, то как я могу это исправить?
РЕДАКТИРОВАТЬ
My ViewPager Adapter:
private class MyViewPagerAdapter extends FragmentStatePagerAdapter {
public MyViewPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int position) {
switch(position) {
case 0:
return MainInfoFragment.newInstance(parkingId);
case 1:
return MainDescFragment.newInstance(parkingId);
case 2:
return MainServicesFragment.newInstance(parkingId);
default:
return null;
}
}
@Override
public int getCount(){
return 3;
}
@Nullable
@Override
public CharSequence getPageTitle(int position) {
switch(position){
case 0: return getContext().getString(R.string.info_title);
case 1: return getContext().getString(R.string.desc_title);
case 2: return getContext().getString(R.service_title);
default: return null;
}
}
}
Ответы
Ответ 1
Чтобы получить атрибут onClick
в XML для работы, этот метод должен быть активен. Для фрагментов предпочтительный метод устанавливает программный вызов слушателя. Метод XML будет работать, если метод находится в действии, но он станет сложным, если метод должен вести себя по-разному для разных фрагментов.
Также я не понимаю, что вы подразумеваете под android:onClick="@{() → handlers.onLayoutClick()}"
. Обычно он выглядит как android:onClick="onLayoutClick"
. И определение будет похоже на
public void onLayoutClick(View view) {
//Your code
}
Существует еще одна возможность: вы можете установить OnTouchListener в представление, которое отменяет щелчок. Если вы хотите прослушивать как прослушивающие, так и щелчки, попробуйте GestureDetector.
Ответ 2
вы можете сделать следующее по методу oncreateview()
oncreate(....)
{.....
View v = inflater.inflate(R.layout.fragment_layout,container,false);
RelativeLayout l = v.findViewById(R.id.rl);
l.setOnClickListener(this);
.....}
@Override
public void onClick(View v)
{
if(v.getId == R.id.rl)
{
//do your work
}
}
и измените макет на это
<RelativeLayout
android:id="@+id/rl"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
>
...
...
...
</RelativeLayout>
нажмите alt + введите в clicklistener, если компилятор показывает ошибку
Ответ 3
Как вы получите, что метод includedLayout из Binding класса?
Я не могу найти его нигде, и это была ошибка, которую я получил, вместо этого вы должны просто использовать mBind.setHandlers(presenter);
Сначала я получил ошибку для метода Binding.setHandler, но после сборки или запуска он был решен и работал должным образом.
А также
Класс MyPresenter должен иметь точную подпись метода. для handlers.onLayoutClick() это должно быть:
public void onLayoutClick(){
....}
Нет проблем с ViewPager, я старался точно так же, как и ваш.
Также проверьте mBind Type, из вашего кода, я думаю, это должен быть FragmentLayoutBinding.
Фрагмент:
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
FragmentLayoutBinding mBind = DataBindingUtil.inflate(inflater, R.layout.fragment_layout, container, false);
MyPresenter presenter = new MyPresenter();
mBind.setHandlers(presenter);
return mBind.getRoot();
}
MyPresenter:
public class MyPresenter{
//using listener binding
public void onLayoutClick(){
//do something..
}
//using method reference
public void onButtonClicked(View view){
// do something
}
}
fragment_layout:
<layout...>
<data>
<variable
name="handlers"
type="com.matip.presenters.MyPresenter" />
</data>
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="@{() -> handlers.onLayoutClick()}">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="32dp"
android:text="Using Method Ref"
android:onClick="@{handlers::onButtonClicked}"/>
</RelativeLayout>
</layout>
Ответ 4
Попробуйте использовать ссылку на метод вместо нотации привязки слушателя, ваш xml будет выглядеть следующим образом:
android:onClick="@{handlers::onLayoutClick}
И ваш Ведущий будет выглядеть так:
public class MyHandlers {
public void onLayoutClick(View view) { ... }
}
/!\Обратите внимание, что подпись метода должна принимать представление как параметр и возвращать пустоту и быть общедоступной
EDIT: вы также можете убедиться, что ни один из дочерних элементов relativeLayout не получит клик, а добавит:
android:descendantFocusability="beforeDescendants"