将 ListFragment 替换为 ViewPager 中的 Fragment 与选项卡
Posted
技术标签:
【中文标题】将 ListFragment 替换为 ViewPager 中的 Fragment 与选项卡【英文标题】:Replace ListFragment with Fragment inside ViewPager with Tabs 【发布时间】: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,我不知道该怎么做)。 此外,开始一个新的活动会隐藏标签栏。
有人可以帮帮我吗?
【问题讨论】:
【参考方案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 的视图来放置子片段 - MyListFragment
或 DetailsFragment
。
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_
android:layout_>
<FrameLayout
android:id="@+id/container"
android:layout_
android:layout_/>
</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_
android:layout_/>
【讨论】:
布局包装器看起来像这样吗?我得到 onCreateView 的 InflateException。wrapper.xml
的示例。如果您对此有任何问题,请告诉我
getChildFragmentManager().popBackStack()
。在显示DetailsFragment
时注意.addToBackStack(null)
行。它基本上说“将此事务保存为历史操作 - 可以通过按下硬件返回按钮将其移回”。 popBackStack()
有点模拟硬件后退按钮的点击。将backStack
管理视为类似于 html5 History API 可能更容易理解。
首先感谢这一点,它解决了我过去几天一直遇到的问题,其次是关于我发现从 getChildFragmentManager() 更改为启用 support.app 的常规 FragmentManager() 的问题后退按钮无需从任何地方手动调用即可工作,使用 childmanager 没有,不确定这会产生什么副作用,但它的所有行为都是我想要的:D
@Kevin,抱歉,错过了您的评论。原因可能是 onCreateOptionsMenu()
仅在***片段 - 包装器上调用。解决方案可能是从那里创建菜单 - 例如通过手动调用listFragment#onCreateOptionsMenu()
。这是从头顶开始的,你需要试试这个以上是关于将 ListFragment 替换为 ViewPager 中的 Fragment 与选项卡的主要内容,如果未能解决你的问题,请参考以下文章
如何设置 ListFragment 自定义布局的 Divider(为 null)
如何在 DialogFragment 中显示现有的 ListFragment