Find the position of the bitmap in the Android image view when the container view is scaled in the center

I have a RelativeLayout that contains a custom ImageView, scaleType = "centerInside", I load into a bitmap (usually smaller than imageView). How can I get the top / left position in which the bitmap was drawn? I need to be able to addView on top of positions relative to a bitmap.

RelativeLayout view = (RelativeLayout) inflater.inflate(R.layout.scroll_scaled, container, false); ContentImageView image = (ContentImageView) view.findViewById(R.id.base_page); Bitmap bm = mInterfaceActivity.getPageImage(mPageNumber); image.setImageBitmap(bm);` 

Layout file scrollled_scaled

 <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" > <ImageView android:scaleType="centerInside" android:id="@+id/base_page" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#ff00ff00" android:contentDescription="@string/product_page" android:src="@android:drawable/ic_menu_report_image" > </ImageView> </RelativeLayout> 
+4
source share
4 answers

You will need to do the math yourself using Drawable borders.

 ImageView test = (ImageView) findViewById(R.id.base_page); Rect bounds = test.getDrawable().getBounds(); int x = (test.getWidth() - bounds.right) / 2; int y = (test.getHeight() - bounds.bottom) / 2; 

First, we calculate the space in the View that is not used by the image. Then, since it is centered, the extra space is evenly distributed before and after the image, so it gains half that length in the View .

These numbers refer to the location of the view, but you can add the views X and Y if you need it.

+3
source

UPDATE 2: getX and getY will return 0 if you use an undefined width and height (e.g. wrap_content). Instead of iv.getX() and iv.getY() replace this with the answer to this question: Getting view coordinates relative to the root layout , then add image borders to these values.

You can do this by adding an ImageView position to the upper left border of the popped inside. Something like that:

 ImageView iv = (ImageView)findViewById(R.id.image_view); Drawable d = iv.getDrawable(); Rect bounds = d.getBounds(); int top = iv.getY() + bounds.top; int left = iv.getX() + bounds.left; 

UPDATE: for scalable images, you will need to multiply the top and left coordinates by the image scale to get a more accurate positioning. You can do it like this:

 Matrix m = iv.getImageMatrix(); float[] values = new float[9]; m.getValues(values); float scaleX = values[Matrix.MSCALE_X]; float scaleY = values[Matrix.MSCALE_Y]; 

Then you will need to multiply the vertex by scaleY, and on the left by scaleX.

+1
source

This method returns the borders of the image inside the imageView.

 /** * Helper method to get the bounds of image inside the imageView. * * @param imageView the imageView. * @return bounding rectangle of the image. */ public static RectF getImageBounds(ImageView imageView) { RectF bounds = new RectF(); Drawable drawable = imageView.getDrawable(); if (drawable != null) { imageView.getImageMatrix().mapRect(bounds, new RectF(drawable.getBounds())); } return bounds; } 
+1
source

A two-part solution based on feedback and a few retries was completed.

I created subviews and added them to the RelativeLayout in "approximate", but as View.INVISIBLE.

I super-classified the RelativeLayout ViewGroup and onLayout I went to the list of children's views and put them in the β€œright” place, because I now had a RelativeLayout, aware of its extended size.

It seems awkward, but it works.

Thanks to everyone for the suggestions, my decision was to take pieces of any advice.

0
source

Source: https://habr.com/ru/post/1433594/


All Articles