3

I want to create a horizontal list of images which user can add (and delete) dynamically, except the first one (it works like add image button). User will click on that first one to add more pictures to the left of it. As shown below I create a horizontal scroll and linear layout which initially has one NetworkImageView, which is the image adder button.

The xml has:

...
        <HorizontalScrollView
            android:id="@+id/horizontal_scroll"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" >

            <LinearLayout
                android:id="@+id/linear"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:orientation="horizontal" >

                <com.android.volley.toolbox.NetworkImageView
                    android:layout_width="100dp"
                    android:layout_height="100dp"
                    android:id="@+id/imageViewAdd"
                    android:adjustViewBounds="true"
                    android:scaleType="centerCrop"
                    android:background="@color/colorAccent"
                    android:contentDescription="@string/description" />


            </LinearLayout>

        </HorizontalScrollView>
...

Then in the code, as the user clicks on that NetworkImageView, I want to add other ones in front of it one by one.

...
// On create code
layout = (LinearLayout) findViewById(R.id.linear);
        imageViewAdd = (NetworkImageView)findViewById(R.id.imageViewAdd);
        ImageLoader imageLoader = CustomVolleyRequest.getInstance(this.getApplicationContext())
                .getImageLoader();
        imageLoader.get(Config.IMAGE_PATH_URL, ImageLoader.getImageListener(imageViewAdd,
                R.drawable.image, android.R.drawable
                        .ic_menu_camera));
        imageViewAdd.setImageUrl(Config.IMAGE_PATH_URL, imageLoader);
        imageViewAdd.setOnClickListener(this);
        totalImageCount = 0;
...
// Create and add new image view
NetworkImageView newView = new NetworkImageView(this);
        newView.setId(id);
        newView.setPadding(2, 2, 2, 2);
    newView.setScaleType(ImageView.ScaleType.FIT_XY);
    layout.addView(newView, id);

    ImageLoader imageLoader = CustomVolleyRequest.getInstance(this.getApplicationContext())
            .getImageLoader();
    imageLoader.get(Config.IMAGE_PATH_URL, ImageLoader.getImageListener(newView,
            R.drawable.image, android.R.drawable
                    .ic_dialog_alert));
    newView.setImageUrl(Config.IMAGE_PATH_URL, imageLoader);
    newView.requestLayout();
    LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
            (int) getResources().getDimension(R.dimen.imageview_height), // 100 dp each
            (int)getResources().getDimension(R.dimen.imageview_width));
    newView.setLayoutParams(layoutParams);
...

Later in the code, when I actually want to set an image path to that, I read the width and height as follows:

int targetW = newView.getWidth();
int targetH = newView.getHeight();

Both of which returns 0. I have seen many solutions in SO but none of them worked for me (in my code you may see the residues of different approaches, which I have been trying for the last 3 hours!).

Any help is appreciated!

erol yeniaras
  • 3,701
  • 2
  • 22
  • 40
  • If you call getWidth() and getHeight() before the layout is actually drawn on screen, you will get 0. Refer this answer http://stackoverflow.com/a/3594216/3533289 – Much Overflow Feb 10 '16 at 06:11
  • Thanks! I saw that answer earlier. I call the getWidth() and getHeight() after I create and add the view to layout. Is not that enough to draw it on the screen? – erol yeniaras Feb 10 '16 at 06:14
  • No. you can use a ViewTreeObserver to identify when exactly the view is drawn on screen and then add your image to the root view – Much Overflow Feb 10 '16 at 06:20
  • When I click on "add image" view, a dialog box is opened and the user selects a picture either from camera or file selection intent. Then I load the path to the network image just that is just created. So the layout indeed is not visible at the time of selection and setting the selected picture. Can this be a problem? Where can I put the view tree observer? – erol yeniaras Feb 10 '16 at 06:24
  • Please check the answers posted by me and Rashid – Much Overflow Feb 10 '16 at 06:26

2 Answers2

2

You can get the height and width by using globalLayoutListener, try to do like this:

imageView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
      @Override
      public void onGlobalLayout() {
           int width = imageView.getWidth();
           int height = imageView.getHeight();
           //you can add your code here on what you want to do to the height and width you can pass it as parameter or make width and height a global variable
           imageView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
      }
});

Hope it works :)

Rashid
  • 1,700
  • 1
  • 23
  • 56
2

Rashid's answer also work. A simpler solution I found was to use the post method of the view. This ensures that the runnable you provide will execute after the view is drawn. So you could do the following

view.post(new Runnable() {
     @Override
     public void run() {
         view.getHeight(); //height is ready
         view.getWidth(); //width is ready
     }
});
Much Overflow
  • 3,142
  • 1
  • 23
  • 40