1

ギャラリーを実装しようとしています。

ギャラリー ウィジェットは非推奨になっているため、それを実装してページング スクロール効果を持たせるために、フラグメント (android 互換性 v4) を使用しています。

スクロールして戻るまで、すべて問題ないように見えます...次の理由により、APPが強制的に閉じられました。

java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.

スクロールして前の写真を表示すると、ImageView が再取得されるようです。

そして、私はこの問題を解決する方法がわかりません...

ここに私のxmlとコードがあります

[XML]

<android.support.v4.view.ViewPager android:id="@+id/pager" android:layout_below="@id/head" android:layout_width="wrap_content" android:layout_height="350dp" android:layout_marginTop="35dp" />

[コード]

public class PhotoView extends FragmentActivity
{
  private Button btnBack=null;
  private ClickHandler click=null;
  private ViewPager pager=null;
  private ArrayList<ImageView> imgList=new ArrayList<ImageView>();

  @Override
  public void onCreate(Bundle savedInstanceState)
  {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.photo_show);
    initUI();
    handler.sendEmptyMessage(0);
  }

  private void initUI()
  {
    btnBack=(Button)findViewById(R.id.btnBack);
    btnBack.setOnClickListener(click);
    pager=(ViewPager)findViewById(R.id.pager);
  }

  private Handler handler=new Handler()
  {
    public void handleMessage(Message msg)
    {
      loadPhotos();
    }
  };

  private void loadPhotos()
  {
    for(int i=0; i<Constants.PHOTO_LIST.size(); i++)
    {
      ImageView img=new ImageView(this);
      img.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
      imgList.add(img);
      new ImageDL(Constants.PHOTO_LIST.get(i).getFileId(), Params.IMAGE_SIZE_PARAM_ORIGINAL).execute(img); // async D/L photo
    }
    pager.setAdapter(new PhotoAdapter(getSupportFragmentManager()));
  }

  @Override
  public void onBackPressed()
  {
    super.onBackPressed();
    btnBack.performClick();
    return;
  }

  @Override
  protected void onStop()
  {
    super.onStop();
    for(int i=0; i<imgList.size(); i++) //Do recycle when activity stopped, but I'm not yet sure this code is right...
    {
      Drawable drawable=imgList.get(i).getDrawable();
      if(drawable instanceof BitmapDrawable)
      {
        BitmapDrawable bitmapDrawable=(BitmapDrawable) drawable;
        Bitmap bitmap=bitmapDrawable.getBitmap();
        bitmap.recycle();
      }
    }
    imgList.clear();
    imgList=null;
  }

  private class ClickHandler implements OnClickListener
  {
    public void onClick(View v)
    {
      if(v==btnBack)
      {
        finish();
        overridePendingTransition(R.anim.lr1, R.anim.lr2);
        System.gc();
      }
    }
  }

  private class PhotoAdapter extends FragmentPagerAdapter
  {
    public PhotoAdapter(FragmentManager mgr)
    {super(mgr);}

    @Override
    public int getCount()
    {
      return(imgList.size());
    }

    @Override
    public Fragment getItem(int position)
    {
      return(new PhotoFragment(position));
    }
  }

  private class PhotoFragment extends Fragment 
  {
    private int index=-1;

    private PhotoFragment(int index)
    {this.index=index;}

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) 
    {
      return imgList.get(index);
    }
  }
}

コードで Fragment API を使用したのはこれが初めてで、実行したコード ロジックが正しいかどうかわかりません...

この問題を解決するのに役立つアイデアや、Android 2.3 ~ 4.x でギャラリー (ページング スクロールを使用) を実装するための別のより良い方法はありますか?

4

1 に答える 1

0

imgList をキャッシュとして使用しないでください。

onCreateView() の実装に関する問題は、次のとおりです。ページ0で、ViewPagerはimageViewをページ0に追加し、imageViewをそのレイアウト(親ビュー)に追加します(私は思う)。. ページ 0 に戻ると、ViewPager は onCreateView() を再度呼び出すため、既に追加されている imageView をそのレイアウトに再度追加しようとするとエラーが発生します。

java.lang.IllegalStateException: 指定された子にはすでに親があります。

そのため、loadPhotos() メソッド内で imgList を使用しないでください。代わりに、代わりに onCreateView() 内で imageView を初期化します。

変更されたコード:

 private void loadPhotos()
  {

    pager.setAdapter(new PhotoAdapter(getSupportFragmentManager()));
  }


public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) 
    {
      ImageView img=new ImageView(this);
      img.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));

      new ImageDL(Constants.PHOTO_LIST.get(i).getFileId(),  Params.IMAGE_SIZE_PARAM_ORIGINAL).execute(img); // async D/L photo


      return img;
}
于 2013-07-15T04:20:21.057 に答える