Bagaimana cara menerapkan android: background yang tidak meregang?

100

Saya menemukan utas bagus ini menjelaskan cara "makan kue dan memilikinya juga", yaitu menggunakan gambar untuk Buttonalih - alih ImageButton(yang tidak mengizinkan SetText(), mengubah ukuran, dll.).

Ini dicapai dengan menggunakan atribut View:

android:background="@drawable/bgimage"

Satu-satunya masalah dengan ini adalah ia meregangkan gambar agar sesuai dengan ukuran tombol.

Singkatnya, hard-coding ukuran tombol tetap (dalam piksel!), Apakah ada cara untuk memberi tahu Android untuk tidak meregangkan gambar latar belakang sama sekali dan memotong atau memangkasnya?

ef2011
sumber

Jawaban:

29

Anda harus menggunakan ImageView jika tidak ingin meregang. Gambar latar belakang akan selalu melebar agar sesuai dengan tampilan. Anda perlu mengaturnya sebagai Drawable untuk memaksa aspek gambar ke objek.

Jika tidak, jika Anda tetap berpegang pada ide Tombol, maka Anda perlu memaksa penskalaan pada tombol untuk mencegah gambar meregang.

Kode:

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);
}
Dr.J
sumber
1
Terima kasih + 1. ImageViewterlihat menarik. Aku melihat itu memiliki atribut yang tidak di Button: android:cropToPadding. Saya tidak keberatan menggunakan ImageView sebagai gantinya, selama itu setOnClickListener()- yang memang dilakukannya. Apa yang akan membuat saya kehilangan dengan beralih dari Buttonke ImageView?
ef2011
1
BTW, solusi kedua yang Anda sarankan tetap meregangkan gambar.
ef2011
Saya akhirnya menggunakan ukuran tombol tetap (dalam piksel!) Tetapi saya menerima jawaban Anda karena saran pertama terlihat seperti solusi alternatif yang berfungsi.
ef2011
1
@ ef2011 Untuk ImageView, jangan tetapkan sebagai gambar latar belakang, Anda harus menyetelnya sebagai a setDrawableResourcedan kemudian memastikan setAdjustViewBoundsdisetel ke true
Dr. J
9
Tidak disukai untuk solusi yang timpang. Solusi yang benar di sini: stackoverflow.com/a/9362168/145046
Aleks N.20
260

Anda dapat membuat bitmap xml dan menggunakannya sebagai latar belakang tampilan. Untuk mencegah peregangan, Anda dapat menentukan android:gravityatribut.

sebagai contoh:

<?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>

Ada banyak opsi yang dapat Anda gunakan untuk menyesuaikan rendering gambar

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

Santosh
sumber
3
Menggunakan ImageViews adalah solusi yang tidak selalu merupakan opsi yang memungkinkan - Saya yakin ini adalah solusi yang tepat :)
JakeP
3
Saya menyetel latar belakang pada waktu proses. Apakah ada solusi untuk membuat bitmap pada saat dijalankan?
Vivek Kumar Srivastava
1
bagi saya ini adalah solusi terbaik tetapi menghapus atribut "gravitasi", yang membuatnya cocok dengan nilai default "isi". Ini akan memungkinkan pengubahan ukuran gambar agar sesuai dengan layar. Pelajari tautan @Santosh untuk info lebih lanjut. Terima kasih!
Hugo
12
Saya hanya melihat satu masalah dengan pendekatan ini. Jika sumber drawable sudah lebih besar dari container, ini akan memotong gambar (berdasarkan gravitasi) daripada mengubah ukurannya, dengan mempertahankan rasio aspek, agar pas dengan container.
Shashwat Black
1
Muncul agak kuno sekarang. Ini hanya berfungsi untuk bitmap, dan tidak berfungsi untuk vector drawable.
The_Sympathizer
25

Cukup menggunakan ImageButtonalih-alih Buttonmemperbaiki masalah.

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

dan Anda dapat mengatur

android:background="@null"

untuk menghapus latar belakang tombol jika Anda mau.

Perbaikan Cepat !! :-)

Adil Malik
sumber
1
Dan kemudian setel gambar dengan metode setImageResource () ... yang berhasil untuk saya.
arlomedia
saya ingin gambar dan warna latar belakang dalam satu tombol ... ini bekerja seperti pesona
Abhishek Chauhan
Ini bekerja lebih akurat untuk saya (maksud saya - "layout_centerVertical", misalnya).
Maxim Firsoff
11

Saya menggunakan ImageView dalam RelativeLayout yang dilapisi dengan tata letak normal saya. Tidak ada kode yang dibutuhkan. Ini mengukur gambar ke tinggi penuh layar (atau tata letak lain yang Anda gunakan) dan kemudian memotong gambar ke kiri dan kanan agar sesuai dengan lebarnya. Dalam kasus saya, jika pengguna memutar layar, gambarnya mungkin agak terlalu kecil. Oleh karena itu saya menggunakan match_parent, yang akan membuat lebar gambar melebar jika terlalu kecil.

<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>
Gunnar Bernstein
sumber
Ini sebenarnya solusi yang jauh lebih mudah untuk masalah yang seharusnya tidak ada
Ákos Nikházy
6

Saya memiliki masalah yang sama: Anda sebaiknya hanya menggunakan gambar 9-patch (.9.png), bukan gambar asli Anda.

Serge

Serge Bollaerts
sumber
5

Gunakan draw9patch ... yang disertakan dalam alat SDK Android Studio. Anda dapat menentukan area gambar Anda yang dapat direntangkan. Bagian penting dibatasi dan gambar tidak terlihat bengkok seluruhnya. Demo bagus di dra9patch ada DI SINI

Gunakan draw9patch untuk mengubah splash.png yang sudah ada menjadi new_splash.9.png, seret new_splash.9.png ke dalam folder proyek drawable-hdpi memastikan AndroidManifest dan styles.xml sesuai seperti di bawah ini:

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>
WM1
sumber
3

Saya memiliki gambar latar belakang, tidak dalam ukuran besar, tetapi dengan dimensi yang aneh - karena itu peregangan dan kinerja yang buruk. Saya membuat metode dengan parameter Context, View dan drawable ID (int) yang akan cocok dengan ukuran layar perangkat. Gunakan ini misalnya di Fragments onCreateView untuk menyetel latar belakang.

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);
}
ZooMagic
sumber
1

Berikut adalah versi jawaban Santosh untuk tombol yang dibuat secara terprogram, tanpa perlu konfigurasi XML terpisah:

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);

Saya menyertakan garis ColorFilter karena itu bekerja sedikit berbeda dari tombol dengan gambar latar belakang normal.

arlomedia
sumber
1

Anda dapat menggunakan a FrameLayoutwith an ImageViewsebagai anak pertama, kemudian layout normal Anda sebagai anak kedua:

<?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>
Adam Johns
sumber
0

Kuncinya adalah menyetel drawable sebagai gambar tombol, bukan sebagai latar belakang. Seperti ini:

rb.setButtonDrawable(R.drawable.whatever_drawable);
Jose L Ugia
sumber
Ini adalah metode CompoundButton tetapi bukan dari Button.
arlomedia
0

Seseorang dapat menggunakan ImageView biasa dalam xml-nya dan membuatnya dapat diklik (android: clickable = "true")? Anda hanya perlu menggunakan sebagai src gambar yang sudah berbentuk seperti tombol yaitu sudut bulat.

Grigoreas P.
sumber