2

私は非常に単純な PagerAdapter を持っています。何らかの理由で、位置 2 にスクロールすると位置 0 と 1 のビューが削除されます。

具体的には、最初にアプリを実行すると、3 つのビューが表示されます。位置 2 までスクロールすると、位置 1 のビューが消えます。ビュー 0 はまだあります。ビュー 0 にスクロールしてビュー 2 に戻り、再びビュー 0 に戻ると、ビュー 0 が突然消えます。もう一度同じことをすると、実際にビュー 0 がインスタンス化され、すぐに破棄されることがわかります。

ここで何が起こっているのですか?

主な活動

public class MainActivity extends Activity {

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        final MyPagerAdapter adapter = new MyPagerAdapter(this);
        final ViewPager myPager = (ViewPager) findViewById(R.id.mypanelpager);
        myPager.setAdapter(adapter);
        myPager.setCurrentItem(1);
}


public class MyPagerAdapter extends PagerAdapter {

private Context ctx;
Calendar c = Calendar.getInstance();
int month = c.get(Calendar.MONTH);
int year = c.get(Calendar.YEAR);
ViewGroup collection;

public MyPagerAdapter (Context ctx){
    this.ctx = ctx ;
}


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

public Object instantiateItem(ViewGroup container, int position ){
    this.collection = (ViewPager)container;
    NewMonth monthObject = new NewMonth(ctx, month+position-1,2012);
    View monthLayout = monthObject.newParentLayout;
    collection.addView(monthLayout);
    return monthLayout;
    return addViewAt(position);
    }


@Override
    public void destroyItem(ViewGroup container, int position, Object object) {
    collection.removeViewAt(position);
}


 @Override
     public Parcelable saveState() {
     return null;
     }


@Override
public boolean isViewFromObject(View view, Object arg1) {
    return view==arg1;
}
}
4

3 に答える 3

4

OffscreenPageLimit を N-1 に指定して、メモリ内のすべてのタブを維持する必要があります。この場合、これを onCreate メソッド内に配置します。

myPager.setOffscreenPageLimit(2);
于 2013-03-02T17:09:54.400 に答える
1

ソースからのチェックアウトpopulate()機能ViewPager- currentIndex+1 および currentIndex-1 アイテムを削除するための明確なチェックがあります。削除はビューのサイズに基づいて行われ、完全に内部の ViewPager ロジックのようです。ViewPager ソースが配置されています

<android sdk folder>\extras\android\support\v4\src\java\android\support\v4\view\ViewPager.jav‌​a

.

それが正確に起こっていることを知るためにデバッグするかもしれませんがViewPager、ViewPager で深刻な問題に直面するまではお勧めしません。理由: ViewPager コードを掘り下げると、パブリック インターフェイスやドキュメントではなく、内部構造に基づいて (意図的でなくても) ハック コードを作成する可能性があります。そのため、データのカプセル化の主なアイデアが台無しになることは間違いなく良くありません (悲しいことに、Android では、ドキュメントの不足/不明確な命名/Android 内部の問題などにより、そうする必要がある場合があります。詳細については、Steve McConnellによる Code Complete を確認してください)。良好なカプセル化などの詳細)。

于 2012-09-22T02:28:31.780 に答える
0

ここで重要なのは、位置がインデックスとは異なることです。彼らがあなたにポジションを与えたとしても、あなたのコレクションが他のポジションを削除していないという保証はありません.

例: 位置 2 にあるとします。destroyItem が位置 0 に対して呼び出された可能性があります。これは、コレクションの位置 2 が実際にはインデックス 1 であることを意味します。したがって、インデックスは位置からすぐに同期しなくなります。リストビューの子でも同じことが起こります。代わりに sparseArray を使用することをお勧めします。

private final SparseArray<View> views = new SparseArray<>();

public View instantiateItem(ViewGroup container, final int position) {
    ...
    views.put(position, view);
    ...
}

public void destroyItem(ViewGroup container, int position, Object object) {
     View view = views.get(position);
     if (view != null) {
         container.removeView(view);
         views.remove(position);
     }
}
于 2014-04-29T15:09:38.233 に答える