0

I know this is a common question to ask but yet I have a problem which the ImageView returns to null. I just want to know if it is possible to call an xml file from the drawable and convert it to Byte []. One thing it returns a null because I didn't declare ImvTempCashCard = findViewById(R.id.ImageView);.Is there any other way to call drawable image without using ImageView?.I just want to set temporary value to ImvTempCashCard which assign image from the drawable files, It is necessary to use setBackgroundResource to ImageView?

error

Attempt to invoke virtual method 'void android.widget.ImageView.setBackgroundResource(int)' on a null object reference

Source

ImageView ImvTempCashCard;

ImvTempCashCard.setBackgroundResource(R.drawable.ic_creditcard);
Bitmap bitmap = ((BitmapDrawable)ImvTempCashCard.getDrawable()).getBitmap();
ImvTempCashCard.setImageBitmap(Bitmap.createScaledBitmap(bitmap, 120, 120, false));
ByteArrayOutputStream stream = new ByteArrayOutputStream();
byte [] byteimage = stream.toByteArray();
//byteimage = returns to null

Latest update:

Actually This will view and add to my GridView, while looping the query, the condition is, when the blob image is null then it will replace the drawable files image. Did I implement it correctly?

  try {
        Cursor cursor = MainActivity.sqLiteHelper.getData("SELECT id,cash_card_actual_no,hh_number,series_number,cc_image, id_image, cash_card_scanned_no FROM CgList");
        list.clear();

        while (cursor.moveToNext()) {
            int id = cursor.getInt(0);
            byte[] CashCardImage = cursor.getBlob(4);

            if (CashCardImage.length ==1){

                Bitmap bitmap = BitmapFactory.decodeResource(getApplicationContext().getResources(),R.drawable.ic_creditcard);
                ByteArrayOutputStream stream = new ByteArrayOutputStream();
                byte [] z = stream.toByteArray();
                CashCardImage = z;

            }
            list.add(new Inventory(cashCardNumber, CashCardImage,id));
        }
        adapter.notifyDataSetChanged();
    }

Adapter inside onCreate

    @Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_inventory_list);
    
    gridView = (GridView) findViewById(R.id.gridView);
    list = new ArrayList<>();
    adapter = new InventoryListAdapter(this, R.layout.activity_inventory_items, list);
    gridView.setAdapter(adapter);

InventoryListAdapter class

public class InventoryListAdapter extends BaseAdapter {

private Context context;
private  int layout;
private ArrayList<Inventory> foodsList;

public InventoryListAdapter(Context context, int layout, ArrayList<Inventory> foodsList) {
    this.context = context;
    this.layout = layout;
    this.foodsList = foodsList;
}

@Override
public int getCount() {
    return foodsList.size();
}
@Override
public Object getItem(int position) {
    return foodsList.get(position);
}

@Override
public long getItemId(int position) {
    return position;
}

private class ViewHolder{
    ImageView imageView;
}

@Override
public View getView(int position, View view, ViewGroup viewGroup) {

    View row = view;
    ViewHolder holder = new ViewHolder();
    if(row == null){
        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        row = inflater.inflate(layout, null);

        holder.imageView = (ImageView) row.findViewById(R.id.imgFood);
        row.setTag(holder);
    }
    else {
        holder = (ViewHolder) row.getTag();
    }
    Inventory inventory = foodsList.get(position);
    byte[] foodImage = inventory.getImage();
    Bitmap bitmap = BitmapFactory.decodeByteArray(foodImage, 0, foodImage.length);
    holder.imageView.setImageBitmap(bitmap);
    return row;
}
}
Audwin Oyong
  • 2,247
  • 3
  • 15
  • 32
