Lekcja 6.3. Komunikacja z innymi fragmentami

> Dodaj do ulubionych

W tej lekcji:

  1. Definiowanie interfejsu
  2. Implementacja interfejsu
  3. Przekazywanie wiadomości do fragmentu

Do przeczytania:

Do wypróbowania:

Pobierz przykładowy interfejs.

Aby mieć możliwość ponownego wykorzystania fragmentów interfejsu, musisz zbudować każdy z nich w formie w pełni samodzielnego, modułowego komponentu, definiującego własny szablon i zachowanie. Kiedy już zdefiniujesz takie fragmenty wielokrotnego użytku, możesz powiązać je z jakąś aktywnością i połączyć z kodem sterującym aplikacją w cały interfejs użytkownika.

Często fragmenty muszą się ze sobą komunikować, np. by zmienić swoją treść w zależności od zdarzenia użytkownika. Komunikacja między fragmentami odbywa się poprzez powiązaną z nimi aktywność, nigdy bezpośrednio.

Definiowanie interfejsu

Aby umożliwić komunikację fragmentu z nadrzędną aktywnością, możesz zdefiniować interfejs w klasie fragmentu, a następnie zaimplementować go w aktywności. Fragment przechwyci implementację interfejsu podczas wykonywania metody cyklu życia onAttach(), a następnie wywoła metody interfejsu w celu skomunikowania się z aktywnością.

Oto przykład komunikacji pomiędzy fragmentem a aktywnością:

public class HeadlinesFragment extends ListFragment {
    OnHeadlineSelectedListener mCallback;

    // aktywność będąca kontenerem musi zaimplementować ten interfejs
    public interface OnHeadlineSelectedListener {
        public void onArticleSelected(int position);
    }

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        
        // upewniam się, że aktywność-kontener zaimplementowała
        // interfejs z metody zwrotnej; jeśli nie, zostanie zgłoszony wyjątek
        try {
            mCallback = (OnHeadlineSelectedListener) activity;
        } catch (ClassCastException e) {
            throw new ClassCastException(activity.toString()
                    + " must implement OnHeadlineSelectedListener");
        }
    }
    
    ...
}

Teraz fragment może przekazywać aktywności komunikaty poprzez wywołanie metody onArticleSelected() (lub innych metod interfejsu) za pomocą wystąpienia mCallback interfejsu OnHeadlineSelectedListener.

Poniższy przykład przedstawia metodę fragmentu wywoływaną po kliknięciu przez użytkownika pozycji z listy. Fragment przekazuje zdarzenie nadrzędnej aktywności za pomocą interfejsu zwrotnego.

@Override
    public void onListItemClick(ListView l, View v, int position, long id) {
        // wysyła zdarzenie do aktywności hostującej
        mCallback.onArticleSelected(position);
    }

Implementacja interfejsu

Aby otrzymać z fragmentu wywołania zwrotne zdarzenia, aktywność hostująca musi zaimplementować interfejs zdefiniowany w klasie fragmentu.

Przykładowo ta aktywność implementuje interfejs z powyższego przykładu:

public static class MainActivity extends Activity
        implements HeadlinesFragment.OnHeadlineSelectedListener{
    ...
    
    public void onArticleSelected(int position) {
        // użytkownik wybiera nagłówek artykułu z fragmentu HeadlinesFragment
        // zrób coś, żeby wyświetlić artykuł
    }
}

Przekazywanie wiadomości do fragmentu

Aktywność hostująca może przekazać fragmentowi wiadomość poprzez przechwycenie jego instancji i wywołanie metody findFragmentById(), a następnie bezpośrednio wywołując publiczne metody fragmentu.

Wyobraź sobie na przykład, że powyższa aktywność zawiera jeszcze jeden fragment, który służy do wyświetlania elementu określonego przez dane zwrócone w powyższej metodzie zwrotnej. W takim wypadku aktywność może przekazać informacje otrzymane od metody zwrotnej do fragmentu, który wyświetli żądany element:

public static class MainActivity extends Activity
        implements HeadlinesFragment.OnHeadlineSelectedListener{
    ...

    public void onArticleSelected(int position) {
        // użytkownik wybiera nagłówek artykułu z fragmentu HeadlinesFragment
        // zrób coś, żeby wyświetlić artykuł

        ArticleFragment articleFrag = (ArticleFragment)
                getSupportFragmentManager().findFragmentById(R.id.article_fragment);

        if (articleFrag != null) {
            // jeśli fragment artykułu jest dostępny, interfejs będzie dwupanelowy…

            // wywołaj metodę we fragmencie ArticleFragment, aby zaktualizować jego zawartość
            articleFrag.updateArticleView(position);
        } else {
            // w przeciwnym razie trzeba będzie podmienić  fragmenty, bo bieżący szablon jest jednopanelowy…

            // utwórz fragment i przekaż mu wybrany artykuł w formie argumentu
            ArticleFragment newFragment = new ArticleFragment();
            Bundle args = new Bundle();
            args.putInt(ArticleFragment.ARG_POSITION, position);
            newFragment.setArguments(args);
        
            FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();

            // zamień całą zawartość widoku fragment_container tym fragmentem
            // i dodaj transakcję do stosu tylnego, aby użytkownik miał opcję powrotu
            transaction.replace(R.id.fragment_container, newFragment);
            transaction.addToBackStack(null);

            // potwierdź transakcję
            transaction.commit();
        }
    }
}

Autor: Google

Źródło: http://developer.android.com/training/basics/fragments/communicating.html

Tłumaczenie: Joanna Liana

Treść tej strony jest dostępna na zasadach licencji CC BY 2.5