位置视图在缩放的ImageView的指定点上

时间:2014-03-25 13:44:24

标签: android android-layout android-imageview pixels

我有问题,我无法解决......

我有一个自定义的imageview,它根据更大的内容来改变它的大小 - 包含此视图的布局的宽度或高度。它的工作方式总是适合布局。

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();
    }
}

它的布局如下:

<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>

我想要实现的是我的原始地图尺寸为1000x1000px。在这张地图上,我有一些观点。我必须在Android上显示此地图,并在原始地图中的相同点上添加其他视图。

例如:

  • 原始地图为1000x1000px
  • 我的屏幕宽度是这样的:

    public int getScreenWidth(){     DisplayMetrics displaymetrics = new DisplayMetrics();     。getWindowManager()getDefaultDisplay()getMetrics(displaymetrics)。     int wt = displaymetrics.widthPixels;     返回wt; }

  • 即。在nexus 4上我有800px

  • 通过setImageBitmap()从服务器获取图像并将其放入我的自定义imageview。
  • 然后我将地图上的原始点翻译成新的,缩放的;因为在orignal地图上我有点x = 408,y = 68.在缩放的地图上它将是326,54。我想放在地图上的我的视图是36x36像素。

不幸的是,这里出现了问题......   - 首先 - 我的原始位置是点的中心,但对于View我只能设置顶部和左侧偏移。如果我减去它的一半大小 - 我会为我的视图获得新的中心点。   - 第二 - 有密度...我怎么能把这个东西放在不同的屏幕上?我想知道这是否有效:

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

我已经在NExus 4和7上检查了它并且它有效。但是在其他设备上 - 不是,新点是错位的......这个“20”是......我不确定。我首先想到的是那里的图像大小只有一半而不是 - 如果我把“18”那么它就会被错位...

以下是它的样子:   - 看起来应该如何 - http://imageshack.com/a/img560/9417/6mz8.png   - 它不应该如何 - http://imageshack.com/a/img24/2822/2u6p.png

有人可以帮我解决这个问题吗?

1 个答案:

答案 0 :(得分:0)

我设法做到了。看起来我的方法很好。

要通过适当的像素值偏移ImageView,我只需要将其宽度/高度的一半(以获得中心)乘以从原始缩放位置减去它。

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

然后设置正确的偏移量:

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);

其中getPosition根据1000px映射将位置缩放到实际设备大小:

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