Як реалізувати android: фон, який не розтягується?


100

Я знайшов цю чудову нитку, що описує, як "з'їсти торт і його теж", тобто використовувати зображення Buttonзамість ImageButton(що не дозволяє SetText(), зміни розміру тощо).

Це досягається за допомогою атрибута View:

android:background="@drawable/bgimage"

Єдина проблема з цим полягає в тому, що він розтягує зображення, щоб відповідати розміру кнопки.

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

Відповіді:


29

Ви повинні використовувати ImageView, якщо не хочете, щоб він розтягувався. Фонові зображення завжди розтягуватимуться, щоб відповідати виду. Потрібно встановити його як графічний малюнок, щоб примусити аспект зображення до об'єкта.

В іншому випадку, якщо ви дотримуєтесь ідеї 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);
}

1
Дякую + 1. ImageViewвиглядає цікаво. Я помітив , що це має атрибут, якого немає в Button: android:cropToPadding. Я не проти використовувати ImageView натомість, доки він має setOnClickListener()- що це робить. Що я втрачу, перейшовши Buttonна ImageView?
ef2011

1
До речі, 2-е рішення, яке ви запропонували, все ще розтягує зображення.
ef2011

Я в кінцевому рахунку використовував фіксований розмір кнопки (у пікселях!), Але я приймаю вашу відповідь, оскільки 1-я пропозиція виглядає як діюче альтернативне рішення.
ef2011

1
@ ef2011 Для ImageView не встановлюйте його як фонове зображення, його потрібно встановити як a, setDrawableResourceа потім переконайтесь, що setAdjustViewBoundsвстановлено значення true
Dr.J

9
Захищений за кульгавий розчин. Правильне рішення тут: stackoverflow.com/a/9362168/145046
Алекс Н.

260

Ви можете створити растровий файл 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/dravable-resource.html#Bitmap


3
Використання ImageViews - це вирішення, яке не завжди є можливим варіантом - я вважаю, що це правильне рішення :)
JakeP

3
Я встановлюю фон під час виконання. Чи є якесь рішення для створення растрових зображень під час виконання?
Vivek Kumar Srivastava

1
для мене це було найкращим рішенням, але вилучити атрибут "gravity", завдяки якому він відповідає його значенню за замовчуванням "fill". Це дозволить змінити розмір зображення на екран. Вивчіть посилання @Santosh для отримання додаткової інформації. Дякую!
Гюго

12
Я бачу лише одну проблему з таким підходом. Якщо джерельне джерело вже є більшим, ніж контейнер, воно буде відрізати зображення (виходячи з сили тяжіння), а не змінювати його розмір, підтримуючи співвідношення сторін, щоб вмістити контейнер.
Шашват Чорний

1
З’являється трохи датоване зараз. Це працює лише для растрових зображень і не працює для векторних малюнків.
The_Sympathizer

25

Просто використовуйте ImageButtonзамість того, щоб Buttonвиправити проблему.

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

і ви можете встановити

android:background="@null"

щоб видалити фон кнопки, якщо ви хочете.

Швидке виправлення !! :-)


1
А потім встановіть зображення методом setImageResource (), який працював на мене.
arlomedia

Мені хотілося, щоб і зображення, і колір фону в кнопці ... це спрацювало як принадність
Абхішек Чаухан

Для мене це працює більш точно (я маю на увазі, наприклад, "layout_centerVertical").
Максим Фірсофф

11

Я використовую 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>

Це насправді набагато простіше рішення проблеми, яка не повинна існувати
Ákos Nikházy

6

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

Серж


5

Використовуйте draw9patch ..., що входить до SDK-інструментів Android Studio. Ви можете визначити розтяжні ділянки зображення. Важливі частини обмежені, і зображення виглядає не викривленим. Гарна демонстрація на dra9patch - ТУТ

Використовуйте draw9patch, щоб змінити існуючий splash.png в new_splash.9.png, перетягніть new_splash.9.png у папку проекту dravable-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>

3

У мене було фонове зображення, не великого розміру, але з дивними розмірами - тому розтягування та погана робота. Я зробив метод з параметрами Context, View та Dravable ID (int), який буде відповідати розміру екрана пристрою. Використовуйте це, наприклад, фрагменти 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);
}

1

Ось версія відповіді Сантоша для програмно створених кнопок без необхідності окремої конфігурації 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, оскільки це працює трохи інакше, ніж кнопки зі звичайним фоновим зображенням.


1

Ви можете використовувати a 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>

0

Ключ полягає в тому, щоб встановити малюнок як зображення кнопки, а не як фон. Подобається це:

rb.setButtonDrawable(R.drawable.whatever_drawable);

Це метод CompoundButton, але не Button.
arlomedia

0

Можна використовувати звичайний ImageView у своєму xml та зробити його інтерактивним (android: clickable = "true")? Ви повинні використовувати як src зображення, яке має форму кнопки, тобто круглих кутів.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.