Come implementare un androide: sfondo che non si allunga?


100

Ho trovato questo ottimo thread che descrive come "mangiare la torta e averla anche", ovvero utilizzare l'immagine per a Buttoninvece di ImageButton(che non consente il SetText()ridimensionamento, ecc.).

Ciò si ottiene utilizzando l'attributo Visualizza:

android:background="@drawable/bgimage"

L'unico problema con questo è che allunga l'immagine per adattarla alle dimensioni del pulsante.

A parte l'hard-coding di una dimensione del pulsante fissa (in pixel!), C'è un modo per dire ad Android di non allungare affatto l'immagine di sfondo e ritagliarla o riempirla?

Risposte:


29

Dovresti usare ImageView se non vuoi che si allunghi. Le immagini di sfondo si allungheranno sempre per adattarsi alla visualizzazione. È necessario impostarlo come Drawable per forzare l'aspetto dell'immagine sull'oggetto.

Altrimenti, se ti attieni all'idea del pulsante, dovrai forzare il ridimensionamento nel pulsante per evitare che l'immagine si allunghi.

Codice:

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
Grazie +1. ImageViewSembra interessante. Ho notato che ha un attributo che non è in Button: android:cropToPadding. Non mi dispiace invece usare un ImageView, fintanto che ha setOnClickListener()- cosa che fa. Cosa perderò passando da Buttona ImageView?
ef2011

1
A proposito, la seconda soluzione che hai suggerito allunga ancora l'immagine.
ef2011

Ho finito per utilizzare la dimensione del pulsante fissa (in pixel!) Ma accetto la tua risposta perché il primo suggerimento sembra una soluzione alternativa funzionante.
ef2011

1
@ ef2011 Per ImageView, non impostarlo come immagine di sfondo, devi impostarlo come a setDrawableResourcee quindi assicurarti che setAdjustViewBoundssia impostato su true
Dr.J

9
Downvoted per una soluzione scadente. Soluzione corretta qui: stackoverflow.com/a/9362168/145046
Aleks N.

260

È possibile creare una bitmap xml e utilizzarla come sfondo per la vista. Per prevenire l'allungamento puoi specificareandroid:gravity attributo.

per esempio:

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

Ci sono molte opzioni che puoi usare per personalizzare il rendering dell'immagine

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


3
L'uso di ImageViews è una soluzione alternativa che non è sempre un'opzione possibile: credo che questa sia la soluzione corretta :)
JakeP

3
Sto impostando lo sfondo in fase di esecuzione. C'è qualche soluzione per creare bitmap in fase di esecuzione?
Vivek Kumar Srivastava

1
per me questa era la soluzione migliore, ma rimuovendo l'attributo "gravity", che lo fa corrispondere al suo valore predefinito "fill". Ciò consentirà il ridimensionamento dell'immagine per adattarsi allo schermo. Studia il link @Santosh per maggiori informazioni. Grazie!
Hugo

12
Vedo solo un problema con questo approccio. Se la sorgente disegnabile è già più grande del contenitore, questo ritaglierà l'immagine (in base alla gravità) invece di ridimensionarla, mantenendo le proporzioni, per adattarla al contenitore.
Shashwat Black

1
Sembra un po 'datato ora. Funziona solo per le bitmap e non per i drawable vettoriali.
The_Sympathizer

25

Il semplice utilizzo ImageButtoninvece di Buttonrisolvere il problema.

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

e puoi impostare

android:background="@null"

per rimuovere lo sfondo del pulsante, se lo desideri.

Soluzione rapida !! :-)


1
E poi imposta l'immagine con il metodo setImageResource () ... che ha funzionato per me.
arlomedia

volevo sia l'immagine che il colore di sfondo in un pulsante ... ha funzionato a meraviglia
Abhishek Chauhan

Funziona in modo più accurato per me (voglio dire - "layout_centerVertical", per esempio).
Maxim Firsoff

11

Sto usando un ImageView in un RelativeLayout che si sovrappone al mio layout normale. Nessun codice richiesto. Ridimensiona l'immagine all'altezza completa dello schermo (o qualsiasi altro layout che utilizzi), quindi ritaglia l'immagine a sinistra ea destra per adattarla alla larghezza. Nel mio caso, se l'utente gira lo schermo, l'immagine potrebbe essere un po 'troppo piccola. Quindi uso match_parent, che allungherà la larghezza dell'immagine se troppo piccola.

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

Questa in realtà è una soluzione molto più semplice per un problema che non dovrebbe esistere
Ákos Nikházy

6

Ho avuto lo stesso problema: dovresti usare solo un'immagine a 9 patch (.9.png) invece della tua immagine originale.

Serge


5

Usa draw9patch ... incluso negli strumenti SDK di Android Studio. Puoi definire le aree estensibili della tua immagine. Le parti importanti sono vincolate e l'immagine non sembra tutta deformata. Una buona demo su dra9patch è QUI

Usa draw9patch per cambiare il tuo splash.png esistente in new_splash.9.png, trascina new_splash.9.png nella cartella del progetto drawable-hdpi assicurati che AndroidManifest e styles.xml siano corretti come di seguito:

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

Avevo un'immagine di sfondo, non di grandi dimensioni, ma con dimensioni strane, quindi lo stretching e le cattive prestazioni. Ho creato un metodo con parametri Context, una vista e un ID disegnabile (int) che corrisponderà alle dimensioni dello schermo del dispositivo. Usalo, ad esempio, in Fragments onCreateView per impostare lo sfondo.

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

Ecco una versione della risposta di Santosh per i pulsanti creati in modo programmatico, senza la necessità di una configurazione XML separata:

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

Ho incluso la linea ColorFilter poiché funziona in modo leggermente diverso dai pulsanti con un'immagine di sfondo normale.


1

Puoi usare a FrameLayoutcon un ImageViewcome primo figlio, quindi il tuo layout normale come secondo figlio:

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

La chiave è impostare il disegnabile come immagine del pulsante, non come sfondo. Come questo:

rb.setButtonDrawable(R.drawable.whatever_drawable);

Questo è un metodo di CompoundButton ma non di Button.
arlomedia

0

Si può usare un semplice ImageView nel suo xml e renderlo cliccabile (android: clickable = "true")? Devi solo usare come src un'immagine che ha la forma di un pulsante, cioè gli angoli arrotondati.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.