android 如何使我的ViewPager一次只加载一个页面即setOffscreenPageLimit(0);

sbdsn5lh  于 2023-05-12  发布在  Android
关注(0)|答案(9)|浏览(286)

我知道我能给予setOffscreenPageLimit(int)的最小值是1。但我需要一次加载一页,因为内存问题。
我是不是要用老式的tabhost等等?或者有没有办法让我的viewPager一次加载一个页面?
My Adapter使用ViewHolder模式扩展了BaseAdapter。

jslywgbw

jslywgbw1#

我遇到了同样的问题,我找到了解决方案:
步骤:
**1)**首先从this链接下载CustomViewPager类。
**2)**使用如下所述的类:
Java中:

CustomViewPager mViewPager;
mViewPager = (CustomViewPager) findViewById(R.id.swipePager);
mViewPager.setOffscreenPageLimit(0);

XML格式:

<com.yourpackagename.CustomViewPager 
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/swipePager"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>

现在一次只能加载一个页面。
P.S:根据问题的要求,我已经发布了Viewpager的解决方案。我还没有在TabLayout上做过同样的尝试。如果我能找到任何解决方案,我会更新答案。

在此文件中,使用了KeyEventCompat,但Android studio可能找不到它,因为KeyEnentCompat类在API级别26.0.0中已被弃用,因此您需要将KeyEventCompat替换为event。有关更多详细信息,请查看https://developer.android.com/sdk/support_api_diff/26.0.0-alpha1/changes/android.support.v4.view.KeyEventCompat

piztneat

piztneat2#

据我所知,这是不可能当使用ViewPager。至少当你想让你的页面可以滑动的时候是不需要的。
因此,解释非常简单:
当你在两个页面之间滑动时,有一个点,当两个页面都需要可见时,因为当其中一个甚至不存在时,你无法在两个东西之间滑动
请参阅此问题了解更多信息:ViewPager.setOffscreenPageLimit(0) doesn't work as expected
CommonsWare在他的answer的评论中提供了很好的解释。

jrcvhitl

jrcvhitl3#

但我需要一次加载一页,因为内存问题。
这假定您正在获取OutOfMemoryError s。
我是不是要用老式的tabhost等等?
是,或FragmentTabHost,或操作栏选项卡。
或者有没有办法让我的viewPager一次加载一个页面?
不可以,原因很简单,ViewPager每次需要多个页面来进行滑动动画。你可以通过使用ViewPager和滑动来看到这一点。
或者,你可以努力解决你感知到的记忆问题。假设这个应用程序是同一个that you reported on earlier today,您只使用了7MB的堆空间。如果剩余的堆是高度碎片化的,那么只会产生OutOfMemoryError s。有一些内存管理策略(例如,inBitmapBitmapOptions用于从外部源创建位图)可以帮助解决这种碎片问题。
My Adapter使用ViewHolder模式扩展了BaseAdapter。
BaseAdapter用于AdapterView,而不是ViewPager

kpbpu008

kpbpu0084#

我有答案。上面提到的setUserVisibleHint()方法已被弃用,您可以使用setMaxLifecycle()方法。如果只加载可见片段,则必须在viewpager适配器中将行为设置为BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT。在建筑师。在片段中使用onResume()方法来处理片段。
通过这种方式,在视图页导航中一次只能加载一个片段。

public static class MyAdapter extends FragmentStatePagerAdapter {
public MyAdapter(FragmentManager fm) {
    super(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT);
}

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

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

}
在Kotlin中:

class MyAdapter(fm: FragmentManager) : FragmentStatePagerAdapter(fm,BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT )

也可以以同样的方式与FragmentPagerAdapter(现已弃用)一起使用

puruo6ea

puruo6ea5#

