将ImageView ScaleType设置为“center”无法正常工作

问题描述 投票:4回答:7

我的ImageView有以下布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    android:descendantFocusability="blocksDescendants">
    <ImageView
        android:id="@+id/imageview_icon"
        android:layout_width="48dp"
        android:layout_height="48dp"
        android:scaleType="fitCenter" />
    (...)
</LinearLayout>

那些48dp分别在ldpimdpihdpi中等于36px,48px和72px。所有将在这个ImageView中使用的图像基本上都是图标,我在网上找到了我想要的应用程序(免费许可证)。但不幸的是,它没有大于48px的图像,并且使用不同的图像是不可能的。所以我需要一个新的解决方案......

现在我分别在ldpimdpi文件夹中有36px和48px的图像。但我在使用hdpi时遇到了麻烦。我想要在hdpi上运行的设备是他们使用mdpi图像(可用的更大的图像)并按原样使用它,无需缩放。基本上,ImageViewhdpi是72px,所以我希望48px图像在72px内,在中心,没有缩放。为此,我只是尝试将上面的scaleType中的ImageView更改为center,但无论如何图像都会缩放。

我在这里的最终问题是,解决上述问题的正确方法是什么?我如何才能在各自的密度中使用ldpimdpi图像,但运行hdpi的设备拾取最大的可用图像(这是mdpi)并防止任何缩放,只是将图像拟合在ImageView的中心?

编辑: 我自己回答了这个问题,但也许是其他人来这里寻找的答案。但我确实提供了一些关于真实情况和潜在问题的见解。如果可以,请查看并提供解决方法/修复方法。我赌你 :)

android imageview scaling
7个回答
13
投票

这个问题结果是一个非问题,我向任何创建它的人道歉,希望接受的答案将是他们正在寻找的不会。

为了说清楚,scaleType=centerInside按预期工作。也就是说,如果你的图像小于ImageView本身,那么该图像将不会缩放到ImageView的边界,它将保持在中心并且未缩放。

但是为了使上述工作符合预期,必须将drawable放在nodpi文件夹中。我知道这并不总是可以接受的。因此,当必须将drawable放入其中一个密度文件夹而不是nodpi文件夹时,scaleType属性仅适用于特定情况。

什么时候会起作用:

  • 您正在使用Xdpi密度在设备/模拟器上运行应用程序,并且在Xdpi密度文件夹中有一个drawable(此处为X表示,lmh或甚至xh)。
  • 例如,您正在使用hdpi密度运行应用程序设备/模拟器,但hdpi文件夹中没有可绘制的,并且系统从nodpi文件夹中选择替代drawable(它并不总是知道它将从哪个文件夹中选取) 。

什么时候不起作用:

  • 您正在运行应用程序设备/模拟器,例如,使用hdpi密度,但hdpi文件夹中没有可绘制的,并且系统从任何其他密度文件夹(不是nodpi文件夹)中选择可替换的drawable,drawable将缩放到ImageView边界,scaleType属性将不会做任何事情。

总之,我的问题没有“正确”的答案,这实际上取决于你想要实现的目标。答案我的问题,我只需要做两件事:a)将ImageView scaleType设置为centerInside和b)将所有drawables从mdpi文件夹复制到hdpi文件夹中(如上所述,scaleType=centerInside将使其工作)。

当然,复制drawables并不是最佳选择,但我找不到任何其他解决方案,到目前为止,没有其他人可以......所以,在目前,我会将此标记为已接受。

那么最佳答案/解决方案是什么? 在我看来,如果设备/模拟器在hdpi中运行并且在hdpi文件夹中没有匹配的drawable,它应该从mdpi文件夹中选择drawable而不缩放它,允许scaleType属性做它的事情。或者可能强制系统转到nodpi文件夹,如果它在相应的密度文件夹中找不到匹配的drawable,这也可能是一个解决方案。

因此,如果任何人都可以提供解决方案/修复此问题,那将是真正正确的答案。如果它发生了,我将改变接受的状态。


1
投票

我用这种方式解决了它:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content">
    <!-- Here is where the money is -->
    <LinearLayout
        android:orientation="vertical"
        android:layout_width="wrap_content"
        android:layout_height="fill_parent"
        android:gravity="center_horizontal|center_vertical">
        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>
    </LinearLayout>
    <LinearLayout
        android:orientation="vertical"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content">
        ...
    </LinearLayout>
</LinearLayout>

1
投票

就我而言,我将图像设置为android:background。当我把它设置为android:src时,它有效!


0
投票

尝试将其从hdpi文件夹中删除,并将其放在drawable-nodpi文件夹中。我不确定层次结构是什么(nodpi是否会覆盖ldpi和mdpi文件夹)但这将是我的第一次尝试。


0
投票

试试这个:

<FrameLayout android:layout_width="48dp" android:layout_height="48dp">
<ImageView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center"

    android:maxWidth="48px"
    android:maxHeight="48px"
    android:adjustViewBounds="true"
    android:src="..."
    />
</FrameLayout>

并将图像正常放在ldpi / mdpi文件夹中。

虽然我不建议使用像素值。


0
投票

试试吧

imageview.setAdjustViewBounds(false);

-1
投票

创建自定义ImageView:

package x;

public class MaxMDPIImageView extends ImageView {

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

    @Override
    protected void onDraw(Canvas canvas) {
        float density = getResources().getDisplayMetrics().density;
        if (density>1) {
            canvas.translate(getWidth()/2-getWidth()/density/2, getHeight()/2-getHeight()/density/2);
            canvas.scale(1/density, 1/density);
        }
        super.onDraw(canvas);
    }

}

简单地用作:

<x.MaxMDPIImageView
    android:src="@drawable/icon"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"/>
    />
© www.soinside.com 2019 - 2024. All rights reserved.