Android - 从阵列适配器位置问题替换图像
Android - Replace image from Array Adapter position issue
我正在尝试从自定义适配器中的网格视图中替换图像。当我单击“编辑图像视图”时,从相机拍摄新快照返回到我的 activity,发送回适配器并尝试在该特定位置进行替换。但它没有显示在我点击的那个位置。任何人都可以建议为什么每次调用 this.notifyDataSetChanged();
后该位置都可能改变
这是我的适配器代码:
public class VehicleImageAdapter extends ArrayAdapter<GridItem> {
private Context context;
private List<GridItem> gridItems = new ArrayList();
int layoutResourceId;
String[] imageNames = {"Front Right", "Right Doors", "Right Top", "Rear Right",
"Engine", "Interior FR", "Interior RR", "Trunk",
"Front", "Interior FL", "Interior RL4", "Rear",
"Front left", "Left Doors", "Left Top", "Rear Left"};
private GridItem gridItem;
private int position;
public VehicleImageAdapter(Context context, int grid_item_layout, ArrayList<GridItem> gridItems) {
super(context, grid_item_layout);
this.context = context;
this.layoutResourceId = grid_item_layout;
this.gridItems = gridItems;
}
public View getView(final int position, View convertView, ViewGroup parent) {
View row = convertView;
ViewHolder holder = null;
this.position = position;
if (row == null) {
LayoutInflater inflater = ((Activity) context).getLayoutInflater();
row = inflater.inflate(layoutResourceId, parent, false);
holder = new ViewHolder();
holder.vehicleImageNameTV = (TextView) row.findViewById(R.id.vehicleImageNameTV);
holder.vehicle_image = (ImageView) row.findViewById(R.id.vehicle_image);
holder.editVehicleImage = (ImageView) row.findViewById(R.id.editVehicleImage);
holder.grey = (ImageView) row.findViewById(R.id.grey);
holder.red = (ImageView) row.findViewById(R.id.red);
holder.green = (ImageView) row.findViewById(R.id.green);
row.setTag(holder);
} else {
holder = (ViewHolder) row.getTag();
}
if (position >= 16) {
holder.vehicleImageNameTV.setText(imageNames[15]);
} else {
holder.vehicleImageNameTV.setText(imageNames[position]);
}
Bitmap defaultImage = BitmapFactory.decodeResource(context.getResources(), R.mipmap.tap_to_snap);
holder.vehicle_image.setOnClickListener(new OnImageClickListener(position));
if (gridItems.size() > 0 && !gridItems.isEmpty()) {
gridItem = gridItems.get(position);
if (gridItem.getStatus().equalsIgnoreCase("server")) { //only in server not in local
Picasso.with(context).load(gridItem.getServerImagePath()).resize(200, 150).placeholder(R.drawable.ic_loading_image).error(R.drawable.ic_error_image).into(holder.vehicle_image);
holder.grey.setVisibility(View.GONE);
holder.green.setVisibility(View.VISIBLE);
holder.red.setVisibility(View.GONE);
} else if (gridItem.getStatus().equalsIgnoreCase("local")) { //only in local not in server
Picasso.with(context).load(new File(gridItem.getLocalImagePath())).resize(200, 150).placeholder(R.drawable.ic_loading_image).error(R.drawable.ic_error_image).into(holder.vehicle_image);
holder.grey.setVisibility(View.GONE);
holder.green.setVisibility(View.GONE);
holder.red.setVisibility(View.VISIBLE);
} else if (gridItem.getStatus().equalsIgnoreCase("localNewServerOld")) { //local new and server old
Picasso.with(context).load(new File(gridItem.getLocalImagePath())).resize(200, 150).placeholder(R.drawable.ic_loading_image).error(R.drawable.ic_error_image).into(holder.vehicle_image);
holder.grey.setVisibility(View.GONE);
holder.green.setVisibility(View.VISIBLE);
holder.red.setVisibility(View.VISIBLE);
} else if (gridItem.getStatus().equalsIgnoreCase("localAndServer")) { //local and server
Picasso.with(context).load(new File(gridItem.getLocalImagePath())).resize(200, 150).placeholder(R.drawable.ic_loading_image).error(R.drawable.ic_error_image).into(holder.vehicle_image);
holder.grey.setVisibility(View.GONE);
holder.green.setVisibility(View.VISIBLE);
holder.red.setVisibility(View.GONE);
} else { // not yet taken
holder.vehicle_image.setImageBitmap(defaultImage);
holder.grey.setVisibility(View.GONE);
holder.green.setVisibility(View.GONE);
holder.red.setVisibility(View.GONE);
}
}
holder.editVehicleImage.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
takeSnap(position);
}
});
return row;
}
private void takeSnap(int position) {
Intent intentFront = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
Uri mImageCaptureUri = Uri.fromFile(getVehiclePicPath(position, Constants.vehicalID));
Constants.editedVehicleImageUrl = mImageCaptureUri;
Constants.editedImagePosition = position;
intentFront.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, mImageCaptureUri);
try {
intentFront.putExtra("return-data", true);
((Activity) context).startActivityForResult(intentFront, position);
} catch (ActivityNotFoundException e) {
e.printStackTrace();
}
}
class OnImageClickListener implements View.OnClickListener {
int _position;
// constructor
public OnImageClickListener(int position) {
this._position = position;
}
@Override
public void onClick(View v) {
// if there is no image from server or local take new snap from camera
if (gridItems.get(_position).getStatus().equalsIgnoreCase("notTaken")) {
takeSnap(_position);
} else {
Intent i = new Intent(context, FullScreenViewActivity.class);
i.putExtra("position", _position);
Bundle bundle = new Bundle();
if (gridItems != null && !gridItems.isEmpty()) {
bundle.putSerializable("gridItems", (Serializable) gridItems);
}
i.putExtras(bundle);
context.startActivity(i);
}
}
}
static class ViewHolder {
TextView vehicleImageNameTV;
ImageView vehicle_image;
ImageView editVehicleImage;
ImageView grey;
ImageView red;
ImageView green;
}
public void setGridItems(ArrayList<GridItem> gridItems) {
this.gridItems = gridItems;
this.notifyDataSetChanged();
}
public void setImageInItem(int position, Uri mImageCaptureUri) {
GridItem gridItem = getItem(position);
if (gridItem.getStatus().equalsIgnoreCase("server")) {
gridItem.setLocalImagePath(mImageCaptureUri.getPath().toString());
gridItem.setStatus("localNewServerOld");
this.notifyDataSetChanged();
}
if (gridItem.getStatus().equalsIgnoreCase("localNewServerOld")) {
gridItem.setLocalImagePath(mImageCaptureUri.getPath().toString());
gridItem.setStatus("localNewServerOld");
this.notifyDataSetChanged();
}
if (gridItem.getStatus().equalsIgnoreCase("localAndServer")) {
gridItem.setLocalImagePath(mImageCaptureUri.getPath().toString());
gridItem.setStatus("localNewServerOld");
this.notifyDataSetChanged();
}
if (gridItem.getStatus().equalsIgnoreCase("local")) {
gridItem.setLocalImagePath(mImageCaptureUri.getPath().toString());
gridItem.setStatus("local");
this.notifyDataSetChanged();
}
}
public List<GridItem> getGridItems() {
return gridItems;
}
@Override
public int getCount() {
return gridItems.size();
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public GridItem getItem(int position) {
return this.gridItems.get(position);
}
@Override
public int getItemViewType(int position) {
return super.getItemViewType(position);
}
}
onActivityResult 代码:
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode != this.RESULT_OK) {
return;
}
showAlertDialog(requestCode);
}
void showAlertDialog(final int requestCode) {
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
alertDialogBuilder.setMessage("Photo will be replaced permanently. \n Are you sure want to replace");
alertDialogBuilder.setCancelable(false);
alertDialogBuilder.setPositiveButton("yes", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface arg0, int arg1) {
final int imagePosition = Constants.editedImagePosition;
mImageCaptureUri = Constants.editedVehicleImageUrl;
// set image to vehicle image adapter based on position
vehicleImageAdapter.setImageInItem(imagePosition,mImageCaptureUri);
}
});
alertDialogBuilder.setNegativeButton("No", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
});
AlertDialog alertDialog = alertDialogBuilder.create();
alertDialog.show();
}
网格视图看起来像:
试试这个
vehicleImageAdapter.setImageInItem(requestCode,mImageCaptureUri);
而不是
vehicleImageAdapter.setImageInItem(imagePosition,mImageCaptureUri);
对适配器使用 notifyDataSetChanged(),对 gridview 使用 invalidateViews,这样适配器和 gridview 都会刷新。
void showAlertDialog(final int requestCode) {
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
alertDialogBuilder.setMessage("Photo will be replaced permanently. \n Are you sure want to replace");
alertDialogBuilder.setCancelable(false);
alertDialogBuilder.setPositiveButton("yes", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface arg0, int arg1) {
final int imagePosition = Constants.editedImagePosition;
mImageCaptureUri = Constants.editedVehicleImageUrl;
// set image to vehicle image adapter based on position
vehicleImageAdapter.setImageInItem(imagePosition,mImageCaptureUri);
vehicleImageAdapter.notifyDataSetChanged();
gridview.invalidateViews();
}
});
alertDialogBuilder.setNegativeButton("No", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
});
AlertDialog alertDialog = alertDialogBuilder.create();
alertDialog.show();
}
使用 showAlertDialog
onClick
方法更新数据源中的数据,而无需从适配器调用任何额外的方法,例如 setImageInItem
:
1. 使用 yes
的 onClick
中的 Constants.editedImagePosition
从用作数据源的 ArrayList 获取项目 :
GridItem gridItem = gridItems.get(Constants.editedImagePosition);
2. 在 gridItem
中更新新图像 url :
gridItem.setLocalImagePath(mImageCaptureUri.getPath().toString());
gridItem.setStatus("local");
3. 将gridItem
放回ArrayList的相同位置:
gridItems.add(Constants.editedImagePosition,gridItem);
4. 现在在 yes
的 onClick
中调用 notifyDataSetChanged()
:
vehicleImageAdapter.notifyDataSetChanged();
或
只需更新 setImageInItem
中数据源中的选定项,即可使其与当前代码一起使用。在 setImageInItem
方法的最后一行添加以下内容:
this.gridItems.add(position,gridItem);
this.notifyDataSetChanged();
最后我通过简单地在 gridView 上调用 invalidate()
并再次将 gridView 添加到适配器来实现它。
即在我的 Activity
中添加了这两行
gridView.invalidate();
gridView.setAdapter(vehicleImageAdapter);
这一行之后:
vehicleImageAdapter.setImageInItem(imagePosition,mImageCaptureUri);
并在 this.notifyDataSetChanged();
之前的 setImageInItem()
方法中的 Array Adapter 中添加了这些行
gridItems.remove(position);
gridItems.add(position, gridItem);
我正在尝试从自定义适配器中的网格视图中替换图像。当我单击“编辑图像视图”时,从相机拍摄新快照返回到我的 activity,发送回适配器并尝试在该特定位置进行替换。但它没有显示在我点击的那个位置。任何人都可以建议为什么每次调用 this.notifyDataSetChanged();
这是我的适配器代码:
public class VehicleImageAdapter extends ArrayAdapter<GridItem> {
private Context context;
private List<GridItem> gridItems = new ArrayList();
int layoutResourceId;
String[] imageNames = {"Front Right", "Right Doors", "Right Top", "Rear Right",
"Engine", "Interior FR", "Interior RR", "Trunk",
"Front", "Interior FL", "Interior RL4", "Rear",
"Front left", "Left Doors", "Left Top", "Rear Left"};
private GridItem gridItem;
private int position;
public VehicleImageAdapter(Context context, int grid_item_layout, ArrayList<GridItem> gridItems) {
super(context, grid_item_layout);
this.context = context;
this.layoutResourceId = grid_item_layout;
this.gridItems = gridItems;
}
public View getView(final int position, View convertView, ViewGroup parent) {
View row = convertView;
ViewHolder holder = null;
this.position = position;
if (row == null) {
LayoutInflater inflater = ((Activity) context).getLayoutInflater();
row = inflater.inflate(layoutResourceId, parent, false);
holder = new ViewHolder();
holder.vehicleImageNameTV = (TextView) row.findViewById(R.id.vehicleImageNameTV);
holder.vehicle_image = (ImageView) row.findViewById(R.id.vehicle_image);
holder.editVehicleImage = (ImageView) row.findViewById(R.id.editVehicleImage);
holder.grey = (ImageView) row.findViewById(R.id.grey);
holder.red = (ImageView) row.findViewById(R.id.red);
holder.green = (ImageView) row.findViewById(R.id.green);
row.setTag(holder);
} else {
holder = (ViewHolder) row.getTag();
}
if (position >= 16) {
holder.vehicleImageNameTV.setText(imageNames[15]);
} else {
holder.vehicleImageNameTV.setText(imageNames[position]);
}
Bitmap defaultImage = BitmapFactory.decodeResource(context.getResources(), R.mipmap.tap_to_snap);
holder.vehicle_image.setOnClickListener(new OnImageClickListener(position));
if (gridItems.size() > 0 && !gridItems.isEmpty()) {
gridItem = gridItems.get(position);
if (gridItem.getStatus().equalsIgnoreCase("server")) { //only in server not in local
Picasso.with(context).load(gridItem.getServerImagePath()).resize(200, 150).placeholder(R.drawable.ic_loading_image).error(R.drawable.ic_error_image).into(holder.vehicle_image);
holder.grey.setVisibility(View.GONE);
holder.green.setVisibility(View.VISIBLE);
holder.red.setVisibility(View.GONE);
} else if (gridItem.getStatus().equalsIgnoreCase("local")) { //only in local not in server
Picasso.with(context).load(new File(gridItem.getLocalImagePath())).resize(200, 150).placeholder(R.drawable.ic_loading_image).error(R.drawable.ic_error_image).into(holder.vehicle_image);
holder.grey.setVisibility(View.GONE);
holder.green.setVisibility(View.GONE);
holder.red.setVisibility(View.VISIBLE);
} else if (gridItem.getStatus().equalsIgnoreCase("localNewServerOld")) { //local new and server old
Picasso.with(context).load(new File(gridItem.getLocalImagePath())).resize(200, 150).placeholder(R.drawable.ic_loading_image).error(R.drawable.ic_error_image).into(holder.vehicle_image);
holder.grey.setVisibility(View.GONE);
holder.green.setVisibility(View.VISIBLE);
holder.red.setVisibility(View.VISIBLE);
} else if (gridItem.getStatus().equalsIgnoreCase("localAndServer")) { //local and server
Picasso.with(context).load(new File(gridItem.getLocalImagePath())).resize(200, 150).placeholder(R.drawable.ic_loading_image).error(R.drawable.ic_error_image).into(holder.vehicle_image);
holder.grey.setVisibility(View.GONE);
holder.green.setVisibility(View.VISIBLE);
holder.red.setVisibility(View.GONE);
} else { // not yet taken
holder.vehicle_image.setImageBitmap(defaultImage);
holder.grey.setVisibility(View.GONE);
holder.green.setVisibility(View.GONE);
holder.red.setVisibility(View.GONE);
}
}
holder.editVehicleImage.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
takeSnap(position);
}
});
return row;
}
private void takeSnap(int position) {
Intent intentFront = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
Uri mImageCaptureUri = Uri.fromFile(getVehiclePicPath(position, Constants.vehicalID));
Constants.editedVehicleImageUrl = mImageCaptureUri;
Constants.editedImagePosition = position;
intentFront.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, mImageCaptureUri);
try {
intentFront.putExtra("return-data", true);
((Activity) context).startActivityForResult(intentFront, position);
} catch (ActivityNotFoundException e) {
e.printStackTrace();
}
}
class OnImageClickListener implements View.OnClickListener {
int _position;
// constructor
public OnImageClickListener(int position) {
this._position = position;
}
@Override
public void onClick(View v) {
// if there is no image from server or local take new snap from camera
if (gridItems.get(_position).getStatus().equalsIgnoreCase("notTaken")) {
takeSnap(_position);
} else {
Intent i = new Intent(context, FullScreenViewActivity.class);
i.putExtra("position", _position);
Bundle bundle = new Bundle();
if (gridItems != null && !gridItems.isEmpty()) {
bundle.putSerializable("gridItems", (Serializable) gridItems);
}
i.putExtras(bundle);
context.startActivity(i);
}
}
}
static class ViewHolder {
TextView vehicleImageNameTV;
ImageView vehicle_image;
ImageView editVehicleImage;
ImageView grey;
ImageView red;
ImageView green;
}
public void setGridItems(ArrayList<GridItem> gridItems) {
this.gridItems = gridItems;
this.notifyDataSetChanged();
}
public void setImageInItem(int position, Uri mImageCaptureUri) {
GridItem gridItem = getItem(position);
if (gridItem.getStatus().equalsIgnoreCase("server")) {
gridItem.setLocalImagePath(mImageCaptureUri.getPath().toString());
gridItem.setStatus("localNewServerOld");
this.notifyDataSetChanged();
}
if (gridItem.getStatus().equalsIgnoreCase("localNewServerOld")) {
gridItem.setLocalImagePath(mImageCaptureUri.getPath().toString());
gridItem.setStatus("localNewServerOld");
this.notifyDataSetChanged();
}
if (gridItem.getStatus().equalsIgnoreCase("localAndServer")) {
gridItem.setLocalImagePath(mImageCaptureUri.getPath().toString());
gridItem.setStatus("localNewServerOld");
this.notifyDataSetChanged();
}
if (gridItem.getStatus().equalsIgnoreCase("local")) {
gridItem.setLocalImagePath(mImageCaptureUri.getPath().toString());
gridItem.setStatus("local");
this.notifyDataSetChanged();
}
}
public List<GridItem> getGridItems() {
return gridItems;
}
@Override
public int getCount() {
return gridItems.size();
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public GridItem getItem(int position) {
return this.gridItems.get(position);
}
@Override
public int getItemViewType(int position) {
return super.getItemViewType(position);
}
}
onActivityResult 代码:
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode != this.RESULT_OK) {
return;
}
showAlertDialog(requestCode);
}
void showAlertDialog(final int requestCode) {
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
alertDialogBuilder.setMessage("Photo will be replaced permanently. \n Are you sure want to replace");
alertDialogBuilder.setCancelable(false);
alertDialogBuilder.setPositiveButton("yes", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface arg0, int arg1) {
final int imagePosition = Constants.editedImagePosition;
mImageCaptureUri = Constants.editedVehicleImageUrl;
// set image to vehicle image adapter based on position
vehicleImageAdapter.setImageInItem(imagePosition,mImageCaptureUri);
}
});
alertDialogBuilder.setNegativeButton("No", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
});
AlertDialog alertDialog = alertDialogBuilder.create();
alertDialog.show();
}
网格视图看起来像:
试试这个
vehicleImageAdapter.setImageInItem(requestCode,mImageCaptureUri);
而不是
vehicleImageAdapter.setImageInItem(imagePosition,mImageCaptureUri);
对适配器使用 notifyDataSetChanged(),对 gridview 使用 invalidateViews,这样适配器和 gridview 都会刷新。
void showAlertDialog(final int requestCode) {
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
alertDialogBuilder.setMessage("Photo will be replaced permanently. \n Are you sure want to replace");
alertDialogBuilder.setCancelable(false);
alertDialogBuilder.setPositiveButton("yes", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface arg0, int arg1) {
final int imagePosition = Constants.editedImagePosition;
mImageCaptureUri = Constants.editedVehicleImageUrl;
// set image to vehicle image adapter based on position
vehicleImageAdapter.setImageInItem(imagePosition,mImageCaptureUri);
vehicleImageAdapter.notifyDataSetChanged();
gridview.invalidateViews();
}
});
alertDialogBuilder.setNegativeButton("No", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
});
AlertDialog alertDialog = alertDialogBuilder.create();
alertDialog.show();
}
使用 showAlertDialog
onClick
方法更新数据源中的数据,而无需从适配器调用任何额外的方法,例如 setImageInItem
:
1. 使用 yes
的 onClick
中的 Constants.editedImagePosition
从用作数据源的 ArrayList 获取项目 :
GridItem gridItem = gridItems.get(Constants.editedImagePosition);
2. 在 gridItem
中更新新图像 url :
gridItem.setLocalImagePath(mImageCaptureUri.getPath().toString());
gridItem.setStatus("local");
3. 将gridItem
放回ArrayList的相同位置:
gridItems.add(Constants.editedImagePosition,gridItem);
4. 现在在 yes
的 onClick
中调用 notifyDataSetChanged()
:
vehicleImageAdapter.notifyDataSetChanged();
或
只需更新 setImageInItem
中数据源中的选定项,即可使其与当前代码一起使用。在 setImageInItem
方法的最后一行添加以下内容:
this.gridItems.add(position,gridItem);
this.notifyDataSetChanged();
最后我通过简单地在 gridView 上调用 invalidate()
并再次将 gridView 添加到适配器来实现它。
即在我的 Activity
中添加了这两行gridView.invalidate();
gridView.setAdapter(vehicleImageAdapter);
这一行之后:
vehicleImageAdapter.setImageInItem(imagePosition,mImageCaptureUri);
并在 this.notifyDataSetChanged();
setImageInItem()
方法中的 Array Adapter 中添加了这些行
gridItems.remove(position);
gridItems.add(position, gridItem);