android - 如何创建包含 fragment 的 Android 选项卡式对话框?

标签 android android-fragments android-dialogfragment fragment-tab-host android-nested-fragment

谁能给我举个例子或告诉我如何在 Android 中创建一个简单的 Tabbed Dialog,其中每个选项卡的内容都是 Fragments?我找到的所有示例/教程都是关于 Fragments 和 Tabs 的,但没有特定于 DialogFragments 的内容。

FragmentTabHost 的文档显示了如何使用 getChildFragmentManager() 在普通 fragment 中创建选项卡。我假设当 fragment 是 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)
...

这是我设置 View 的代码(然后传递给 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);
}

最佳答案

花了很多时间让它工作,但没有运气。我找到的唯一解决方案是创建虚拟 fragment tabhost 并将 viewpager 与 fragment 而不是 tabhost fragment 一起使用

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>

Dialog 类,诀窍是使用 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);
                }
            });

        }

    }

}

这是结果,现在您可以按 Tab 键或滑动 fragment

enter image description here

关于android - 如何创建包含 fragment 的 Android 选项卡式对话框?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16634519/

相关文章:

android - Android 的 PDF 库?

java - 在使用空 while 循环初始化 fragment 之前等待抽屉导航关闭

android - 如何使用嵌套 fragment (Android 4.2)在 ViewPager 中添加 fragment

android - 显示 DialogFragments 会使 ICS 崩溃

java - Android:更改背景颜色显示对话框

android - 从 dialogfragment 发布新数据后更新 Listview

java - 加载json数据并将其绑定(bind)到自定义布局

安卓:adb.exe pull/mnt/sdcard/somefile.txt 不工作?

java - 从扩展 RTP 数据包头解码 unix 时间戳以计算延迟

android - 有没有办法预览在 IntelliJ IDEA 12 的另一个 View 中使用的 fragment ?