0

I am making a list view using 2 layouts depending upon type of photo. If the photo is square then square photo layout is used otherwise rectangular, along with other attributes. I tried to solve the problem but I couldn't figure out why I am getting NullPointerException even though I have initialized ImageView. Following is my code:

@Override
public View getView(int position, View convertView, ViewGroup parent) {

LayoutInflater inflater = (LayoutInflater) context .getSystemService(Context.LAYOUT_INFLATER_SERVICE);

View row;
final CartPhoto cp = photos.get(position);

if (convertView == null) {
    if(cp.image.width != cp.image.height){  //  Check for not Square Photo
        row = inflater.inflate(layoutId, null);
    }
    else
        row = inflater.inflate(layoutId_square, null);  //  Square Photo

} else {
    row = convertView;
}

final ImageView iv = (ImageView) row.findViewById(R.id.sq_image);
final ImageView iv_sqr = (ImageView) row.findViewById(R.id.sq_image_square);

float finalAspect = Product.aspectForProductSize(Product.ProductSize.Size4x6);
Bitmap thumb = cp.image.getThumbnail(context);

if(thumb != null) {
    if (thumb.getWidth() < thumb.getHeight()) { // portrait
        thumb = ImageOperations.cropToAspect(thumb, finalAspect);
    } else {
        thumb = ImageOperations.cropToAspect(thumb, 1/finalAspect);
    }


    if(cp.image.width != cp.image.height){

        iv.setImageBitmap(thumb);           // ERROR 1
        iv.setOnClickListener(imageClicked);
    }
    else {

        iv_sqr.setImageBitmap(thumb);      // ERROR 2
        iv_sqr.setOnClickListener(imageClicked);
    }
}
else {
    //  Crashlytics Log
    //String msg = "Else - Thumbnail Width : " + cp.image.width + ", Thumbnail Height : " + cp.image.height + "\n URI: " + cp.image.fullUrl;
    //Crashlytics.log(msg);
}

/***    Square or Rectangular    ***/
    /*
    if(cp.image.width == cp.image.height) {     //  SQUARE

        setupSizeQuantityButton(row, R.id.sq_4x4_minus, R.id.sq_4x4_qty, Product.ProductSize.Size4x4, -1, cp);
        setupSizeQuantityButton(row, R.id.sq_4x4_plus, R.id.sq_4x4_qty, Product.ProductSize.Size4x4, 1, cp);
        setupQuantityLabel(row, R.id.sq_4x4_qty, Product.ProductSize.Size4x4, cp);

        setupSizeQuantityButton(row, R.id.sq_8x8_minus, R.id.sq_8x8_qty, Product.ProductSize.Size8x8, -1, cp);
        setupSizeQuantityButton(row, R.id.sq_8x8_plus, R.id.sq_8x8_qty, Product.ProductSize.Size8x8, 1, cp);
        setupQuantityLabel(row, R.id.sq_8x8_qty, Product.ProductSize.Size8x8, cp);
    }
    else {
        setupSizeQuantityButton(row, R.id.sq_4x6_minus, R.id.sq_4x6_qty, Product.ProductSize.Size4x6, -1, cp);
        setupSizeQuantityButton(row, R.id.sq_4x6_plus, R.id.sq_4x6_qty, Product.ProductSize.Size4x6, 1, cp);
        setupQuantityLabel(row, R.id.sq_4x6_qty, Product.ProductSize.Size4x6, cp);

        setupSizeQuantityButton(row, R.id.sq_5x7_minus, R.id.sq_5x7_qty, Product.ProductSize.Size5x7, -1, cp);
        setupSizeQuantityButton(row, R.id.sq_5x7_plus, R.id.sq_5x7_qty, Product.ProductSize.Size5x7, 1, cp);
        setupQuantityLabel(row, R.id.sq_5x7_qty, Product.ProductSize.Size5x7, cp);

        setupSizeQuantityButton(row, R.id.sq_8x10_minus, R.id.sq_8x10_qty, Product.ProductSize.Size8x10, -1, cp);
        setupSizeQuantityButton(row, R.id.sq_8x10_plus, R.id.sq_8x10_qty, Product.ProductSize.Size8x10, 1, cp);
        setupQuantityLabel(row, R.id.sq_8x10_qty, Product.ProductSize.Size8x10, cp);
    }

return row;
}

The lines on which I am getting an error are commented as Error 1 and Error 2 respectively. Following is my error log:

Fatal Exception: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.ImageView.setImageBitmap(android.graphics.Bitmap)' on a null object reference
   at com.mailpix.samedayphoto.adapters.SizeQuantityAdapter.getView(SizeQuantityAdapter.java:128)
   at android.widget.AbsListView.obtainView(AbsListView.java:2347)
   at android.widget.GridView.makeAndAddView(GridView.java:1433)
   at android.widget.GridView.makeRow(GridView.java:361)
   at android.widget.GridView.fillDown(GridView.java:302)
   at android.widget.GridView.fillGap(GridView.java:262)
   at android.widget.AbsListView.trackMotionScroll(AbsListView.java:4995)
   at android.widget.AbsListView$FlingRunnable.run(AbsListView.java:4543)
   at android.view.Choreographer$CallbackRecord.run(Choreographer.java:773)
   at android.view.Choreographer.doCallbacks(Choreographer.java:586)
   at android.view.Choreographer.doFrame(Choreographer.java:555)
   at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:759)
   at android.os.Handler.handleCallback(Handler.java:739)
   at android.os.Handler.dispatchMessage(Handler.java:95)
   at android.os.Looper.loop(Looper.java:135)
   at android.app.ActivityThread.main(ActivityThread.java:5333)
   at java.lang.reflect.Method.invoke(Method.java)
   at java.lang.reflect.Method.invoke(Method.java:372)
   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:940)
   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:735)
Vishal
  • 1
  • YOu have two imageview 'sq_image` and 'sq_image_square'. I believe those are in two different layout . So depending upon which layout you inflate, the image view associated with the other layout will be null. You may want to move the code to get image view within the condition as well. – Jimmy Jul 10 '17 at 16:23

2 Answers2

0
final ImageView iv = (ImageView) row.findViewById(R.id.sq_image);
final ImageView iv_sqr = (ImageView) row.findViewById(R.id.sq_image_square);

Here, I think you've two different layouts respectively for rectangular and square images. Now check if there is only one Image View id (R.id.sq_image or R.id.sq_image_square) for each layout.

  • I have 2 different layouts for rectangular and square images. Also, I am having 2 different ImageView ids (R.id.sq_image and R.id.sq_image_square) respectively. – Vishal Jul 10 '17 at 19:05
  • If you can share your layouts code, it would be better to find out solution... – mustafiz012 Jul 10 '17 at 19:08
  • You can find the code (https://github.com/vishalmusale/StackOverflow) – Vishal Jul 10 '17 at 20:13
  • Got it. Suppose, your image is rectangular and rectangular layout will be selected in this case. So **row** holds the rectangular layout. Now see, you're trying to invoke both Image Views by **row** view: `final ImageView iv = (ImageView) row.findViewById(R.id.sq_image); final ImageView iv_sqr = (ImageView) row.findViewById(R.id.sq_image_square);` But **row** only holds rectangular rather than both of the layouts. So, you've to invoke any of them according to the layout selected and assigned to **row**. When rectangular: R.id.sq_image, otherwise R.id.sq_image_square. – mustafiz012 Jul 10 '17 at 20:31
0

Try to move it to the respective ifs.

if (convertView == null) {
    if(cp.image.width != cp.image.height){  //  Check for not Square Photo
        row = inflater.inflate(layoutId, null);
        ImageView iv = (ImageView) row.findViewById(R.id.sq_image);
    }
    else
        row = inflater.inflate(layoutId_square, null);  //  Square Photo
        ImageView iv_sqr = (ImageView) row.findViewById(R.id.sq_image_square);    
} else {
    row = convertView;
}

I would instantiate ImageView just below LayoutInflater, like this:

LayoutInflater inflater = (LayoutInflater) context .getSystemService(Context.LAYOUT_INFLATER_SERVICE);    
ImageView iv;
ImageView iv_sqr;
Abdul Rahman A Samad
  • 1,062
  • 1
  • 15
  • 21