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

Чаще всего вы хотите связать фрагменты между собой, например, чтобы изменить содержание, основанное на событиях пользователя. Вся связь между фрагментами выполняется через соответствующую activity . Два фрагменты никогда не должны общаться напрямую.

 

Определение интерфейса


Чтобы разрешить фрагменту общаться с его activity , можно определить интерфейс в классе фрагмента и реализовать его в activity . Фрагмент захватывает реализацию интерфейса во время его метода жизненного цикла onAttach(), а затем может вызывать методы интерфейса, чтобы общаться с activity .

Вот пример общения между фрагментом и activity :

public class HeadlinesFragment extends ListFragment {
    OnHeadlineSelectedListener mCallback;

    // Container Activity must implement this interface
    public interface OnHeadlineSelectedListener {
        public void onArticleSelected(int position);
    }

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        
        // This makes sure that the container activity has implemented
        // the callback interface. If not, it throws an exception
        try {
            mCallback = (OnHeadlineSelectedListener) activity;
        } catch (ClassCastException e) {
            throw new ClassCastException(activity.toString()
                    + " must implement OnHeadlineSelectedListener");
        }
    }
    
    ...
}

 

Теперь фрагмент может доставлять сообщения в activity вызывая onArticleSelected() метод (или другие методы интерфейса), используя mCallback экземпляр OnHeadlineSelectedListenerинтерфейса.

Например, следующий метод фрагмента вызывается, когда пользователь нажимает на элемент списка. Фрагмент использует интерфейс обратного вызова для доставки событий в родительскую activity .

  @Override
    public void onListItemClick(ListView l, View v, int position, long id) {
        // Send the event to the host activity
        mCallback.onArticleSelected(position);
    }

 

Реализация интерфейса


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

Например, следующая activity реализует интерфейс из приведенного выше примера.

public static class MainActivity extends Activity
        implements HeadlinesFragment.OnHeadlineSelectedListener{
    ...
    
    public void onArticleSelected(int position) {
        // The user selected the headline of an article from the HeadlinesFragment
        // Do something here to display that article
    }
}

 

Доставка сообщения во фрагмент


activity , содержащая фрагмент, может доставлять сообщения во фрагменты, захвативFragment экземпляр с помощью findFragmentById(), затем напрямую вызывать общедоступные методы фрагмента.

Например, представьте, что activity показанная выше может содержать другой фрагмент, который используется для отображения элемента, указанного в данных возвращаемых методом обратного вызова выше. В этом случае activity может передать информацию, полученную в методе обратного вызова, в другой фрагмент, который будет отображать элемент:

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

    public void onArticleSelected(int position) {
        // The user selected the headline of an article from the HeadlinesFragment
        // Do something here to display that article

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

        if (articleFrag != null) {
            // If article frag is available, we're in two-pane layout...

            // Call a method in the ArticleFragment to update its content
            articleFrag.updateArticleView(position);
        } else {
            // Otherwise, we're in the one-pane layout and must swap frags...

            // Create fragment and give it an argument for the selected article
            ArticleFragment newFragment = new ArticleFragment();
            Bundle args = new Bundle();
            args.putInt(ArticleFragment.ARG_POSITION, position);
            newFragment.setArguments(args);
        
            FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();

            // Replace whatever is in the fragment_container view with this fragment,
            // and add the transaction to the back stack so the user can navigate back
            transaction.replace(R.id.fragment_container, newFragment);
            transaction.addToBackStack(null);

            // Commit the transaction
            transaction.commit();
        }
    }
}

 

 

2 комментария

andrii · 08.08.2015 в 16:36

как этим же способом передать и принять объект?

Judg · 25.03.2016 в 20:06

Доброго времени суток,

не могли бы привести пример как мог бы выглядеть метод articleFrag.updateArticleView(position); при передаче сообщения во фрагмент? Заранее спасибо.

Добавить комментарий

Этот сайт использует Akismet для борьбы со спамом. Узнайте как обрабатываются ваши данные комментариев.