Henry
  • 165
  • 13
  • Tips: Try searching for answer to your root problem to avoid [XY problem](https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem) – Ricky Mo Sep 21 '21 at 02:12
  • @RickyMo Thanks for response but why I'm getting a null since this line exist in my drawable ? `ImvTempCashCard.setBackgroundResource(R.drawable.ic_creditcard);` In other way if that lines is wrong for declaration how can I declare drawable file ? so that I can convert it to Bitmap – Henry Sep 21 '21 at 02:21
  • You answered yourself `One thing it returns a null because I didn't declare ImvTempCashCard = findViewById(R.id.ImageView);` – Ricky Mo Sep 21 '21 at 02:22
  • @Ricky Mo Yes is there any other way to call drawable image without using ImageView? – Henry Sep 21 '21 at 02:24
  • See the link in my first comment. – Ricky Mo Sep 21 '21 at 02:24
  • @RickyMo Thanks for your response, based on the link you've been provided, my question is it is necessary to use and declare ImageView like this image? [Image](https://i.stack.imgur.com/TIBl4.png) I have updated code above but the bitmap didn't use at all since I didn't declare` ImageView.` – Henry Sep 21 '21 at 02:37
  • You don't care then don't use it. That's it. You just want to get a `Bitmap` from `Drawable` right? And you already did it. What is your real goal? – Ricky Mo Sep 21 '21 at 02:43
  • Please state your real goal when asking question. Don't ask about things that you don't care. – Ricky Mo Sep 21 '21 at 02:44
  • Do you want [converting Java bitmap to byte array](https://stackoverflow.com/questions/4989182/converting-java-bitmap-to-byte-array)? – Ricky Mo Sep 21 '21 at 02:47
  • @RickyMo Thanks for your response I've added and updated my really goal above but it didn't show to my GridView the only shows is those image that is not null. – Henry Sep 21 '21 at 02:59
  • @RickyMo And also I've been wondering it is really my bitmap convert to `byte[]` , It is the bitmap value used at all? since I remove `ImageView` because I don' t need it like this image [Image](https://i.stack.imgur.com/5laA1.png) – Henry Sep 21 '21 at 03:05
  • Can you show the `getView()` method of your `adapter`? I am guessing you have an `ImageView` there. If your goal is to display the drawable, you just have to call `setDrawable` to the `ImageView` that you actually want to display. No need to do anything in the middle. No need to extract the data and store somewhere else temporarily. – Ricky Mo Sep 21 '21 at 03:08
  • Please post the implementation of your `InventoryListAdapter` – Ricky Mo Sep 21 '21 at 03:13
  • @Ricky Mo Thanks for your response I don't have any ImageView from this class but my adapter is getting the list of ImageView from the other class which is the `InvetonryListAdapter` class do you have idea for this? should I post InventoryList? – Henry Sep 21 '21 at 03:13
  • In your `InventoryListAdapter` there should be some kind of ViewHolder which hold the reference to the `ImageView`. When you bind a list item to a view, you have access to the viewHolder and hence you can call something like `viewHolder.imageView.setDrawable()` Please post your implentation of `InventoryListAdapter` if you are not sure about it. – Ricky Mo Sep 21 '21 at 03:17
  • @Ricky Mo Yes I've posted above my class which it has `getView()` – Henry Sep 21 '21 at 03:18

1 Answers1

1

Your goal is to display a placeholder image from drawable in a grid view when the image is not found from the database. You can put all the logic inside the getView() in the adapater. Check if the image data does not exist, then call setImageResource instead of setImageBitmap.

First, no need to do any extra steps when constructing the list

Cursor cursor = MainActivity.sqLiteHelper.getData("SELECT id,cash_card_actual_no,hh_number,series_number,cc_image, id_image, cash_card_scanned_no FROM CgList");
list.clear();

while (cursor.moveToNext()) {
    int id = cursor.getInt(0);
    byte[] CashCardImage = cursor.getBlob(4);
    list.add(new Inventory(cashCardNumber, CashCardImage,id));
}
adapter.notifyDataSetChanged();

Then change your getView() like this:

@Override
public View getView(int position, View view, ViewGroup viewGroup) {

    View row = view;
    ViewHolder holder = new ViewHolder();
    if(row == null){
        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        row = inflater.inflate(layout, null);

        holder.imageView = (ImageView) row.findViewById(R.id.imgFood);
        row.setTag(holder);
    }
    else {
        holder = (ViewHolder) row.getTag();
    }
    Inventory inventory = foodsList.get(position);
    byte[] foodImage = inventory.getImage();
    if(foodImage.length > 1)
    {
        Bitmap bitmap = BitmapFactory.decodeByteArray(foodImage, 0, foodImage.length);
        holder.imageView.setImageBitmap(bitmap);
    }
    else{
        holder.imageView.setImageResource (R.drawable.ic_creditcard)
    }
    
    return row;
}

Tips: Whenever you want to display something to the view that don't need extra processing, try to do it as directly as possible. Avoid extracting the data, storing the data somewhere and pass it around etc. Just get the data to the view you want to display directly.

Ricky Mo
  • 6,285
  • 1
  • 14
  • 30
  • I have an error that drawable cannot resolve method `setDrawable` in `ImageView` [image](https://i.stack.imgur.com/IQkjz.png) should I convert it to bitmap? Thanks by the you have the idea of how I'm going to write it down. – Henry Sep 21 '21 at 03:35
  • @Henry Sorry. The method name should be `setImageResource` instead of `setDrawable`. I edited. [setImageResource](https://developer.android.com/reference/android/widget/ImageView#setImageResource(int)) – Ricky Mo Sep 21 '21 at 03:37
  • Thanks for your response I appreciate it, but I tried it lately but I'm getting this error? [Image](https://i.stack.imgur.com/Gkoas.png) since my drawable is xml? `Require type = Drawable provide = int` – Henry Sep 21 '21 at 03:50
  • @Henry Use `setImageResource` instead of `setImageDrawable`. – Ricky Mo Sep 21 '21 at 03:51
  • Thank you so much! It solves my problem, I appreciate your effort – Henry Sep 21 '21 at 03:56