【问题标题】:Fragment views in TabLayout not yet created on activity createTabLayout 中的片段视图尚未在活动创建时创建
【发布时间】:2015-07-14 19:45:56
【问题描述】:

我在我的许多应用程序中不断遇到一个反复出现的问题,并且一直在使用各种变通方法来“解决”它,但这次我遇到了它,我想找出一个真正的解决方案。

我正在尝试构建一个带有两个选项卡的选项卡式布局,其中每个选项卡显示一些应从 Internet 获取的数据。获取数据后,将其缓存在设备上,以便下次打开应用时立即恢复(然后在后台刷新)。

为此,我尝试加载缓存的数据并将其显示在第一个选项卡的 RecyclerView 中,并且我想在活动创建时执行此操作。在我这样做之前,我显然设置了所有选项卡布局的东西,以便正确加载选项卡。问题是它们不是,组成标签页的片段似乎还没有它们的视图,因此我无法访问它们上的 RecyclerView。

这是我的活动代码:

public class MainActivity extends NetworkBusActivity
{
    // Views
    ViewPager tabPager;
    TabLayout tabLayout;

    // Tab pager adapter
    private ViewPagerAdapter adapter;

    // Fragment one and two
    private MenuFragment menuFragment;
    private OrderFragment orderFragment;

    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Create the views
        tabPager = (ViewPager) findViewById(R.id.tabPager);
        tabLayout = (TabLayout) findViewById(R.id.tabLayout);

        // Setup the tab layouts
        this.setupTabs();

        // Show cached data
        this.setCachedItems();

        // Start loading new data in background
        this.startLoading();
    }

    private void setupTabs()
    {       
        // Create Fragments
        menuFragment = new MenuFragment();
        orderFragment = new OrderFragment();

        // Setup adapter
        adapter = new ViewPagerAdapter(getSupportFragmentManager());
        adapter.addFragment(menuFragment, getString(R.string.title_menu));
        adapter.addFragment(orderFragment, getString(R.string.title_orders));
        tabPager.setAdapter(adapter);

        // Setup the tab layout
        tabLayout.setupWithViewPager(tabPager);
        tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);

        tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener()
        {
            // not shown
        });
    }    

    private void setCachedItems()
    {
        // Show cached data
        ArrayList<Item> items = Cache.menu.getItems();

        menuFragment.setItems(items);
    }

    private void startLoading()
    {
        // Start loading in background (not shown)
    }
}

应该很简单:创建视图、创建片段、设置选项卡布局,然后加载缓存数据。

MenuFragment 扩展了一个基类ItemListFragment,它定义了setItems 方法:

public class MenuFragment extends ItemListFragment
{
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
    {
        View view = inflater.inflate(R.layout.tab_menu, container, false);
        return view;
    }

    @Override
    protected ItemListAdapter getAdapter(ArrayList<Item> items, boolean categorize)
    {
        return new MenuListAdapter(this, R.layout.row_item, items, categorize);
    }
}

public abstract class ItemListFragment extends Fragment
{
    private RecyclerView recycler;

    @Override
    public void onViewCreated(View view, Bundle savedInstanceState)
    {
        super.onViewCreated(view, savedInstanceState);

        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity());
        recycler = (RecyclerView) view;
        recycler.setLayoutManager(linearLayoutManager);
        recycler.addItemDecoration(new DividerItemDecoration(getActivity(), DividerItemDecoration.VERTICAL_LIST));
    }

    public void setItems(ArrayList<Item> items)
    {
        recycler.setAdapter(getAdapter(items, true));
    }

    protected abstract ItemListAdapter getAdapter(ArrayList<Item> items, boolean categorize);
}

再直白点:在onCreateView创建view,然后在onViewCreated获取RecyclerView,最后用adapter设置item。

问题很简单:MainActivity 中的方法setCachedItems 被调用之前在片段中调用onCreateViewonViewCreated 方法。因此,RecyclerView 为空,我无法设置它的适配器。即使我在调用该方法之前创建了 Fragments 的新实例并将它们添加到功能 TabLayout。

在创建视图之前似乎有一些延迟,但我需要在创建活动时设置项目。

我哪里出错了,我该如何解决?

【问题讨论】:

    标签: android android-fragments tabs android-tablayout


    【解决方案1】:

    在片段的 onViewCreated 中执行此操作

    ((MainActivity)getActivity).setCachedData().....

    而不是在创建活动时

    【讨论】:

    • 看看这是我使用的解决方法之一。我有点不喜欢它,它创建了对我不想要的活动的依赖,而且它看起来就像一个 hack。一定有一些我不理解的潜在事物,我正在寻求理解它,以便我可以将其应用于更多类似的场景。不过谢谢你的建议!
    • 但是你的做法是错误的,你甚至在没有创建回收器时就尝试使用它。
    • 你可以在activity中覆盖onResumedFragment()并设置缓存数据
    猜你喜欢
    • 2016-09-07
    • 2013-12-21
    • 1970-01-01
    • 2011-07-31
    • 1970-01-01
    • 1970-01-01
    • 2014-04-13
    • 1970-01-01
    • 2014-10-04
    相关资源
    最近更新 更多