Scale down (or crop) dialog background in Android

2019-07-22 12:59发布

问题:

I have a high res image (let's say 1900x1200), which I want to use as background for my dialog. It is created

    Dialog dialog = new Dialog(this);
    dialog.setContentView(R.layout.dialog);

Dialog layout:

<LinearLayout 
   android:id="@+id/dialog"
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:orientation="vertical" >

However, if I use this image, the Dialog (layout) is expanded to cover the image (or reach the full-screen, whichever is smaller). If I make the image very small (like 320x200), the upscaling works fine. What I need, the Layout should wrap only the content, and NOT the background image. Image should be downscaled automatically or cropped to the dialog size, does not matter, it is a texture. I don't want to programmatically set/scale (if can be avoid), as I want to use this background in all my dialogs, and I am lazy to change code, instead of XMLs :) Also absolutely do not want to create all sort of resolutions, as Dialogs can be from very small to full screen, so no chance the guess the size.

What I tried:

Add to LinearLayout: android:background="@drawable/your_image this will extend the dialog to fit the image, which I don't want.

Use FrameLayout. As a first child add an ImageView, and comes the LinerLayout. Set the following in your ImageView.

android:src="@drawable/your_image"
android:scaleType = "centerCrop" //I tried ALL scaleType

Tried all tricks here: Scale background image to wrap content of layout Did not work.

I believe there is a very simple solution for this very simple and frequent request, I just could not figure out.

Here is my full dialog layout source:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/dialog"
android:orientation="vertical"
android:minWidth="300dp" 
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/back_dialog">

<EditText
    android:id="@+id/edittext_1"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"/>
<EditText
    android:id="@+id/edittext_2"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"/>

<CheckBox
    android:id="@+id/checkBox_1"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="@string/IDS_ABC" />

<LinearLayout 
    android:orientation="horizontal"
    android:paddingTop="10dp"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content">

    <Button
        android:id="@+id/button_ok"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:text="@string/IDS_OK" />

    <Button
        android:id="@+id/button_cancel"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:text="@string/IDS_CANCEL" />

</LinearLayout>
</LinearLayout>

EDIT Here is an image for better understanding

回答1:

The solution idea comes from here: How to wrap content views rather than background drawable?

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   xmlns:android="http://schemas.android.com/apk/res/android">
<ImageView
   android:src="@drawable/back_dialog"
   android:scaleType="fitXY"
   android:layout_width="0dp"
   android:layout_height="0dp"
   android:layout_alignTop="@+id/dialog_layout_main"
   android:layout_alignBottom="@id/dialog_layout_main"
   android:layout_alignLeft="@id/dialog_layout_main"
   android:layout_alignRight="@id/dialog_layout_main" />
<LinearLayout 
   android:id="@+id/dialog_layout_main"
   android:layout_width="match_parent"
   android:layout_height="wrap_content">
       .........
</LinearLayout>
</RelativeLayout>