ImageView的scaleType属性中,如何在BitmapDrawable中实现'centerCrop'效果?

42

我创建了一个带有标题图片的活动。这个标题图片最初是在活动的布局xml中使用ImageView创建的,其中scaleType设置为centerCrop。这样做可以实现我的需求,将图像居中,将其在纵向模式下剪裁左右部分,在横向模式下全部显示。

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingTop="30dp"
    android:paddingBottom="6dp"
    android:paddingLeft="6dp"
    android:paddingRight="6dp"
    android:background="#919EAC"
    android:orientation="vertical" >

<ImageView
    android:id="@+id/header_image"
    android:layout_width="match_parent"
    android:layout_height="120dp"
    android:contentDescription="@string/header_description"
    android:scaleType="centerCrop"
    android:src="@drawable/header" />

    .... <other views> ...

我希望用一个背景图替换它,这样我就可以利用头部图片的空间来显示数据,而且这样可以避免在不同的活动中重复使用相同的布局。

为此,我创建了一个可在android:background属性中引用的可绘制对象:

    <layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
        <item>
            <shape android:shape="rectangle" >
                <solid android:color="#919EAC" />
            </shape>
        </item>
        <item>
            <bitmap 
                android:antialias="true"
                android:gravity="top|center_horizontal"
                android:src="@drawable/header" />
        </item>
    </layer-list>

这个drawable定义了有颜色的背景,否则布局会定义它,并且它还定义了一个标题图片,否则将作为ImageView包含在布局中。

然而现在我的图片被缩放了,而我希望它被裁剪。

查看 Android 文档后,我尝试了其他重力模式,比如

    android:gravity="top|clip_horizontal"

但它似乎仍然与图像视图显示/缩放不同。

背景可绘制的正确定义是什么?


7
你能找到解决问题的方法吗?我也遇到了同样的困难。 - Marty
相关内容:https://dev59.com/JFTTa4cB1Zd3GeqPuq4V - mathheadinclouds
2
如何使用“fill_vertical|clip_horizontal”? - Trey Cai
@TreyCai 关闭了,但不完全相同... - User
4个回答

3

要在代码中进行中心裁剪位图,请按照以下步骤操作:

public static Bitmap cropCenter(Bitmap bmp) {
    int dimension = Math.min(bmp.getWidth(), bmp.getHeight());
    return ThumbnailUtils.extractThumbnail(bmp, dimension, dimension);
}

我不知道有其他的方法可以通过xml实现图片居中裁剪。

希望对大家有所帮助。

我在这篇文章中找到了这个解决方案: Android图片居中裁剪


3
我通过一个修饰器解决了这个问题,它可以维持底层可绘制对象的纵横比。以下是修饰器代码:https://gist.github.com/rudchenkos/e33dc0d6669a61dde9d6548f6c3e0e7e
不幸的是,无法从XML应用它,因此我在启动页Activity的最开始进行应用。
public class SplashActivity extends AppCompatActivity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        final Drawable bg = getResources().getDrawable(R.drawable.screen);
        getWindow().setBackgroundDrawable(new CenterCropDrawable(bg));

        ...
    }
}

这大致相当于在活动主题中将可绘制项指定为 android:windowBackground

不幸的是,这只是非常粗略的等价物,因为它出现在活动的正常布局时间,所以不能用作闪屏替代。 - User

-1

我不知道如何在背景上实现它。不过你可以尝试其他解决方案:

1)最简单的方法是将要显示在图像上方的内容和图像放在同一个布局中,使它们重叠。例如,您可以使用RelativeLayout,其中ImageView的尺寸为match_parent,TextView位于中心。

2)您可以将Imageview保存在不同的布局中,例如header.xml,并通过include header.xml在需要时随处使用它。

3)如果要在ImageView上方显示的布局在各处都相同,则可以创建一个自定义布局,其中包含一个ImageView和一个位于中心的TextView,并在各处使用该布局。然后您可以在此自定义布局上设置TextView字符串。您可以阅读更多关于自定义布局的信息,它们很容易理解。


-6

使用 scaleType = "centerCrop",您可以实现所需的结果,即裁剪图像的边缘并显示适合该大小的中心部分

对于 ImageView:

ImageViewscaleType 属性,仅适用于设置为其源的图像以显示。即如果它是 TextView,则 Text 是其源。

甚至您可能已经注意到,scaleType 不适用于设置为背景的图像,它只适用于在 XML 或运行时提供的图像。

对于布局

Layout 可以显示背景图像,但没有任何属性可用于处理背景图像并根据属性值进行缩放

因此,您应该停止从 Layout 要求 ImageView 的功能,因为它没有这个功能。

解决您问题的两种不同方法

1) 在不同的drawable文件夹中保留适当的背景头部图像并使用它,这样您就不需要在运行时进行缩放,因为您已经为不同大小开发了图像。

2) 您只需要重新设计您的XML,如下面的示例所示

<RelativeLayout 
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    >

    <ImageView
        android:id="@+id/imageView1"
        android:layout_width="wrap_content"
        android:layout_height="50dp"
        android:background="@drawable/subway"
        android:scaleType="centerCrop" />

    <Button
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:layout_alignParentLeft="true"
         />

    <EditText
        android:id="@+id/editText1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        />
</RelativeLayout> 

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接