web-dev-qa-db-fra.com

Comment implémenter un Android: un fond qui ne s'étire pas?

J'ai trouvé ce excellent fil décrivant comment "manger le gâteau et l'avoir aussi", c'est-à-dire utiliser l'image pour un Button au lieu de ImageButton (qui ne permet pas SetText(), de redimensionnement, etc.).

Ceci est réalisé en utilisant l'attribut View:

Android:background="@drawable/bgimage"

Le seul problème avec cela est que l'image s'étend sur la taille du bouton.

À moins de coder en dur une taille de bouton fixe (en pixels!), Existe-t-il un moyen de dire à Android not d’agrandir l’image d’arrière-plan et de le rogner ou de l’alimenter?

92
ef2011

Vous devez utiliser ImageView si vous ne voulez pas que celle-ci s'étire . Les images d'arrière-plan seront toujours étirées pour s'adapter à l'affichage . Vous devez la définir en tant que Drawable pour forcer l'aspect de l'image à l'objet. .

Sinon, si vous vous en tenez à l'idée du bouton, vous devrez forcer la mise à l'échelle du bouton pour éviter que l'image ne s'étire.

Comme dans votre 

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);
}
27
Dr.J

Vous pouvez créer un bitmap xml et l'utiliser comme arrière-plan pour la vue. Pour empêcher l'étirement, vous pouvez spécifier l'attribut Android:gravity.

par exemple:

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

Il y a beaucoup d'options que vous pouvez utiliser pour personnaliser le rendu de l'image.

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

253
Santosh

Le simple fait d'utiliser ImageButton au lieu de Button résout le problème.

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

et vous pouvez définir 

Android:background="@null"

supprimer l'arrière-plan du bouton si vous le souhaitez.

Solution rapide !! :-)

25
Adil Malik

J'utilise un ImageView dans un RelativeLayout qui se superpose à ma mise en page normale. Aucun code requis . Il redimensionne l'image à la hauteur de l'écran (ou de tout autre agencement utilisé), puis découpe l'image de gauche à droite pour l'adapter à la largeur. Dans mon cas, si l'utilisateur allume l'écran, l'image risque d'être un peu trop petite. Par conséquent, j'utilise match_parent, ce qui rend l'image plus large si elle est trop petite.

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

J'ai eu le même problème: vous ne devriez utiliser qu'une image de 9 patchs (.9.png) au lieu de votre image d'origine.

Serge

6
Serge Bollaerts

Utilisez draw9patch ... inclus dans les outils de SDK d'Android Studio. Vous pouvez définir les zones extensibles de votre image. Les parties importantes sont contraintes et l'image ne semble pas complètement déformée. Une bonne démo sur dra9patch est ICI

Utilisez draw9patch pour modifier votre fichier splash.png existant en new_splash.9.png, Faites glisser new_splash.9.png dans le dossier du projet drawable-hdpi Assurez-vous que le fichier AndroidManifest et styles.xml sont corrects, comme indiqué ci-dessous: 

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

J'avais une image d'arrière-plan, pas de grande taille, mais avec des dimensions étranges - d'où l'étirement et la mauvaise performance. J'ai créé une méthode avec les paramètres Context, une vue et un identifiant pouvant être dessiné (int) qui correspond à la taille de l'écran du périphérique. Utilisez-le, par exemple, dans Fragments onCreateView pour définir l’arrière-plan.

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

Voici une version de la réponse de Santosh pour les boutons créés par programme, sans nécessiter de configuration XML distincte:

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

J'ai inclus la ligne ColorFilter car cela fonctionne un peu différemment des boutons avec une image d'arrière-plan normale.

1
arlomedia

Vous pouvez utiliser une FrameLayout avec une ImageView comme premier enfant, puis votre présentation normale comme deuxième enfant:

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

On peut utiliser un ImageView simple dans son xml et le rendre cliquable (Android: clickable = "true")? Vous n’avez qu’à utiliser comme image une image ayant la forme d’un bouton dans les coins arrondis.

0
Grigoreas P.

La clé est de définir le dessin comme image du bouton et non comme arrière-plan. Comme ça:

rb.setButtonDrawable(R.drawable.whatever_drawable);
0
Jose L Ugia