Android - 从阵列适配器位置问题替换图像

时间:2017-01-04 05:24:46

标签: android android-arrayadapter

我正在尝试从自定义适配器中的网格视图替换图像。当我点击编辑图像视图时,从摄像机拍摄新的快照返回到我的活动,发送回适配器并尝试替换该特定位置。但它没有显示我点击的那个位置。在调用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();
    }

网格视图看起来像:

enter image description here

4 个答案:

答案 0 :(得分:1)

对gridview使用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();
}

答案 1 :(得分:0)

使用showAlertDialog onClick方法更新数据源中的数据,而无需调用适配器中的setImageInItem等额外方法:

1。使用Constants.editedImagePosition onClick yes中的GridItem gridItem = gridItems.get(Constants.editedImagePosition); 从ArrayList获取项目作为数据源:

gridItem

2。更新gridItem.setLocalImagePath(mImageCaptureUri.getPath().toString()); gridItem.setStatus("local"); 中的新图片网址:

gridItem

3. 在同一位置的ArrayList中放回gridItems.add(Constants.editedImagePosition,gridItem);

notifyDataSetChanged()

4. 现在拨打onClick yes中的vehicleImageAdapter.notifyDataSetChanged();

setImageInItem

只需更新setImageInItem中数据源中的所选项目,即可使用当前代码。在this.gridItems.add(position,gridItem); this.notifyDataSetChanged(); 方法中添加以下行作为最后一行:

public class Player : MonoBehaviour, IControllable
{

}

答案 2 :(得分:0)

最后,我通过在gridView上调用invalidate()并再次将gridView添加到适配器来实现它。

即,在我的活动中添加了这两行

gridView.invalidate();
gridView.setAdapter(vehicleImageAdapter);

这一行之后:

  

vehicleImageAdapter.setImageInItem(imagePosition,mImageCaptureUri);

并在setImageInItem()

之前的this.notifyDataSetChanged();方法中将这些行添加到数组适配器中
  

gridItems.remove(位置);

     

gridItems.add(position,gridItem);

答案 3 :(得分:-1)

试试这个

vehicleImageAdapter.setImageInItem(requestCode,mImageCaptureUri);

而不是

vehicleImageAdapter.setImageInItem(imagePosition,mImageCaptureUri);