【问题标题】:PagerAdapter class getting called multiple timesPagerAdapter 类被多次调用
【发布时间】:2013-02-15 10:46:21
【问题描述】:

我正在开发一个包含 ViewPager 视图的应用程序, 我已经创建了一个 PagerAdapter,它具有视图,PagerAdapter 的 instantiateItem() 方法在 create() 中被调用了两次,我不知道为什么,谁能帮我解决这个问题?

这是我的代码,

         View PagerView;
        MyPagerAdapter adapter;
        ViewPager pager;

            adapter = new MyPagerAdapter();     
    pager.setAdapter(adapter);
    pager.setCurrentItem(0);

public class MyPagerAdapter extends PagerAdapter {

        @Override
        public Object instantiateItem(final View collection, final int position) {
            Log.d("Inside", "Pager");
            PagerView = new View(collection.getContext());
            LayoutInflater inflater = (LayoutInflater) collection.getContext()
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            PagerView = inflater.inflate(R.layout.tablemenu, null, false);
            tbMenuDetails = (TableLayout) PagerView
                    .findViewById(R.id.Menutable1);
            scrollview = (ScrollView) PagerView.findViewById(R.id.scrollView1);
            tbMenuDetails.removeAllViews();
            removeTableRows();
            createTableLayout(position);
            String str[][] = datasource.GetSubMenuDetailsFromMenuId(MenuIdlst
                    .get(position).trim());
            Log.d("Str", "" + str.length);
            for (int i = 0; i < str.length; i++) {
                addRows(str[i][1], str[i][2], str[i][0], str[i][3], position);
                Log.d("Message", "Pos   " + position + "    SubMenuName" + str[i][2]
                        + " SubMenuId" + " " + str[i][0] + " TypeID" + "    "
                        + str[i][3]);
            }

            // View view = inflater.inflate(resId, null);
            ((ViewPager) collection).addView(PagerView, 0);

            return PagerView;
        }

        @Override
        public void destroyItem(final View arg0, final int arg1,
                final Object arg2) {
            ((ViewPager) arg0).removeView((View) arg2);

        }

        @Override
        public boolean isViewFromObject(final View arg0, final Object arg1) {
            return arg0 == ((View) arg1);

        }

        @Override
        public void finishUpdate(View arg0) {
            // TODO Auto-generated method stub

        }

        @Override
        public void restoreState(Parcelable arg0, ClassLoader arg1) {
            // TODO Auto-generated method stub

        }

        @Override
        public Parcelable saveState() {
            // TODO Auto-generated method stub
            return null;
        }

        @Override
        public void startUpdate(View arg0) {
            // TODO Auto-generated method stub

        }

        @Override
        public int getCount() {
            // TODO Auto-generated method stub
            return MenuIdlst.size();
        }

    }

请帮忙

【问题讨论】:

  • 没人能帮我吗??
  • 你是如何用片段实例化寻呼机的?粘贴该代码。 (onCreate() 代码)
  • 适配器 = new MyPagerAdapter(); pager.setAdapter(适配器); pager.setCurrentItem(0); pager.setOffscreenPageLimit(0);
  • 你在寻呼机中使用片段吗?
  • 已完成,但仍然调用了两次

标签: android android-viewpager android-pageradapter


【解决方案1】:

如果您决定使用 Fragments,请不要实现 PagerAdapter。相反,扩展FragmentPagerAdapterFragmentStatePagerAdapter

private class MyPagerAdapter extends FragmentStatePagerAdapter {
    public MyPagerAdapter(FragmentManager fm) {
        super(fm);
    }

    @Override
    public int getCount() {
        return NUMBER_OF_PAGES_IN_PAGER;
    }

    @Override
    public Fragment getItem(int position) {
        // Implement the static method newInstance in MyFragment.java yourself.
        // It should return you a brand new instance of MyFragment, basically using
        // the code you had in your original instantiateItem method.
        return MyFragment.newInstance(position, ... etc ...); 
    }
}

然后在您的活动中:

myPagerAdapter = new MyPagerAdapter(getFragmentManager());
// or myPagerAdapter = new MyPagerAdapter(getSupportFragmentManager());
myViewPager.setAdapter(myPagerAdapter);

要获取有关如何使用 Fragments 和 ViewPagers 的更多信息: https://developer.android.com/reference/android/app/Fragment.html https://developer.android.com/reference/android/support/v4/view/ViewPager.html https://developer.android.com/reference/android/support/v4/app/FragmentStatePagerAdapter.html

