我正在开发一个寻宝游戏应用程序,该应用程序显示要在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();
}
}
答案 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);
}