5

Görüntüleyici'de zaten IllegalStateException eklenmiş Resimler görüntülemek için viewpager kullanıyorum. Temel olarak üç parçaya ihtiyacım var: önizleme için önceki resim, geçerli ekran görüntüsü ve önizleme için sonraki resim. Sadece bir önceki ve bir sonraki resmin önizlemesini görüntülemek istiyorum, kullanıcı aslında ona kaydırdığında tam görüntüye dönüşecektir. Bu yüzden bunu başarmak için sadece 3 parçayı kullanmayı düşünüyorum. Kod aşağıdaki gibidir: Fragman

private class ImagePagerAdapter extends FragmentStatePagerAdapter implements ViewPager.OnPageChangeListener { 
    private ImageFragment mImageFragment; 
    private ImagePreviewFragment mPreviousPreviewFragment; 
    private ImagePreviewFragment mNextPreviewFragment; 

    public ImagePagerAdapter(FragmentManager fm, ImageFragment image, ImagePreviewFragment previous, ImagePreviewFragment next) { 
     super(fm); 
     mImageFragment = image; 
     mPreviousPreviewFragment = previous; 
     mNextPreviewFragment = next; 
    } 

    @Override 
    public Fragment getItem(int position) { 
     if (position == mPager.getCurrentItem()) { 
      mImageFragment.display(position); 
      return mImageFragment; 
     } 

     if (position < mPager.getCurrentItem()) { 
      mPreviousPreviewFragment.display(position - 1); 
      return mPreviousPreviewFragment; 
     } 
     mNextPreviewFragment.display(position + 1); 
     return mNextPreviewFragment; 
    } 


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

    @Override 
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { 
     Log.d(TAG, "onPageScrolled"); 
    } 

    @Override 
    public void onPageSelected(final int position) { 
     Log.d(TAG, "onPageSelected " + position); 
     new Handler().postDelayed(new Runnable() { 
      @Override 
      public void run() { 
       notifyDataSetChanged(); 
      } 
     }, 500); 
    } 


    @Override 
    public void onPageScrollStateChanged(int state) { 
     Log.d(TAG, "onPageScrollStateChanged " + state); 
    } 

    @Override 
    public int getItemPosition(Object item) { 
     return POSITION_NONE; 
     //return POSITION_UNCHANGED; 
    } 
} 

Yani temelde, G/önceki sonraki önizleme ve güncel görüntüyü ve GetItem için onları geri göndermek üzere üç parçaları oluşturulan önceden(). Kullanıcı yeni sayfaya kaydırıldığında parçayı güncellemek için üç konumun da yapılabilmesi için onpageselected() öğesinde de notifydatasetchange().

Ama sorun fragmanları ikinci kez eklendiğinde bu

Fragment already added IllegalStateException 

dışarı atmak olacaktır. Sanırım daha önce eklenmiş çünkü. Her seferinde yeni bir parça oluşturabilirim ama sanırım bu berbat. Öyleyse, zaten oluşturulan parçayı nasıl yeniden kullanabilirim ve sadece bunları güncelleyebilirim?

sayesinde Simon

cevap

2

FragmentStatePagerAdapter tasarım her sayfada (see Google's example) için yeni bir Fragment oluşturarak öneriyor. Ve ne yazık ki, Fragment'u bir FragmentManager'a eklendikten sonra (adaptörün içinde dolaylı olarak ne meydana geldiğini) okuyamazsınız. Bu nedenle resmi Google yolu yeni fragmanlar oluşturmak ve bunların adaptör tarafından imha edilmesine ve yeniden oluşturulmasına izin vermektir.

Ancak sayfaları yeniden kullanmak ve bir ViewHolder kalıbı örneği kullanmak istiyorsanız, parça yerine görünümlere bağlı kalmalısınız. Görünümler ebeveynlerinden çıkarılabilir ve fragmanların aksine yeniden kullanılabilir. PagerAdapter uzatın ve bunun gibi instantiateItem() uygulamak:

@Override 
public Object instantiateItem(ViewGroup container, final int position) { 
    //determine the view type by position 
    View view = viewPager.findViewWithTag("your_view_type"); 
    if (view == null) { 
     Context context = container.getContext(); 
     view = LayoutInflater.from(context).inflate(R.layout.page, null); 
     view.setTag("your_view_type"); 
    } else { 
     ViewGroup parent = (ViewGroup) item.getParent(); 
     if (parent != null) { 
      parent.removeView(item); 
     } 
    } 
    processYourView(position, view); 
    container.addView(view, MATCH); 
    return view; 
} 

Sen (görünümler 3 tip beri) konuma göre görünüm türünü belirlemek için bazı ekstra mantığı eklemek gerekir, bunu anlamaya düşünüyorum.