Как обрабатывать нажатия кнопок, используя XML onClick внутри фрагментов - PullRequest
419 голосов
/ 23 мая 2011

Pre-Honeycomb (Android 3), каждое действие было зарегистрировано для обработки нажатий кнопок через тег onClick в XML макета:

android:onClick="myClickMethod"

В этом методе вы можете использовать view.getId() и оператор switch для логики кнопки.

С введением Honeycomb я разбил эти действия на фрагменты, которые можно повторно использовать во многих различных действиях. Большая часть поведения кнопок не зависит от активности, и я хотел бы, чтобы код находился внутри файла фрагментов без , используя старый (до 1.6) метод регистрации OnClickListener для каждой кнопки.

final Button button = (Button) findViewById(R.id.button_id);
button.setOnClickListener(new View.OnClickListener() {
    public void onClick(View v) {
        // Perform action on click
    }
});

Проблема в том, что, когда мои макеты завышены, все же хост-активность получает нажатия кнопок, а не отдельные фрагменты. Есть ли хороший подход к

  • Зарегистрировать фрагмент для получения нажатия кнопки?
  • Передать события клика из Действия в фрагмент, к которому они принадлежат?

Ответы [ 17 ]

1 голос
/ 30 июля 2015

Возможно, вы захотите использовать EventBus для развязанных событий. Вы можете очень легко прослушивать события.Вы также можете убедиться, что событие принимается в потоке пользовательского интерфейса (вместо вызова runOnUiThread .. для себя для каждой подписки на событие)

https://github.com/greenrobot/EventBus

от Github:

Шина событий, оптимизированная для Android, которая упрощает связь между операциями, фрагментами, потоками, службами и т. Д. Меньше кода, лучшее качество

1 голос
/ 19 мая 2015

Если вы зарегистрируетесь в xml с помощью android: Onclick = "", обратный вызов будет передан уважаемой активности, в контексте которой принадлежит ваш фрагмент (getActivity ()). Если такой метод не найден в Activity, система выдаст исключение.

1 голос
/ 15 февраля 2014

Добавление к ответу Бланделла,
Если у вас есть больше фрагментов, с большим количеством кликов:

Активность:

Fragment someFragment1 = (Fragment)getFragmentManager().findFragmentByTag("someFragment1 "); 
Fragment someFragment2 = (Fragment)getFragmentManager().findFragmentByTag("someFragment2 "); 
Fragment someFragment3 = (Fragment)getFragmentManager().findFragmentByTag("someFragment3 "); 

...onCreate etc instantiating your fragments

public void myClickMethod(View v){
  if (someFragment1.isVisible()) {
       someFragment1.myClickMethod(v);
  }else if(someFragment2.isVisible()){
       someFragment2.myClickMethod(v);
  }else if(someFragment3.isVisible()){
       someFragment3.myClickMethod(v); 
  }

} 

В вашем фрагменте:

  public void myClickMethod(View v){
     switch(v.getid()){
       // Just like you were doing
     }
  } 
1 голос
/ 03 мая 2017

Я хотел бы добавить к ответу Аджорна Линца .

Если вам нужно несколько обработчиков, вы можете просто использовать лямбда-ссылки

void onViewCreated(View view, Bundle savedInstanceState)
{
    view.setOnClickListener(this::handler);
}
void handler(View v)
{
    ...
}

Хитрость в том, что подпись handler метода соответствует View.OnClickListener.onClick подписи. Таким образом, вам не понадобится интерфейс View.OnClickListener.

Кроме того, вам не понадобятся операторы switch.

К сожалению, этот метод ограничен только интерфейсами, которые требуют одного метода или лямбда-выражения.

0 голосов
/ 13 апреля 2016

Ваша активность получает обратный вызов, как должны были использовать:

mViewPagerCloth.setOnClickListener((YourActivityName)getActivity());

Если вы хотите, чтобы ваш фрагмент получил обратный вызов, сделайте следующее:

mViewPagerCloth.setOnClickListener(this);

и реализовать onClickListener интерфейс во фрагменте

0 голосов
/ 26 ноября 2014

Это работает для меня: (Android studio)

 @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

        View rootView = inflater.inflate(R.layout.update_credential, container, false);
        Button bt_login = (Button) rootView.findViewById(R.id.btnSend);

        bt_login.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                System.out.println("Hi its me");


            }// end onClick
        });

        return rootView;

    }// end onCreateView
0 голосов
/ 19 апреля 2015

Лучшее решение ИМХО:

во фрагменте:

protected void addClick(int id) {
    try {
        getView().findViewById(id).setOnClickListener(this);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

public void onClick(View v) {
    if (v.getId()==R.id.myButton) {
        onMyButtonClick(v);
    }
}

затем в onViewStateRestored фрагмента:

addClick(R.id.myButton);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...