当我尝试在recyclerview上显示从相机拍摄的图像时,图像出现多行

时间:2019-07-07 02:44:38

标签: java android firebase android-recyclerview

我正在开发一个寻宝游戏应用程序,该应用程序显示要在recyclerview中拍照的物品列表。该列表是从Firebase加载的。有一个onClickListener,以便单击列表中的一个项目时,它会打开相机,然后拍照,我想在所选项目旁边显示图像。现在,当我拍摄照片时,它会在recyclerview中多行显示。例如,如果我选择列表中的第0个项目并拍照,则图片将同时显示在列表中的第0个项目和第11个项目上。我正在尝试使其仅显示在所选项目上。

添加图像后,我尝试使用adapter.notifyDataSetChanged()和adapter.notifyItemChanged(tmpPosition),但它们都在多行上显示图像。我知道列表中只有一项得到更新。我现在的操作方式是创建一个名为tmpPosition的全局int变量。当您单击列表中的项目时,我将tmpPosition设置为等于所选择项目的索引。然后在onActivityResult中,使用以下命令设置图像:

scavengerHuntItemsList.get(tmpPosition).setScavengerHuntImage(imageTaken);
adapter.notifyDataSetChanged();

来自我的MainActivity 这是打开相机的onClickListener

     ((ScavengerHuntRecyclerAdapter) dapter).setOnItemClickListener(new 
     ScavengerHuntRecyclerAdapter.ClickListener() {
                @Override
                public void onItemClick(int position, View v) {
                    //Here I am saving the position of the item so later I can update the correct index in the list
                    tmpPosition = position;

                    dispatchTakePictureIntent();

                }
            });
            scavengerHuntMainRecyclerView.setAdapter(adapter);
        }

我来自MainActivity的相机东西

private void dispatchTakePictureIntent() {
    Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

    if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
        File photoFile = null;
        photoFile = createPhotoFile();
        if (photoFile != null) {
            pathToFile = photoFile.getAbsolutePath(); //gets the path to the image
            Uri photoURI = FileProvider.getUriForFile(ScavengerHuntMainActivity.this, "com.example.test", photoFile);
            takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
            startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
        }
    }
}

private File createPhotoFile() {
    String name = new SimpleDateFormat(Constants.PHOTO_DATE_NAME_FORMAT).format(new Date());
    File storageDir = getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);  //the directory where we will be storing the pic
    File image = null;

    try {
        image = File.createTempFile(name, ".jpg", storageDir);
    } catch (IOException e) {
        e.printStackTrace();
    }
    return image;
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {

        Bitmap imageTaken = BitmapFactory.decodeFile(pathToFile);
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        imageTaken.compress(Bitmap.CompressFormat.JPEG, Constants.IMAGE_THUMBNAIL_QUALITY, bos);

        if (tmpPosition > -1) {
            scavengerHuntItemsList.get(tmpPosition).setScavengerHuntImage(imageTaken);
            adapter.notifyDataSetChanged();
            tmpPosition = -1;
        }

    }
}

下面是我的recyclerview适配器 我在onBindViewHolder中设置图片

public class ScavengerHuntRecyclerAdapter extends RecyclerView.Adapter<ScavengerHuntRecyclerAdapter.ScavengerHuntViewHolder> {

private ArrayList<ScavengerHuntItem> scavengerHuntArrayList;
private static ClickListener clickListener;


private RecyclerView.AdapterDataObserver dataObserver = new RecyclerView.AdapterDataObserver() {
    @Override
    public void onChanged() {
        super.onChanged();
    }

    @Override
    public void onItemRangeChanged(int positionStart, int itemCount) {
        super.onItemRangeChanged(positionStart, itemCount);
    }

    @Override
    public void onItemRangeChanged(int positionStart, int itemCount, @Nullable Object payload) {
        super.onItemRangeChanged(positionStart, itemCount, payload);
    }

    @Override
    public void onItemRangeInserted(int positionStart, int itemCount) {
        super.onItemRangeInserted(positionStart, itemCount);
    }

    @Override
    public void onItemRangeRemoved(int positionStart, int itemCount) {
        super.onItemRangeRemoved(positionStart, itemCount);
    }

    @Override
    public void onItemRangeMoved(int fromPosition, int toPosition, int itemCount) {
        super.onItemRangeMoved(fromPosition, toPosition, itemCount);
    }
};

public static class ScavengerHuntViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {

    public TextView scavengerHuntLayoutTextView;
    public ImageView scavengerHuntLayoutImageView;

    public ScavengerHuntViewHolder(@NonNull View itemView) {
        super(itemView);

        itemView.setOnClickListener(this);
        scavengerHuntLayoutTextView = itemView.findViewById(R.id.scavengerHuntLayoutTextView);
        scavengerHuntLayoutImageView = itemView.findViewById(R.id.scavengerHuntLayoutImageView);

    }

    @Override
    public void onClick(View v) {
        clickListener.onItemClick(getAdapterPosition(), v);
    }
}

public void setOnItemClickListener(ClickListener clickListener) {
    ScavengerHuntRecyclerAdapter.clickListener = clickListener;
}

public interface ClickListener {
    void onItemClick(int position, View v);
}

public ScavengerHuntRecyclerAdapter(ArrayList<ScavengerHuntItem> scavengerHuntArrayList) {
    this.scavengerHuntArrayList = scavengerHuntArrayList;
}

@NonNull
@Override
public ScavengerHuntViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
    View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.scavenger_hunt_list_layout, viewGroup, false);
    ScavengerHuntViewHolder scavengerHuntViewHolder = new ScavengerHuntViewHolder(view);
    return scavengerHuntViewHolder;
}

@Override
public void onBindViewHolder(@NonNull ScavengerHuntViewHolder scavengerHuntViewHolder, int i) {
    ScavengerHuntItem currentItem = scavengerHuntArrayList.get(i);
    scavengerHuntViewHolder.scavengerHuntLayoutTextView.setText(currentItem.getDescription());

    if (currentItem.getScavengerHuntImage() != null) {
        scavengerHuntViewHolder.scavengerHuntLayoutImageView.setImageBitmap(currentItem.getScavengerHuntImage());
        Log.d("in adapter UPDATED POS", "position  =  " + i);
    }
}



@Override
public int getItemCount() {
    return scavengerHuntArrayList.size();
}

}

1 个答案:

答案 0 :(得分:0)

发生这种情况是因为RecyclerView重用了它的视图(项目/单元格)。因此,单元格1中的内容将在单元格11中重新使用,从而使照片出现多次。

这可以通过清除ImageView内容来解决。

if (currentItem.getScavengerHuntImage() != null) {
        scavengerHuntViewHolder.scavengerHuntLayoutImageView.setImageBitmap(currentItem.getScavengerHuntImage());
        Log.d("in adapter UPDATED POS", "position  =  " + i);
    } else {
scavengerHuntViewHolder.scavengerHuntLayoutImageView.setImageResource(android.R.color.transparent);
//or
//scavengerHuntViewHolder.scavengerHuntLayoutImageView.setImageBitmap(null);
}