【讨论】:

  • -Streets Of Boston 我应该在哪里初始化 ViewPager 中的视图?
  • getItem(int pos) 返回您要在页面“pos”上显示的 Fragment。片段(MyFragment)是片段的子类。您在这个子类的 onCreateView 实现中创建视图:developer.android.com/reference/android/app/…, android.view.ViewGroup, android.os.Bundle)
  • 我使用了相同的结果并给出了相同的结果.. 在预加载时调用了两次
  • @StreetsOfBoston 谢谢,我也有同样的问题。您可以查看此代码吗?请paste.debian.net/786168
  • 我在使用 ViewPager2 时遇到了类似的问题,发现 viewPager.setOffscreenPageLimit(1);导致了这个问题。在官方文档中它说:“值表示应该使用 RecyclerView 的默认缓存机制,而不是显式地预取和保留页面到当前页面的任一侧。”对于公共静态最终 int OFFSCREEN_PAGE_LIMIT_DEFAULT = 0;我依赖 recyclerview 默认缓存机制,而不是显式设置 viewpager 的离屏页面限制。
【解决方案2】:

默认情况下,ViewPager 在当前页面之前/之前预加载一页(如果有)。您没有说它是针对相同的职位还是不同的职位。

【讨论】:

【解决方案3】:

ViewPager.setOffscreenpageLimit(int) 的最小值为 1。您可以从 source code for ViewPager 中看到这一点:

private static final int DEFAULT_OFFSCREEN_PAGES = 1;

...

/**
     * Set the number of pages that should be retained to either side of the
     * current page in the view hierarchy in an idle state. Pages beyond this
     * limit will be recreated from the adapter when needed.
     *
     * <p>This is offered as an optimization. If you know in advance the number
     * of pages you will need to support or have lazy-loading mechanisms in place
     * on your pages, tweaking this setting can have benefits in perceived smoothness
     * of paging animations and interaction. If you have a small number of pages (3-4)
     * that you can keep active all at once, less time will be spent in layout for
     * newly created view subtrees as the user pages back and forth.</p>
     *
     * <p>You should keep this limit low, especially if your pages have complex layouts.
     * This setting defaults to 1.</p>
     *
     * @param limit How many pages will be kept offscreen in an idle state.
     */
    public void setOffscreenPageLimit(int limit) {
        if (limit < DEFAULT_OFFSCREEN_PAGES) {
            Log.w(TAG, "Requested offscreen page limit " + limit + " too small; defaulting to " +
                    DEFAULT_OFFSCREEN_PAGES);
            limit = DEFAULT_OFFSCREEN_PAGES;
        }
        if (limit != mOffscreenPageLimit) {
            mOffscreenPageLimit = limit;
            populate();
        }
    }

如果您尝试将其设置为零,您应该会在 Logcat 中看到警告。

下限为 1 是有充分理由的。当您滚动寻呼机时,相邻页面需要已经加载 - 否则您将看不到下一页的任何内容。如果您设法将屏幕外页面限制强制为零,那么当您从第一页滚动到第二页时,您可能只会看到一个黑色的空白页面。如果您在开始时创建的第一页和第二页都存在特定问题,请尝试定位并修复它。

【讨论】:

  • 有道理...很好。
【解决方案4】:

为分页器中的每个视图使用片段。

FragmentActivityonCreate()方法中编写以下代码。

List<Fragment> fragments = new Vector<Fragment>();

//for each fragment you want to add to the pager
Bundle page = new Bundle();
page.putString("url", url);
fragments.add(Fragment.instantiate(this,MyFragment.class.getName(),page));

//after adding all the fragments write the below lines

this.mPagerAdapter  = new PagerAdapter(super.getSupportFragmentManager(), fragments);

mPager.setAdapter(this.mPagerAdapter);

一个示例片段定义:

public class MyFragment extends Fragment {


public static MyFragment newInstance(String imageUrl) {

final MyFragment mf = new MyFragment ();

    final Bundle args = new Bundle();
    args.putString("somedata", "somedata");
    mf.setArguments(args);

    return mf;
}

public MyFragment() {}

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    String data = getArguments().getString("somedata");
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    // Inflate and locate the main ImageView
    final View v = inflater.inflate(R.layout.my_fragment_view, container, false);
    //... 
    return v;
}

每当我需要使用ViewPager 时,我都会遵循此方法。希望这可以帮助。根据您提供的信息,我无法弄清楚为什么您的实例化方法被调用了两次。

【讨论】:

  • 不,我不知道如何实现这是我的应用程序,你能建议我修改我的代码吗
【解决方案5】:

对 isViewFromObject() 方法进行必要的更改。这非常重要,在它的文档中说"This method is required for a PagerAdapter to function properly."

@Override
public boolean isViewFromObject(View view, Object object) {
    if(object != null){
        return ((Fragment)object).getView() == view;
    }else{
        return false;
    }
}

你可以看here

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-12-27
    • 1970-01-01
    • 2020-06-08
    • 2010-10-24
    • 2011-10-18
    • 2020-10-19
    • 2020-08-06
    • 1970-01-01
    相关资源
    最近更新 更多