【问题标题】:List Fragment inside FragmentTabHost not updating when adapter changed适配器更改时,FragmentTabHost 中的列表片段未更新
【发布时间】:2013-09-16 12:01:03
【问题描述】:

我有一个包含 Fragment 的 FragmentActivity。 此片段包含一个 FragmentTabHost。 选项卡宿主包含三个选项卡,每个选项卡都是一个 ListFragment。

列表配置有自定义适配器,从主 FragmentActivity 获取更新,并在更新时调用 notifyDatasetChanged。

我的问题是 ListFragment UI 似乎在显示时从不更新视图。 如果我更改选项卡 - 我可以看到列表更新,但是当屏幕上显示列表时我无法实时看到更新。

这就是包含FragmentTabHost的Fragment的定义:

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>

【问题讨论】:

    标签: android android-fragments android-listfragment fragment-tab-host


    【解决方案1】:

    我的第一个问题是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");
        }
    }
    

    【讨论】:

    • 可以请您发布在 onTabCreated 下获得参考的代码,我有点卡在获取片段的参考
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多