3

My Problem

Suppose I have a bitmap - call it bmap with dimensions 100x75 (bmap.getWidth() x bmap.getHeight())

Suppose I have a rectangle, rect, sitting at point on the phone screen (x,y), with dimensions 500x350 (width x height)

How might I write a piece of code, which centers this bitmap within the bounding rect.

Note: Because I am using ContraintLayout there is not concept of parents or relativity.

Additionally, I would like a scale variable in the range (0,1], which scales bmap but it maintains its position in the center of the bounding rectangle rect.

My horrible attempt:

ImageView imgView = new ImageView(this.context);
imgView.setMaxWidth((int)(width*scale));
imgView.setMinimumWidth((int)(width*scale));
imgView.setMaxHeight((int)(height*scale));
imgView.setMinimumHeight((int)(height*scale));

imgView.setImageBitmap(bmap);

imgView.setX(x+((width-bmap.getWidth())/2));
imgView.setY(y+((height-bmap.getHeight())/2));

imgView.setAdjustViewBounds(true);

constraintLayout.addView(imgView);

This gives the following result (with scale = 1 for the green circle and scale = 0.6 for the red circle

enter image description here

Any ideas? I'm really stuck.

Greg Peckory
  • 7,700
  • 21
  • 67
  • 114

3 Answers3

2

I assume that the grey rectangles are normal Android Views which are children of your ConstraintLayout. They are created and added programmatically, so you'll have to give them ids with setId() method. The ids have to be positive numbers and have to be unique in this view hierarchy.

The size of the images which you are going to center in them is not important. You just have to give them proper constraints.

    //Set the id for the greyRectangleLeft
    greyRectangleLeft.setId(1)
    //Create a new constraint set
    ConstraintSet set = new ConstraintSet();

    //Clone the current constraints from your ConstraintsLayout to avoid losing them
    set.clone(constraintLayout);

    //Create the ImageView and set its Bitmap
    ImageView imageView = new ImageView(this);
    imageView.setImageBitmap(bmap);
    //The imageView should have an id as well
    imageView.setId(2);

    //Add the constraints which will center the ImageView within the bounds of the grey_rectangle_left
    set.connect(imageView.getId(), ConstraintSet.START, greyRectangleLeft.getId(), ConstraintSet.START);
    set.connect(imageView.getId(), ConstraintSet.END, greyRectangleLeft.getId(), ConstraintSet.END);
    set.connect(imageView.getId(), ConstraintSet.TOP, greyRectangleLeft.getId(), ConstraintSet.TOP);
    set.connect(imageView.getId(), ConstraintSet.BOTTOM, greyRectangleLeft.getId(), ConstraintSet.BOTTOM);

    //Set the width and height of your ImageView to the desired width and height
    set.constrainWidth(imageView.getId(), bmap.getWidth());
    set.constrainHeight(imageView.getId(), bmap.getHeight());

    //Add the newly created ImageView to the ConstraintLayout
    constraintLayout.addView(imageView);
    //Apply the created constraints
    set.applyTo(constraintLayout);

Repeat for the greyRectangleRight and second ImageView (but give them different ids).

Regarding the scale, I recommend using setScaleX() and setScaleY() of the ImageViews.

1

The easiest solution I see for this problem is to use the containers provided by android to help us to get this behavior. First of all, you can use relative layouts inside an constraint layout. there is no problem with that. Use two relative layouts with an image view inside them an just us centerInParent property to do the trick. I strongly recomend don't resize programatically the size of the views. Use the containers and the tools you have.

1

Your code actually does do what you expect it to do, but you probably use getHeight() and getWidth() instead of getMeasuredHeight() and getMeasuredHeight(). This will result in getting the width and height that are calculated from the xml and not the measured width and height that are set after the layout phase.

Check this post to learn more about the difference between them.

Qw4z1
  • 3,041
  • 1
  • 24
  • 36
  • getWidth and getHeight comes from the bitmap, not the imageView – Greg Peckory Feb 02 '18 at 15:11
  • @GregPeckory When I write getWidth() and getHeight() I'm talking about how you obtain the values for width and height variables. The way I interpreted your description was that they came from the gray rectangle views. – Qw4z1 Feb 02 '18 at 15:16