将新数据添加到viewpager

时间:2016-09-20 04:43:18

标签: android android-viewpager

我创建了一个ViewPager,我在其中使用bitmapArray在viewpager中显示图像。每件事都运行正常但是当我添加新数据并调用notifydatasetchange时,应用程序崩溃了。

在这个应用程序中我正在下载歌曲并从该文件中我从该下载的歌曲中获取位图并添加位图数组。

它提供以下Execption:

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

我无法找到导致此操作的原因

ViewPager的适配器类是:

public class CoverFlowPagerAdapter extends PagerAdapter {

    ArrayList<Bitmap> mBitmapArray;
    Context c;

    interface CoverFlowClick {
        public void coverClick(int coverFlowPosition);
    }

    CoverFlowClick mCoverFlowClick;

    public CoverFlowPagerAdapter(Context c, ArrayList<Bitmap> mBitmapArray) {
        this.c = c;
        this.mBitmapArray = mBitmapArray;
        mCoverFlowClick = (CoverFlowClick) c;
    }

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

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

    @Override
    public Object instantiateItem(ViewGroup container, final int position) {

        ImageView imageView;
        View v = null;
        LayoutInflater inflater= (LayoutInflater) c.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        v=inflater.inflate(R.layout.coverflow_item,null);
        imageView= (ImageView) v.findViewById(R.id.coverFlowImage);

        imageView.setImageBitmap(mBitmapArray.get(position));

        container.addView(imageView);
        imageView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(c, "Clicked::--" + position, Toast.LENGTH_SHORT).show();
                mCoverFlowClick.coverClick(position);
            }
        });

        return imageView;
    }

    @Override
    public int getItemPosition(Object object) {
        return POSITION_NONE;
    }

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

我将位图添加到数组并调用notifydatasetchanged,如下所示:

@Override
    public void updateSongList(String songName) {

        getBitmapArray(songName);
        mCoverFlowAdapter.notifyDataSetChanged();

    }

编辑:我的自定义布局文件是

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <ImageView
        android:id="@+id/coverFlowImage"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
</LinearLayout>

我的getBitmapArray函数是

public void getBitmapArray(String songName) {

        Bitmap bitmap = null;
        path = Environment.getExternalStorageDirectory() + "/AppDownloads/" + songName;
        File file = new File(path);
        FileInputStream inputStream = null;

        try {
            inputStream = new FileInputStream(file.getAbsolutePath());
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }

        try {
            metaRetriver.setDataSource(inputStream.getFD());
        } catch (IOException e) {
            e.printStackTrace();
        }

        art = metaRetriver.getEmbeddedPicture();
        if (art != null) {
            bitmap = BitmapFactory
                    .decodeByteArray(art, 0, art.length);
        }

        if (bitmap != null) {
            mBitmapArray.add(bitmap);
        } else {
            Bitmap icon = BitmapFactory.decodeResource(getResources(), R.drawable.unknown_album);
            mBitmapArray.add(icon);
        }
    }

4 个答案:

答案 0 :(得分:1)

在自定义布局文件coverflow_item.xml中已包含ImageView

再次尝试使用

添加相同的容器
  

container.addView(ImageView的);

这就是它抛出异常的原因。

要克服它,您需要更改

container.addView(imageView);

container.addView(v);

这个也是

return imageView;

return v;

修改

也改变这个

container.removeView((ImageView) object); 

container.removeView((LinearLayout)object)

答案 1 :(得分:1)

不要将LinearLayout作为ImageView的父级,而是让ImageView成为布局的ROOT,如下所示: -

<ImageView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/coverFlowImage"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

在适配器中: -

@Override
public Object instantiateItem(ViewGroup container, final int position) {

    LayoutInflater inflater= (LayoutInflater) c.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    ImageView imageView = (ImageView) inflater.inflate(R.layout.coverflow_item, container, false);
    imageView.setImageBitmap(mBitmapArray.get(position));

    container.addView(imageView);
    imageView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Toast.makeText(c, "Clicked::--" + position, Toast.LENGTH_SHORT).show();
            mCoverFlowClick.coverClick(position);
        }
    });

    return imageView;
}

如果您想将LinearLayout用作ROOT,而不是将ImageView添加到容器,请添加膨胀的视图,并将其返回到 instantiateItem < / strong>方法。

同时将 destroyItem 方法更改为

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

答案 2 :(得分:0)

看这里:

   imageView.setImageBitmap(mBitmapArray.get(position));
    container.addView(imageView);

每次添加biotmap时,它都会将它添加到同一个容器中,如何容纳一个视图的容器可以添加其他视图,因此您需要删除旧视图:这样的事情

  @Override
public void updateSongList(String songName) {

    getBitmapArray(songName);
    container.removeView((ImageView) object)
    mCoverFlowAdapter.notifyDataSetChanged();

}

PS:插图代码请确保你传递正确的参数 让我知道它是否有帮助:)

答案 3 :(得分:0)

我最近实现了这个,这是我的instantiateItem方法(因为它的可读性有点小。

 @Override
  public Object instantiateItem(View collection, int position) {

     Evaluation evaluation = evaluations.get(position); 

     View layout = inflater.inflate(R.layout.layout_evaluation, null);

     TextView evaluationSummary = (TextView) layout.findViewById(R.id.evaluation_summary);

     evaluationSummary.setText(evaluation.getEvaluationSummary());

     ((ViewPager) collection).addView(layout);

   return layout;
}

 @Override
 public void destroyItem(View collection, int position, Object view) {
    ((ViewPager) collection).removeView((View) view);
}

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

因此,对于显示的页面,我使用位置作为索引从我的评估列表中获取数据。然后膨胀布局,其中包含我将添加数据的视图。然后我得到TextView来设置评估摘要文本。然后将整个布局添加到ViewPager。最后还返回了布局。

让我知道它是否有帮助:)