Подтвердить что ты не робот

Эквивалент ImageView scaleType 'centerCrop' для растровой гравитационной гравитации

Я создал действие с изображением заголовка. Это изображение заголовка изначально создаётся в макете Activity 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> ...

Я хотел бы заменить это на выделение фона, чтобы я мог использовать пространство изображения заголовка для отображения данных, и это избавляет меня от повторения одного и того же макета в разных действиях.

По этой причине я создал drawable, на который я могу ссылаться в атрибуте 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"

Но он по-прежнему выглядит/масштабируется по-другому, чем изображение.

Каким будет правильное определение фона?

4b9b3361

Ответ 1

Чтобы обрезать растровое изображение в коде, сделайте следующее:

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

Я не знаю другого способа, чтобы centerCrop bitmap xml мудрый.

Надеюсь, это поможет кому угодно.

Я нашел это решение из этой публикации: Android Crop Center Bitmap

Ответ 2

Я не знаю, как это сделать с фоном. Вы можете попробовать другие решения:

1) Самое простое решение отображать что-то поверх изображения - это разместить их как в макете, так и в том, что они перекрываются. Например, вы можете использовать RelativeLayout с размерами ImageView, ImageView - match_parent в обоих измерениях и TextView в центре.

2) Вы можете сохранить изображение в другом макете, скажем, header.xml, и использовать его include header.xml везде, где это необходимо.

3) Если макет, который будет отображаться поверх ImageView, будет таким же везде, вы можете создать собственный макет с помощью ImageView и сказать, TextView в центре, и использовать этот макет повсюду. Затем вы можете установить строку TextView на этом настраиваемом макете. Вы можете больше узнать о пользовательских макетах, они легки.

Ответ 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));

        ...
    }
}

Это примерно эквивалентно определению drawable как android:windowBackground в теме Activity

Ответ 4

Используя scaleType = "centerCrop", вы достигли желаемого результата, обрезая края изображения и отображая центральную часть, которая подходит для этого размера.

Для ImageView:

ImageView имеет атрибут scaleType, который работает только для изображения, которое установлено в качестве источника для отображения. то есть, как если бы он был TextView, тогда Text является источником.

Даже вы могли заметить, что scaleType не работает для изображения, которое устанавливается как фон, который работает только с изображением, которое поставляется в качестве источника либо в XML во время выполнения.

Для макета

Layout может отображать фоновые изображения, но нет никакого атрибута для макета, который может обрабатывать фоновые изображения и масштабировать его в соответствии с значением атрибута.

Итак, вы должны прекратить запрашивать объект ImageView из Layout, потому что он его не имеет.

2 разных решения вашей проблемы

1) Соблюдайте правильные изображения для фонового заголовка в разных папках и используйте его, так что вам не нужно масштабировать его во время выполнения, поскольку вы уже разработали изображение для размера по-разному.

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>