【问题标题】:Position View on specified point of scaled ImageView在缩放的 ImageView 的指定点上定位视图
【发布时间】:2023-03-04 22:45:02
【问题描述】:

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

我有一个自定义的图像视图,它会根据包含此视图的布局的宽度或高度来改变它的大小。它的工作方式始终适合布局。

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>

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

例如:

  • 原图为1000x1000px
  • 我用这个来获取屏幕宽度:

    公共 int getScreenWidth() { DisplayMetrics displaymetrics = new DisplayMetrics(); getWindowManager().getDefaultDisplay().getMetrics(displaymetrics); int wt = displaymetrics.widthPixels; 返回重量; }

  • 即在 nexus 4 上,我有 800 像素

  • 从服务器获取图像并通过 setImageBitmap() 将其放入我的自定义图像视图中。
  • 然后我将地图上的原始点转换为新的缩放点;例如,在原始地图上,我的点 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

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

【问题讨论】:

标签: android android-layout android-imageview pixels


【解决方案1】:

我已经成功了。看来我的方法不错。

要使 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;
}

【讨论】:

  • 为什么要这么复杂的数学?你真正需要的是:1)getImageMatrix(),2)通过调用inverse来反转它,3)在反转矩阵上调用mapPoints或mapRect
  • 嗯,对我来说它就像 2+2 一样简单......而且我真的不明白使用 Matrix 的想法。也许如果你有时间,你能解释一下吗?据我了解,mapPoints 会给我和现在给我 getPositionX 方法一样的东西?
  • 您的 2+2 仅适用于特定数据(例如,游览 ImageView 必须具有与 Drawable 显示相同的纵横比),如果您的地图有 1010x990 的暗淡,那么您的所有数学运算都失败了,与矩阵,您可以使用普通的 ImageView 并根据需要缩放 Drawable,矩阵映射将始终没问题,因为正是该矩阵转换了 Canvas 以便使用您想要的任何 scaleType 绘制您的 Drawable
  • 是的,你说得对,它只适用于特定条件。对于我正在使用的项目-它们将永远是正确的。我将尝试深入研究使用 Matrix,因为它将来可能会有所帮助。谢谢!
猜你喜欢
  • 1970-01-01
  • 2016-02-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-13
  • 2012-09-04
相关资源
最近更新 更多