使用ViewPager滑动选项卡

时间:2015-04-15 22:52:48

标签: android android-cursorloader android-pageradapter pagerslidingtabstrip

我想要实现带有滑动标签的Google Play商店式菜单。我密切实现了这个tutorial,但是在我的实现中,我通过CursorLoader启动异步数据加载,我在PagerAdapter内部类的instantiateItem方法中初始化。

问题是PagerAdapter调用instantiateItem两次(因此实例化对应于两个选项卡的视图),这会启动异步进程两次,每次用户单击另一个选项卡时,它会再次启动异步加载两次,创造一个巨大的无法控制的混乱。如何才能使PagerAdapter调用instantiateItem一次?

谢谢。

编辑:这是我的PagerAdapter sublcass的代码,实现了教程:

class SamplePagerAdapter extends PagerAdapter {

    /**
     * @return the number of pages to display
     */
    @Override
    public int getCount() {
        return 5;
    }

    /**
     * @return true if the value returned from {@link #instantiateItem(ViewGroup, int)} is the
     * same object as the {@link View} added to the {@link ViewPager}.
     */
    @Override
    public boolean isViewFromObject(View view, Object o) {
        return o == view;
    }

    // BEGIN_INCLUDE (pageradapter_getpagetitle)
    /**
     * Return the title of the item at {@code position}. This is important as what this method
     * returns is what is displayed in the {@link SlidingTabLayout}.
     * <p>
     * Here we construct one using the position value, but for real application the title should
     * refer to the item's contents.
     */
    @Override
    public CharSequence getPageTitle(int position) {
        CharSequence title = "default";
        switch (position) {
            case 0:
                title = "Happiness";
            break;

            case 1:
                title = "Intelligence";
            break;

            case 2:
                title = "Memory";
            break;

            case 3:
                title = "Personality";
            break;

            case 4:
                title = "Success & Failure";
            break;
        }

    return title;
    }
    // END_INCLUDE (pageradapter_getpagetitle)

    /**
     * Instantiate the {@link android.view.View} which should be displayed at {@code position}. Here we
     * inflate a layout from the apps resources and then change the text view to signify the position.
     */
    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        // Inflate a new layout from our resources
        ListView view = (ListView) getActivity().getLayoutInflater().inflate(R.layout.article_list,
                container, false);
        // Add the newly created View to the ViewPager
        container.addView(view);

        switch (position) {
            case 0:
                Intent intent1 = new Intent(getActivity(), ArticleService.class);
                intent1.putExtra(ArticleService.CATEGORY_EXTRA, 1);
                getActivity().startService(intent1);

                getLoaderManager().initLoader(ARTICLE_LOADER, null, KnowledgeFragment.this);
                mArticleAdapter = new ArticleAdapter(getActivity(), null, 0);
                view.setAdapter(mArticleAdapter);

                Log.v("PagerAdapter", "Adapter Set");

                Log.v("PagerAdapter", "View added");

                break;
            case 1:
                Intent intent2 = new Intent(getActivity(), ArticleService.class);
                intent2.putExtra(ArticleService.CATEGORY_EXTRA, 2);
                getActivity().startService(intent2);

                getLoaderManager().initLoader(ARTICLE_LOADER, null, KnowledgeFragment.this);
                mArticleAdapter = new ArticleAdapter(getActivity(), null, 0);
                view.setAdapter(mArticleAdapter);
                break;
            case 2:
                Intent intent3 = new Intent(getActivity(), ArticleService.class);
                intent3.putExtra(ArticleService.CATEGORY_EXTRA, 3);
                getActivity().startService(intent3);

                getLoaderManager().initLoader(ARTICLE_LOADER, null, KnowledgeFragment.this);
                mArticleAdapter = new ArticleAdapter(getActivity(), null, 0);
                view.setAdapter(mArticleAdapter);
                break;
            case 3:
                Intent intent4 = new Intent(getActivity(), ArticleService.class);
                intent4.putExtra(ArticleService.CATEGORY_EXTRA, 4);
                getActivity().startService(intent4);

                getLoaderManager().initLoader(ARTICLE_LOADER, null, KnowledgeFragment.this);
                mArticleAdapter = new ArticleAdapter(getActivity(), null, 0);
                view.setAdapter(mArticleAdapter);
                break;
            case 4:
                Intent intent5 = new Intent(getActivity(), ArticleService.class);
                intent5.putExtra(ArticleService.CATEGORY_EXTRA, 5);
                getActivity().startService(intent5);

                getLoaderManager().initLoader(ARTICLE_LOADER, null, KnowledgeFragment.this);
                mArticleAdapter = new ArticleAdapter(getActivity(), null, 0);
                view.setAdapter(mArticleAdapter);
                break;
        }

        // Return the View
        return view;
    }

    /**
     * Destroy the item from the {@link ViewPager}. In our case this is simply removing the
     * {@link View}.
     */
    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        container.removeView((View) object);
        Log.i(LOG_TAG, "destroyItem() [position: " + position + "]");
    }

}

我知道PagerAdapter的默认行为是调用方法两次以优化内存使用和平滑滚动。从本质上讲,我会问是否有办法改变它。

1 个答案:

答案 0 :(得分:0)

我使用getItem而不是instantiateItem,见下文:

@Override
public Fragment getItem(int position) {
    return MyFrag.newInstance(position);
}

编辑:

getItem()在android.support.v4.app.FragmentPagerAdapter中,应与Fragments一起使用

然后你的片段可以单独处理加载。