Search code examples
androidsurfaceviewandroid-gallery

Gallery doesn't show anything when it has only 1 image


I'm using SurfaceView in my 1st activity. On clicking an image using SurfaceView, I move to 2nd activity also storing path of the recently clicked image. In 2nd activity, I want to display that image in Gallery.

In 2nd activity on a button click, again I move to 1st activity and after clicking picture, I move to 2nd activity.

Now in 2nd activity, there will 2 images that should be displayed in Gallery.

My problem is after clicking 1st image, Gallery is not displaying anything. Note that getView() of adapter set for Gallery is getting called.

But after clicking 2nd image onwards, when there are 2 or more images in Gallery, they are getting displayed.

I also tried g.refreshDrawableState(); after

g.setAdapter(new ImageAdapter(this));
g.setOnItemClickListener(this);     
g.setSelection(0, false);

but to no avail.

I know what I have written here sounds complex, but try to visualize the scenario.

Any help appreciated.

Edit

ImageAdapter.java

public class ImageAdapter extends BaseAdapter {
        public ImageAdapter(Context c) {
            mContext = c;
        }

        public int getCount() {
            return mImageIds.length;//mImageIds is Array of image paths
        }

        public Object getItem(int position) {
            return position;
        }

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

        public View getView(int position, View convertView, ViewGroup parent) {
            ImageView i = new ImageView(mContext);

            final String imageUri = mImageIds[position].trim();
            try {
                if (imageUri.length() != 0) {
                    File f = new File(imageUri);
                    if (f.exists()) {
                        b = constants.shrinkBitmap(f.getPath(), 800, 800);
                        d = new BitmapDrawable(getResources(), b);
                        i.setImageDrawable(d);
                    } else {
                        i.setBackgroundColor(Color.WHITE);
                        i.setImageResource(R.drawable.ic_launcher);
                    }
                } else {
                    i.setBackgroundResource(R.drawable.ic_launcher);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }

            i.setAdjustViewBounds(true);
//BELOW "length" is some predefined value
            i.setPadding(Math.round(length * 0.05f), 0,
                    Math.round(length * 0.05f), 0);
            i.setLayoutParams(new Gallery.LayoutParams(Math
                    .round(length * 0.9f),
                    LayoutParams.WRAP_CONTENT));
            i.setScaleType(ScaleType.FIT_XY);
            return i;
        }
    }

Edit (2)

After Vikram's suggestion, I tried logging length value and it was indeed 0 for the first time i.e. when calling i.setLayoutParams(new Gallery.LayoutParams(Math.round(length * 0.9f),LayoutParams.WRAP_CONTENT));

I set this length variable just after onCreate() by this way:

g.post(new Runnable() {
     public void run() {
       length = g.getRight() - g.getLeft();
     }
    });

as I want to retrieve width of my parent layout in code and accordingly set Gallery item width.

I know the reason I get length as 0 is setContentView() takes bit of time to take effect. How can I retrieve before Adapter is called?


Solution

  • The variable length seems to be the problem here. If it's value is zero, when getView() for the first item is called, the width parameter is set to zero.

    In your edit, length is indeed getting a non-zero value, perhaps a bit late. You can make the following call to update the view:

    myAdapter.notifyDataSetChanged();
    

    This call should be placed inside run() after the computation of length.

    Your workaround for the 'blinking' is fine. As an alternative(and if the gallery's width should match screen width), try this:

    In place of:

    g.post(new Runnable() {
     public void run() {
       length = g.getRight() - g.getLeft();
     }
    });
    

    put:

    Point pointSize = new Point();
    getWindowManager().getDefaultDisplay().getSize(pointSize);
    length = pointSize.x;
    

    Place this before initializing the adapter.

    Another thing to note here is that g.getRight() is computed as:

    g.getRight() = g.getLeft() + g.getWidth()
    

    So, to compute length, you may as well do:

    length = g.getWidth()
    

    as:

    getWidth() = getRight() - getLeft()