我有一个包含片段的FragmentActivity。 这个片段包含一个FragmentTabHost。 选项卡主机包含三个选项卡,每个选项卡都是一个ListFragment。
列表配置了自定义适配器,可从主FragmentActivity获取更新,并在更新时调用notifyDatasetChanged。
我的问题是,ListFragment UI似乎永远不会在显示时更新视图。 如果我更改标签 - 我可以看到列表更新,但是当屏幕上显示列表时,我无法实时看到更新。
这是包含FragmentTabHost的片段的定义:
public class SubOptionFragmentManager extends Fragment
{
FragmentTabHost mTabHost;
SoiListFragment mFrag1;
SoiListFragment mFrag2;
SoiListFragment mFrag3;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
return inflater.inflate(R.layout.soi_container, container, false);
}
public void init(FragmentManager fm, int optionInstanceID)
{
mOptionInstanceID = optionInstanceID;
// find and setup the tabhost
mTabHost = (FragmentTabHost)getActivity().findViewById(android.R.id.tabhost);
mTabHost.setup(getActivity(), getChildFragmentManager(), R.id.realtabcontent);
// add the three tabs
mTabHost.addTab(mTabHost.newTabSpec("1")
.setIndicator("1"),
SoiListFragment.class,
getTabBundle("1", optionInstanceID));
mTabHost.addTab(mTabHost.newTabSpec(dsTag)
.setIndicator("2"),
SoiListFragment.class,
getTabBundle("2", optionInstanceID));
mTabHost.addTab(mTabHost.newTabSpec("3")
.setIndicator("3"),
SoiListFragment.class,
getTabBundle("3", optionInstanceID));
// get reference to the fragments added
mFrag1 = (SoiListFragment)getChildFragmentManager().findFragmentByTag("1");
mFrag2 = (SoiListFragment)getChildFragmentManager().findFragmentByTag("2");
mFrag3 = (SoiListFragment)getChildFragmentManager().findFragmentByTag("3");
}
public void HandleSoiItemUpdate(SubOptionInstanceItem soi, int fragID)
{
Log.i(TAG, "ItemUpdate:" + soi.toString());
updateItemRunnable ur = new updateItemRunnable(soi, int fragID);
getActivity().runOnUiThread(ur);
}
class updateItemRunnable implements Runnable
{
SubOptionInstanceItem mItem;
int mFragID;
public updateItemRunnable (SubOptionInstanceItem item, int fragID)
{
mItem = item;
}
public void run()
{
switch (mFragID)
{
// the second parameter - true means it calls notifyDatasetChanged() after updating the item
case 1:
mFrag1.getAdapter().updateItem(mItem, true);
break;
case 2:
mFrag2.getAdapter().updateItem(mItem, true);
break;
case 3:
mFrag3.getAdapter().updateItem(mItem, true);
break;
}
}
}
}
该类中还包含ListFragment对象:
public static class SoiListFragment extends ListFragment
{
private int mOptionInstanceID;
private int mPageType;
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
mOptionInstanceID = getArguments().getInt(FIELD_OPTION_INSTANCE_ID);
mPageType = getArguments().getInt(FIELD_PAGE_TYPE);
}
public SubOptionInstanceAdapter getAdapter()
{
return (SubOptionInstanceAdapter)getListAdapter();
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
// inflate the list view and return it
View v = inflater.inflate(R.layout.soi_list, container, false);
init();
return v;
}
public void init()
{
SubOptionInstanceAdapter mAdapter = null;
switch(mPageType)
{
case 1:
mAdapter = new SubOptionInstanceAdapter(getActivity(),
R.layout.soi_item,
Globals.getList1());
break;
case 2:
mAdapter = new SubOptionInstanceAdapter(getActivity(),
R.layout.soi_item,
Globals.getList2());
break;
case 3:
mAdapter = new SubOptionInstanceAdapter(getActivity(), R.layout.soi_item, Globals.getList3());
break;
}
setListAdapter(mAdapter);
}
片段布局“soi_container.xml”(包含FragmentTabHost的简单布局):
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="@color/background" >
<android.support.v4.app.FragmentTabHost
android:id="@android:id/tabhost"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="@android:id/tabcontent"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="0" />
</android.support.v4.app.FragmentTabHost>
<FrameLayout
android:id="@+id/realtabcontent"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
</LinearLayout>
答案 0 :(得分:0)
我的第一个问题是init()
部分的onCreateView
展示位置。
这导致每次加载或更改选项卡时都会发生init()
- 这就是为什么我认为只有在不可见时才更新选项卡。
此外,在容器中的init()
上获取ListFragments引用是错误的,因为在该点上尚未创建片段。
最后我的解决方案是在OnStart
事件期间在容器片段上创建选项卡,获取列表片段引用并在onTabCreated
事件中使用适配器初始化它们,然后使用我得到的引用更新它们之前。
编辑: Ravi的代码示例 - 获取列表片段参考
public void onTabCreated(int pageType)
{
// if I don't already have the reference for the fragment
if (mFrag1 == null)
{
mFrag1 = (SoiListFragment)getFragmentManager().findFragmentByTag("1");
}
}