Как создать диалоговое окно с вкладками Android с фрагментами?

Может ли кто-нибудь указать мне пример или показать мне, как создать простой Tabbed Dialog в Android, где содержимое каждой вкладки Fragments? Все примеры/учебники, которые я нашел, касаются фрагментов и вкладок, но ничего особенного для DialogFragments.

Документация для FragmentTabHost показывает, как создавать вкладки в нормальных фрагментах с помощью getChildFragmentManager(). Я предполагаю, что это также должно работать, когда фрагмент является DialogFragment, но когда я его попробую, я получаю:

java.lang.IllegalStateException: Fragment does not have a view at android.support.v4.app.Fragment$1.findViewById(Fragment.java:1425)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:901)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1088)
...

Здесь мой код для настройки представления (который затем передается на AlertDialog.setView()):

private void setupView(View v) {
    mTabHost = (FragmentTabHost) v.findViewById(android.R.id.tabhost);

   mTabHost.setup(getActivity(), getChildFragmentManager(), R.id.realtabcontent);

   mTabHost.addTab(mTabHost.newTabSpec("tab1").setIndicator("Tab1"),
            MyDialogFragment.class, null);
}

Ответ 1

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

voters_dialog.xml

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

        <android.support.v4.app.FragmentTabHost
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:id="@+id/tabs"
                >
        </android.support.v4.app.FragmentTabHost>

        <android.support.v4.view.ViewPager
                android:id="@+id/pager"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:gravity="center"/>

</LinearLayout>

Диалоговый класс, трюк - использование onCreateView не onCreateDialog

public class VotersDialog extends DialogFragment {


    private FragmentTabHost mTabHost;
    private ViewPager viewPager;
    private VotersPagerAdapter adapter;


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.voters_dialog, container);

        getDialog().setTitle(getArguments().getString("title"));

        mTabHost = (FragmentTabHost) view.findViewById(R.id.tabs);

        mTabHost.setup(getActivity(), getChildFragmentManager());
        mTabHost.addTab(mTabHost.newTabSpec("tab1").setIndicator("Плюсов"), Fragment.class, null);
        mTabHost.addTab(mTabHost.newTabSpec("tab2").setIndicator("Минусов"), Fragment.class, null);


        adapter = new VotersPagerAdapter(getChildFragmentManager(), getArguments());
        adapter.setTitles(new String[]{"Плюсов", "Минусов"});

        viewPager = (ViewPager)view.findViewById(R.id.pager);
        viewPager.setAdapter(adapter);

        viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int i, float v, int i2) {
            }

            @Override
            public void onPageSelected(int i) {
                mTabHost.setCurrentTab(i);
            }

            @Override
            public void onPageScrollStateChanged(int i) {

            }
        });

        mTabHost.setOnTabChangedListener(new TabHost.OnTabChangeListener() {
            @Override
            public void onTabChanged(String s) {
                int i = mTabHost.getCurrentTab();
                viewPager.setCurrentItem(i);
            }
        });

        return view;
    }


    public class VotersPagerAdapter extends FragmentPagerAdapter {

        Bundle bundle;
        String [] titles;

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

        public VotersPagerAdapter(FragmentManager fm, Bundle bundle) {
            super(fm);
            this.bundle = bundle;
        }

        @Override
        public Fragment getItem(int num) {
            Fragment fragment = new VotersListFragment();
            Bundle args = new Bundle();
            args.putSerializable("voters",bundle.getSerializable( num == 0 ? "pros" : "cons"));
            fragment.setArguments(args);
            return fragment;
        }

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

        @Override
        public CharSequence getPageTitle(int position) {
            return titles[position];
        }

        public void setTitles(String[] titles) {
            this.titles = titles;
        }
    }

    public static class VotersListFragment extends ListFragment {

        List<String> voters;

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
            View view = inflater.inflate(R.layout.list_fragment, container, false);
            return view;
        }

        @Override
        public void onActivityCreated(Bundle savedInstanceState) {

            super.onActivityCreated(savedInstanceState);
            voters = (ArrayList) getArguments().getSerializable("voters");

            ArrayAdapter<String> adapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, voters);
            setListAdapter(adapter);

            getListView().setOnItemClickListener(new AdapterView.OnItemClickListener() {
                @Override
                public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
                    Intent intent = new Intent(getActivity(), ProfileActivity_.class);
                    String login = voters.get(i);
                    intent.putExtra("login", Utils.encodeString(login.substring(0, login.indexOf("(")).trim()));
                    startActivity(intent);
                }
            });

        }

    }

}

Вот результат, теперь вы можете нажимать вкладки или прокручивать фрагменты

enter image description here

Ответ 2

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

вы можете проверить полный исходный код здесь

Ответ 3

Вы должны использовать DialogFragment, TabLayout и ViewPager. Например, ваше представление фрагмента диалога может выглядеть так:

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

    <android.support.design.widget.TabLayout
        android:id="@+id/tabLayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <android.support.v4.view.ViewPager
        android:id="@+id/masterViewPager"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</LinearLayout>

Создайте свой адаптер и убедитесь, что вы переопределили метод getPageTitleMethod, например:

public class CustomAdapter extends FragmentPagerAdapter {  
   List<Fragment> mFragmentCollection = new ArrayList<>();  
   List<String> mTitleCollection = new ArrayList<>();  
   public CustomAdapter(FragmentManager fm) {  
     super(fm);  
   }  
   public void addFragment(String title, Fragment fragment)  
   {  
     mTitleCollection.add(title);  
     mFragmentCollection.add(fragment);  
   }  
   //Needed for  
   @Override  
   public CharSequence getPageTitle(int position) {  
     return mTitleCollection.get(position);  
   }  
   @Override  
   public Fragment getItem(int position) {  
     return mFragmentCollection.get(position);  
   }  
   @Override  
   public int getCount() {  
     return mFragmentCollection.size();  
   }  
 }

В OnCreateView вашего диалога вы должны настроить свой viewpager с помощью tabLayout:

 public View onCreateView(LayoutInflater inflater,  ViewGroup container,  Bundle savedInstanceState) {  
     View rootview = inflater.inflate(R.layout.dialog_sample,container,false);  
     tabLayout = (TabLayout) rootview.findViewById(R.id.tabLayout);  
     viewPager = (ViewPager) rootview.findViewById(R.id.masterViewPager);  
     CustomAdapter adapter = new CustomAdapter(getChildFragmentManager());  
     adapter.addFragment("Boy",CustomFragment.createInstance("John"));  
     adapter.addFragment("Girl",CustomFragment.createInstance("Stacy"));  
     adapter.addFragment("Robot",CustomFragment.createInstance("Aeon"));  
     viewPager.setAdapter(adapter);  
     tabLayout.setupWithViewPager(viewPager);  
     return rootview;  
   } 

У меня есть запись в блоге, написанная здесь: здесь.

Ответ 4

Попробуйте использовать DialogFragment вместо этого, а в вашем диалоговом окне диафрагмы включите LinearLayout для фрагментации.

FragmentTransaction t = getSupportFragmentManager().beginTransaction();  
String Tag = fragment.getClass().getSimpleName(); 
t.replace(R.id.llTabFragmentContainer, fragment, Tag); 
t.commit(); 

фрагмент - ваш фрагмент вкладки. cheeers