40

私が与えることができる最小の数setOffscreenPageLimit(int)が 1 であることは理解していますが、メモリの問題のため、一度に 1 ページずつロードする必要があります。

古いスタイルのタブホストなどを使用する必要がありますか? または、viewPagerに一度に1ページずつロードさせる方法/ハックはありますか?

私のアダプターは、BaseAdapter を ViewHolder パターンで拡張します。

4

9 に答える 9

42

私は同じ問題を抱えていましたが、その解決策を見つけました:

手順:

1)まず、このリンク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"/>

これで、一度に 1 ページだけが読み込まれます。

PS:質問の要件に従って、のソリューションを投稿しましたViewpager。私はまだ同じことを試していTabLayoutません。そのための解決策が見つかった場合は、回答を更新します。

このファイルでは、KeyEventCompat が使用されていますが、KeyEnentCompat クラスは API レベル 26.0.0 で廃止されたため、Android Studio では見つからない可能性があります 。 SDK/support_api_diff/26.0.0-alpha1/changes/android.support.v4.view.KeyEventCompat

于 2017-06-07T06:24:43.420 に答える
18

私の知る限り、 ViewPager を使用する場合は不可能です。少なくとも、ページをスワイプ可能にしたい場合はそうではありません。

したがって、説明は非常に簡単です。

2 つのページ間をスワイプする場合、両方のページを表示する必要があるポイントがあります。これは、2 つのページのうちの 1 つがその時点で存在しない場合でも、2 つのページ間をスワイプできないためです。

詳細については、この質問を参照してください: ViewPager.setOffscreenPageLimit(0) does not work as expected

CommonsWareは、彼の回答のコメントで適切な説明を提供しました。

于 2013-09-30T14:40:03.370 に答える
12

しかし、メモリの問題のため、一度に 1 ページずつロードする必要があります。

それはあなたが得ていることを前提としていますOutOfMemoryError

古いスタイルのタブホストなどを使用する必要がありますか?

はい、またはFragmentTabHost、またはアクション バーのタブ。

または、viewPagerに一度に1ページずつロードさせる方法/ハックはありますか?

ViewPagerいいえ、スライド アニメーションに一度に複数のページが必要なという単純な理由からです。ViewPagerこれは、とスワイプを使用して表示できます。

または、知覚された記憶の問題の修正に取り組むこともできます。このアプリが、本日報告したものと同じであると仮定すると、7MB のヒープ スペースしか使用していません。OutOfMemoryError残りのヒープが非常に断片化されている場合にのみ、結果はs になります。このような断片化の問題に対処するのに役立つメモリ管理の戦略 (たとえば、外部ソースからビットマップを作成するためのinBitmapon ) があります。BitmapOptions

私のアダプターは、BaseAdapter を ViewHolder パターンで拡張します。

BaseAdapterで使用するためのものでAdapterViewはありませんViewPager

于 2013-09-30T14:39:47.030 に答える
3

このメソッドを使用すると、ビュー ページャーを使用してタブ レイアウトで一度に 1 ページを読み込むことができます`

  @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);

        }
    }

`

于 2018-10-31T06:36:02.660 に答える
1

まず、ViewPager 内の登録済みフラグメントのインテリジェントなキャッシュを提供する SmartFragmentStatePagerAdapter.java をコピーします。これは、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;
        }

    }
于 2019-09-03T06:55:41.133 に答える
-2

これが古い投稿であることは知っていますが、この問題に出くわし、断片を読み込んでいる場合に適切な修正を見つけました。単純に、setUserVisibleHint() をオーバーライドして、ユーザーがフラグメントを表示しているかどうかを確認します。その後、データをロードします。

    @Override
public void setUserVisibleHint(boolean isVisibleToUser) {
    super.setUserVisibleHint(isVisibleToUser);
    if (isVisibleToUser) {
        getData(1, getBaseUrl(), getLink());
    }
}
于 2016-11-03T19:24:56.843 に答える