通过使用此方法,您可以使用视图分页器在选项卡布局中一次加载一个页面`

@Override
    public void onResume() {
        super.onResume();
        if (getUserVisibleHint() && !isVisible) {
            Log.e("~~onResume: ", "::onLatestResume");
           //your code
        }
        isVisible = true;
    }

    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);

        if (isVisibleToUser && isVisible) {
            Handler handler = new Handler();
            handler.postDelayed(new Runnable() {
                @Override
                public void run() {
                   //your code
                }
            }, 500);

        }
    }

wyyhbhjk

wyyhbhjk6#

覆盖setUserVisibleHint并在every片段中添加postDelayed,如下所示。

override fun setUserVisibleHint(isVisibleToUser: Boolean) {
    if (isVisibleToUser)
        Handler().postDelayed({
            if (activity != null) {
                // Do you stuff here 
            }
        }, 200)
    super.setUserVisibleHint(isVisibleToUser)
}

我可以用这种方式管理,它现在对我来说很好。

zbsbpyhn

zbsbpyhn7#

首先,复制到SmartFragmentStatePagerAdapter.java,它提供了ViewPager中注册片段的智能缓存。它通过覆盖instantiateItem()方法并在内部缓存任何创建的片段来实现。这解决了需要在ViewPager中访问当前项目的常见问题。
现在,我们想要在声明适配器时从上面复制的SmartFragmentStatePagerAdapter进行扩展,以便我们可以利用状态分页器的更好的内存管理:

public abstract class SmartFragmentStatePagerAdapter extends FragmentStatePagerAdapter {
    // Sparse array to keep track of registered fragments in memory
    private SparseArray<Fragment> registeredFragments = new SparseArray<Fragment>();

    public SmartFragmentStatePagerAdapter(FragmentManager fragmentManager) {
        super(fragmentManager);
    }

    // Register the fragment when the item is instantiated
    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        Fragment fragment = (Fragment) super.instantiateItem(container, position);
        registeredFragments.put(position, fragment);
        return fragment;
    }

    // Unregister when the item is inactive
    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        registeredFragments.remove(position);
        super.destroyItem(container, position, object);
    }

    // Returns the fragment for the position (if instantiated)
    public Fragment getRegisteredFragment(int position) {
        return registeredFragments.get(position);
    }
}

// Extend from SmartFragmentStatePagerAdapter now instead for more dynamic ViewPager items
    public static class MyPagerAdapter extends SmartFragmentStatePagerAdapter {
    private static int NUM_ITEMS = 3;

        public MyPagerAdapter(FragmentManager fragmentManager) {
            super(fragmentManager);
        }

        // Returns total number of pages
        @Override
        public int getCount() {
            return NUM_ITEMS;
        }

        // Returns the fragment to display for that page
        @Override
        public Fragment getItem(int position) {
            switch (position) {
            case 0: // Fragment # 0 - This will show FirstFragment
                return FirstFragment.newInstance(0, "Page # 1");
            case 1: // Fragment # 0 - This will show FirstFragment different title
                return FirstFragment.newInstance(1, "Page # 2");
            case 2: // Fragment # 1 - This will show SecondFragment
                return SecondFragment.newInstance(2, "Page # 3");
            default:
                return null;
            }
        }

        // Returns the page title for the top indicator
        @Override
        public CharSequence getPageTitle(int position) {
            return "Page " + position;
        }

    }
v2g6jxz6

v2g6jxz68#

实际上,您不需要自定义ViewPager。
我也遇到了同样的问题,我就这样做了。

  • 保持setOffscreenPageLimit()为1。
  • 使用片段的onResumeonPause生命周期方法。

初始化并释放这些生命周期方法的内存。

flvlnr44

flvlnr449#

我知道这是一个老帖子,但我偶然发现了这个问题,并找到了一个很好的修复方法,如果你的加载片段。简单地说,通过覆盖setUserVisibleHint()来检查用户是否看到了片段。然后加载数据。

@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
    super.setUserVisibleHint(isVisibleToUser);
    if (isVisibleToUser) {
        getData(1, getBaseUrl(), getLink());
    }
}

相关问题