esh0.pl
esh0.pl

Reputation: 61

Position View on specified point of scaled ImageView

I've problem that I can't solve...

I've a custom imageview, that is changing it's size depending on what is bigger - width or height of layout that contains this view. It's working that way to always fit into layout.

public class AspectRatioImageView extends ImageView {

    public AspectRatioImageView(Context context) {
        super(context);
    }

    public AspectRatioImageView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public AspectRatioImageView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        if (getDrawable() == null) {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        } else {
            int height = MeasureSpec.getSize(heightMeasureSpec);
            int width = MeasureSpec.getSize(widthMeasureSpec);

            if (width > height) {           
                width = height * getDrawable().getIntrinsicWidth() / getDrawable().getIntrinsicHeight();
            } else
                height = width * getDrawable().getIntrinsicWidth() / getDrawable().getIntrinsicHeight();

            setMeasuredDimension(width, height);
        }
    }

    @Override
    protected void onDetachedFromWindow() {
        setImageDrawable(null);

        super.onDetachedFromWindow();
    }
}

And it's putted in layout like this:

<RelativeLayout
    android:id="@+id/layMap"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_below="@+id/mFlipper"
    android:layout_above="@+id/layControl" >

    <com.mobiler.pogodynka.controls.AspectRatioImageView
        android:id="@+id/map"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:scaleType="fitXY"
        android:src="@drawable/ostrzezenia_hydro"/>

    <RelativeLayout
        android:id="@+id/layMapOverlay"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignTop="@+id/map"
        android:layout_alignBottom="@+id/map"
        android:layout_alignLeft="@+id/map"
        android:layout_alignRight="@+id/map"/>

</RelativeLayout>

What I'm trying to achieve is that I've original map with size 1000x1000px. On this map I've some points. I have to show this map on Android and also add other Views on the same points like in the original map.

So for example:

Unfortunatelly here comes the problem... - first - my original location is center of point, but for View I can only set top and left offset. If I subtract its half of size - I'd get new center point for my View. - second - there comes density... How on earth can i position this thing on different screens? I was wondering if this would work:

public int getPositionX(int imageWidth) {
    Resources resources = getResources();
    DisplayMetrics metrics = resources.getDisplayMetrics();
    int position = (int) ((imageWidth * (X - metrics.density * 20)) / 1000);
    return position;
}

I've checked it on NExus 4 and 7 and it works. But on other devices - not, the new points are misplaced... And this "20" is sth I'am not sure. I was first thinking that there shouold be half of image size but not - if i put "18"then it's going to be missaligned...

Here is how it look like: - how it should look - http://imageshack.com/a/img560/9417/6mz8.png - how it shouldn't - http://imageshack.com/a/img24/2822/2u6p.png

Could someone help me solve this?

Upvotes: 1

Views: 1057

Answers (1)

esh0.pl
esh0.pl

Reputation: 61

I've managed to do it. It looks like my approach was good.

To offset an ImageView by proper value of pixels I just need to multiply half (to get the center) of its width/height and subract it from original scaled position.

DisplayMetrics metrics = getResources().getDisplayMetrics();
final int offset = (int) (36/2 * metrics.density);

And then setting the correct offset:

RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT);
params.setMargins(marker.getPositionX(mMap.getWidth()) - offset,
marker.getPositionY(mMap.getHeight()) - offset, 0, 0);          
point.setLayoutParams(params);

Where getPosition scales position based on 1000px map to real device size:

public int getPositionX(int imageWidth) {
    int position = (int) ((imageWidth * X) / 1000);
    return position;
}

Upvotes: 0

Related Questions