ViewPager и фрагменты - дизайн вложенных фрагментов или ...? - PullRequest
1 голос
/ 31 октября 2011

Документы говорят, что вы не должны вкладывать фрагменты, потому что они предназначены для работы по-другому.Но!

Область действия

Но что, если я использую ViewPager и его фрагмент (видимый экран) должен быть построен из других фрагментов.Допустим, у нас есть приложение для обмена сообщениями.На главном экране есть ViewPager с фрагментом, который называется «Последние сообщения» (MessagesFragment), а на вспомогательном экране (скажем, «Комната обсуждений» или «Чат») у нас также есть ViewPager, но экран «Сообщения» состоит из MessagesFragment, NewMessageBarFragment и, например, фрагмента заголовка с другой информацией.

Проблема

Можно сказать, что мы не должны использовать ViewPager для этого, и мы можем использовать библиотеку с открытым исходным кодом ViewFlow, но поверьте мне, код, содержащийся в таком действии, - беспорядок даже с фрагментами.Также есть подход для заполнения дополнительных макетов, а не фрагментов для NewMessageBar и HeaderInfo в MessagesFragment - но это для меня вдвойне уродливо.

Вопрос

Можно ли использовать вложенные фрагменты в данной конкретной ситуации??Что бы вы порекомендовали?

Upadate

Иногда это действительно «обязательная» функция.Но!В большинстве случаев я бы рекомендовал следовать «адаптивному дизайну»: http://www.slideshare.net/kirillcool/responsive-mobile-design-in-practice

Ответы [ 3 ]

5 голосов
/ 14 ноября 2012

Быстрое обновление:

Вложенные Fragment были официально представлены в Android API версии 17 .

2 голосов
/ 31 октября 2011

Но что, если я использую ViewPager и его фрагмент (видимый экран) должен быть построен из других фрагментов.

Не делайте этого.

Можно ли использовать вложенные фрагменты в данной конкретной ситуации?

Абсолютно нет .

Что бы вы порекомендовали?

Замените ваши "внешние" фрагменты на простые макеты.Затем используйте другую реализацию PagerAdapter, которая сама по себе не требует фрагмента (как и интерфейс FragmentPagerAdapter).Возможно, вам придется сжать некоторый код из FragmentPagerAdapter, чтобы убедиться, что все это работает хорошо.

Или объедините «MessagesFragment, NewMessageBarFragment и, например, фрагмент заголовка с другой информацией» в один фрагмент для использования на экранах размеров, гдеВы хотите иметь это поведение пейджера.Это может привести к некоторому дублированию кода, чтобы разделить пользовательский интерфейс отдельно для экранов меньшего размера.

1 голос
/ 16 ноября 2012

Вот мое решение. Теперь вы можете использовать getChildFragmentManager из фрагмента. Он включен в новую библиотеку SupportLibrary. В моем производственном решении я сначала проверяю наличие фрагментов и добавляю их только при необходимости.

public class TestActivity extends SherlockFragmentActivity {

    private ViewPager mPager;

    @Override
    protected void onCreate(Bundle arg0) {
        super.onCreate(arg0);
        setContentView(R.layout.pager);
        mPager = (ViewPager) findViewById(R.id.viewPager);
        mPager.setAdapter(new TestAdapter(getSupportFragmentManager()));
    }

    public class TestAdapter extends FragmentStatePagerAdapter {

        public TestAdapter(FragmentManager fm) {
            super(fm);
        }

        @Override
        public Fragment getItem(int position) {
            return TestFragment.newInstance(position);
        }

        @Override
        public int getCount() {
            return 4;
        }
    }

    public static class TestFragment extends SherlockFragment {

        private static final int ID = 9129345;
        private static final String ARG_INDEX = "TestFragment.pageindex";

        public static TestFragment newInstance(int page) {
            TestFragment fragment = new TestFragment();
            Bundle args = new Bundle();
            args.putInt(ARG_INDEX, page);
            fragment.setArguments(args);
            return fragment;
        }

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
            View view = inflater.inflate(R.layout.root_container, null);
            int pageId = getArguments().getInt(ARG_INDEX);

            FragmentTransaction transaction = getChildFragmentManager().beginTransaction();

            transaction.add(R.id.live_radio, TextFragment.newInstance("PAGE", pageId + 1));
            transaction.add(R.id.breaking_news, TextFragment.newInstance("TEXT", 1));
            transaction.add(R.id.main_container, TextFragment.newInstance("TEXT", 2));


            transaction.commit();

            return view;
        }

    }

    public static class TextFragment extends SherlockFragment {

        private static final String ARG_INDEX = "TextFragment.index";
        private static final String ARG_TEXT = "TextFragment.text";

        public static TextFragment newInstance(String text, int index) {
            TextFragment fragment = new TextFragment();
            Bundle args = new Bundle();
            args.putString(ARG_TEXT, text);
            args.putInt(ARG_INDEX, index);
            fragment.setArguments(args);
            return fragment;
        }

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,   Bundle savedInstanceState) {
            TextView textView = new TextView(getActivity());
            textView.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
            textView.setText(getArguments().getString(ARG_TEXT) + " " + getArguments().getInt(ARG_INDEX));
            return textView;
        }

    }

}

Основной макет с виджером

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <FrameLayout
        android:id="@+id/player"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true" />

    <android.support.v4.view.ViewPager
        android:id="@+id/viewPager"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_above="@id/player"
        android:layout_alignParentTop="true" >
    </android.support.v4.view.ViewPager>

</RelativeLayout>

Фрагмент макета

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/root_container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <FrameLayout
        android:id="@+id/live_radio"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <FrameLayout
        android:id="@+id/breaking_news"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <FrameLayout
        android:id="@+id/main_container"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1" />

</LinearLayout>
...