Как реализовать андроид: фон, который не растягивается?

Я нашел этот отличный поток, описывающий, как "съесть торт и его тоже", т.е. использовать образ для Button вместо ImageButton (который не разрешает SetText(), изменение размера и т.д.).

Это достигается с помощью атрибута View:

android:background="@drawable/bgimage"

Единственная проблема заключается в том, что он растягивает изображение, чтобы он соответствовал размеру кнопки.

За исключением жесткого кодирования фиксированного размера кнопки (в пикселях!), есть ли способ сказать Android не растянуть фоновое изображение вообще и либо обрезать, либо пропустить его?

Ответ 1

Вы должны использовать ImageView, если вы не хотите, чтобы он растягивался. Фоновые изображения всегда будут растягиваться, чтобы соответствовать представлению. Вы должны установить его как Drawable, чтобы заставить аспект изображения к объекту.

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

Например, в

OnCreate(Bundle bundle) {
  //set content layout, etc up here

  //now adjust button sizes
  Button B = (Button) findViewById(R.id.somebutton);
  int someDimension = 50; //50pixels
  B.setWidth(someDimension);
  B.setHeight(someDimension);
}

Ответ 2

Вы можете создать растровое изображение xml и использовать его в качестве фона для представления. Чтобы предотвратить растяжку, вы можете указать атрибут android:gravity.

например:

<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
    android:src="@drawable/dvdr"
    android:tileMode="disabled" android:gravity="top" >
</bitmap>

Существует множество опций, которые вы можете использовать для настройки рендеринга изображения

http://developer.android.com/guide/topics/resources/drawable-resource.html#Bitmap

Ответ 3

Просто использование ImageButton вместо Button устраняет проблему.

<ImageButton android:layout_width="30dp"
             android:layout_height="30dp"
             android:src="@drawable/bgimage" />

и вы можете установить

android:background="@null"

чтобы удалить фон кнопки, если вы хотите.

Быстрое исправление!!: -)

Ответ 4

Я использую ImageView в RelativeLayout, который накладывается на мой обычный макет. Не требуется код. Он изменяет изображение на всю высоту экрана (или любой другой макет, который вы используете), а затем обрезайте изображение влево и вправо, чтобы соответствовать ширине. В моем случае, если пользователь поворачивает экран, изображение может быть слишком маленьким. Поэтому я использую match_parent, который сделает изображение растянутым по ширине, если оно слишком мало.

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ImageView
        android:id="@+id/main_backgroundImage"
        android:layout_width="match_parent"
        //comment: Stretches picture in the width if too small. Use "wrap_content" does not stretch, but leaves space

        android:layout_height="match_parent"
        //in my case I always want the height filled

        android:layout_alignParentTop="true"
        android:scaleType="centerCrop"
        //will crop picture left and right, so it fits in height and keeps aspect ratio

        android:contentDescription="@string/image"
        android:src="@drawable/your_image" />

    <LinearLayout
        android:id="@+id/main_root"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical" >
    </LinearLayout>

</RelativeLayout>

Ответ 5

У меня была та же проблема: вы должны использовать только 9-патч-изображение (.9.png) вместо исходного изображения.

Serge

Ответ 6

Используйте draw9patch..., включенный в инструменты Android Studio SDK. Вы можете определить растяжимые области вашего изображения. Важные детали ограничены, и изображение не выглядит искаженным. Хорошая демонстрация на dra9patch ЗДЕСЬ

Используйте draw9patch, чтобы изменить существующий splash.png на new_splash.9.png, перетащите new_splash.9.png в папку проекта drawable-hdpi убедитесь, что AndroidManifest и styles.xml являются правильными, как показано ниже:

AndroidManifest.xml:

<application
...
        android:theme="@style/splashScreenStyle"
>

styles.xml:

<style name="splashScreenStyle" parent="Theme.AppCompat.Light.DarkActionBar">
    <item name="android:windowBackground">@drawable/new_splash</item>
</style>

Ответ 7

Здесь версия ответа Santosh для программно созданных кнопок, без необходимости отдельной XML-конфигурации:

Button button = new Button(getContext());
Bitmap backgroundBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.my_button);
BitmapDrawable backgroundDrawable = new BitmapDrawable(getResources(), backgroundBitmap);
backgroundDrawable.setGravity(Gravity.CENTER); // also LEFT, CENTER_VERTICAL, etc.
backgroundDrawable.setColorFilter(new PorterDuffColorFilter(Color.RED, PorterDuff.Mode.SRC_ATOP));
button.setBackground(backgroundDrawable);

Я включил строку ColorFilter, так как это работает немного иначе, чем кнопки с обычным фоновым изображением.

Ответ 8

У меня было фоновое изображение, оно не было большого размера, но со странными размерами - поэтому растяжение и плохая производительность. Я сделал метод с параметрами Context, View и drawable ID (int), который будет соответствовать размеру экрана устройства. Используйте это, например, в Fragments onCreateView, чтобы установить фон.

public void setBackground(Context context, View view, int drawableId){
    Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(),
           drawableId);
    bitmap = Bitmap.createScaledBitmap(bitmap, Resources.getSystem().getDisplayMetrics()
                    .widthPixels, Resources.getSystem().getDisplayMetrics().heightPixels,
            true);
    BitmapDrawable bitmapDrawable = new BitmapDrawable(context.getResources(), bitmap);
    view.setBackground(bitmapDrawable);
}

Ответ 9

Ключ состоит в том, чтобы установить выталкиваемый как образ кнопки, а не как фон. Вот так:

rb.setButtonDrawable(R.drawable.whatever_drawable);

Ответ 10

Можно использовать простой ImageView в своем xml и сделать его интерактивным  (Андроид: кликабельны = "истина" )? Вы должны использовать только как src изображение, которое было сформировано как кнопка в круглых углах.

Ответ 11

Вы можете использовать FrameLayout с ImageView в качестве первого дочернего элемента, а затем ваш обычный макет как второй ребенок:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

  <ImageView
        android:id="@+id/background_image_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scaleType="centerCrop"
        android:src="@drawable/your_drawable"/>

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

  </LinearLayout>

</FrameLayout>