0

I have a FragmentActivity that contains a Fragment. this fragment contains a FragmentTabHost. The tab host contains three tabs that each one is a ListFragment.

The lists are configured with custom adapter that getting updates from the main FragmentActivity, and calling notifyDatasetChanged on update.

My problem is that it seems the ListFragment UI never updates the view when it's shown. If I change tabs - I can see the list updates, but I can't see the updates on real time when a list is shown on the screen.

That's the definition of the Fragment containing the 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;
            }
        }
    }
}

Also included in that class is the ListFragment object:

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);
        }

The fragment layout "soi_container.xml" (simple layout containing 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>
4

1 回答 1

0

我的第一个问题是零件的init()位置onCreateView。这导致init()每次加载或更改选项卡时都会发生 - 这就是为什么我认为选项卡仅在不可见时才会更新。

此外,在容器中获取 ListFragments 引用init()是错误的,因为此时尚未创建片段。

最后我的解决方案是在事件期间在容器片段上创建选项卡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");
    }
}
于 2013-10-21T14:25:14.327 回答