【问题标题】:Replace ListFragment with Fragment inside ViewPager with Tabs将 ListFragment 替换为 ViewPager 中的 Fragment 与选项卡
【发布时间】:2013-02-25 15:08:24
【问题描述】:

我尝试在我的应用中设置以下导航:

实际情况:ViewPager + Tabs 在列表之间滑动:

  • ListFragment A
  • ListFragment B

所需条件: ViewPager + 选项卡:

  • ListFragment A onListItemSelected 将 ListFragment A 替换为 DetailFragment A
  • ListFragment B onListItemSelected 将 ListFragment B 替换为 DetailFragment B

目标是在选项卡导航中显示详细信息片段。我不能用 detailFragment 替换 fragmentList(fragmentList 没有自定义布局,因此没有 ID,我不知道该怎么做)。 此外,开始一个新的活动会隐藏标签栏。

有人可以帮帮我吗?

【问题讨论】:

    标签: android tabs android-viewpager fragment android-listfragment


    【解决方案1】:

    我会制作一个包装片段,它知道要显示什么 - 列表或详细信息。这将与ViewPager 完全分离——寻呼机只知道它包含包装片段,而这些片段将自己管理它们的内容。

    实施将遵循以下原则:

    public class WrapperFragment extends Fragment {
    
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
    
            MyListFragment list = new MyListFragment();
            list.setListAdapter(adapter);
            list.setOnItemClickListener(new OnItemClickListener() {
                @Override public void onItemClick(AdapterView<?> l, View v, int position, long id) {
                  // Create details fragment based on clicked item's position
                  Fragment details = new Fragment();
                  getChildFragmentManager()
                      .beginTransaction()
                      .replace(R.id.container, details)
                      .addToBackStack(null)
                      .commit();
                }
            });
    
            getChildFragmentManager()
                .beginTransaction()
                .add(R.id.container, list)
                .commit();
        }
    
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
            // There has to be a view with id `container` inside `wrapper.xml`
            return inflater.inflate(R.layout.wrapper, container, false);
        }
    
        public class MyListFragment extends ListFragment {
    
            private OnItemClickListener listener;
    
            public void setOnItemClickListener(OnItemClickListener l) {
                this.listener = l;
            }
    
            @Override
            public void onListItemClick(ListView l, View v, int position, long id) {
                if(listener != null) {
                  listener.onItemClick(l, v, position, id);
                }
            }
        }
    }
    

    wrapper.xml。想法是 WrapperFragment 必须提供一个布局,其中包含一个 id 为 container 的视图 - 因为我们正在使用具有此 id 的视图来放置子片段 - MyListFragmentDetailsFragment

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

    另一种方式。这应该可行,但你必须尝试一下(布局本身有id,而不是有一个ID为container的孩子):

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

    【讨论】:

    • 布局包装器看起来像这样吗?我得到 onCreateView 的 InflateException。 schemas.android.com/apk/res/android" android:id="@+id/container" android:name="PATH_TO_WrapperFragment" ... >
    • 添加了wrapper.xml 的示例。如果您对此有任何问题,请告诉我
    • getChildFragmentManager().popBackStack()。在显示DetailsFragment 时注意.addToBackStack(null) 行。它基本上说“将此事务保存为历史操作 - 可以通过按下硬件返回按钮将其移回”。 popBackStack() 有点模拟硬件后退按钮的点击。将backStack 管理视为类似于 HTML5 History API 可能更容易理解。
    • 首先感谢这一点,它解决了我过去几天一直遇到的问题,其次是关于我发现从 getChildFragmentManager() 更改为启用 support.app 的常规 FragmentManager() 的问题后退按钮无需从任何地方手动调用即可工作,使用 childmanager 没有,不确定这会产生什么副作用,但它的所有行为都是我想要的:D
    • @Kevin,抱歉,错过了您的评论。原因可能是 onCreateOptionsMenu() 仅在顶级片段 - 包装器上调用。解决方案可能是从那里创建菜单 - 例如通过手动调用listFragment#onCreateOptionsMenu()。这是从头顶开始的,你需要试试这个
    猜你喜欢
    • 1970-01-01
    • 2014-07-07
    • 1970-01-01
    • 2012-04-16
    • 2011-12-05
    • 1970-01-01
    • 1970-01-01
    • 2017-04-07
    • 1970-01-01
    相关资源
    最近更新 更多