私が与えることができる最小の数setOffscreenPageLimit(int)
が 1 であることは理解していますが、メモリの問題のため、一度に 1 ページずつロードする必要があります。
古いスタイルのタブホストなどを使用する必要がありますか? または、viewPagerに一度に1ページずつロードさせる方法/ハックはありますか?
私のアダプターは、BaseAdapter を ViewHolder パターンで拡張します。
私が与えることができる最小の数setOffscreenPageLimit(int)
が 1 であることは理解していますが、メモリの問題のため、一度に 1 ページずつロードする必要があります。
古いスタイルのタブホストなどを使用する必要がありますか? または、viewPagerに一度に1ページずつロードさせる方法/ハックはありますか?
私のアダプターは、BaseAdapter を ViewHolder パターンで拡張します。
私は同じ問題を抱えていましたが、その解決策を見つけました:
手順:
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
私の知る限り、 ViewPager を使用する場合は不可能です。少なくとも、ページをスワイプ可能にしたい場合はそうではありません。
したがって、説明は非常に簡単です。
2 つのページ間をスワイプする場合、両方のページを表示する必要があるポイントがあります。これは、2 つのページのうちの 1 つがその時点で存在しない場合でも、2 つのページ間をスワイプできないためです。
詳細については、この質問を参照してください: ViewPager.setOffscreenPageLimit(0) does not work as expected
CommonsWareは、彼の回答のコメントで適切な説明を提供しました。
しかし、メモリの問題のため、一度に 1 ページずつロードする必要があります。
それはあなたが得ていることを前提としていますOutOfMemoryError
。
古いスタイルのタブホストなどを使用する必要がありますか?
はい、またはFragmentTabHost
、またはアクション バーのタブ。
または、viewPagerに一度に1ページずつロードさせる方法/ハックはありますか?
ViewPager
いいえ、スライド アニメーションに一度に複数のページが必要なという単純な理由からです。ViewPager
これは、とスワイプを使用して表示できます。
または、知覚された記憶の問題の修正に取り組むこともできます。このアプリが、本日報告したものと同じであると仮定すると、7MB のヒープ スペースしか使用していません。OutOfMemoryError
残りのヒープが非常に断片化されている場合にのみ、結果はs になります。このような断片化の問題に対処するのに役立つメモリ管理の戦略 (たとえば、外部ソースからビットマップを作成するためのinBitmap
on ) があります。BitmapOptions
私のアダプターは、BaseAdapter を ViewHolder パターンで拡張します。
BaseAdapter
で使用するためのものでAdapterView
はありませんViewPager
。
このメソッドを使用すると、ビュー ページャーを使用してタブ レイアウトで一度に 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);
}
}
`
まず、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;
}
}
これが古い投稿であることは知っていますが、この問題に出くわし、断片を読み込んでいる場合に適切な修正を見つけました。単純に、setUserVisibleHint() をオーバーライドして、ユーザーがフラグメントを表示しているかどうかを確認します。その後、データをロードします。
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if (isVisibleToUser) {
getData(1, getBaseUrl(), getLink());
}
}