web-dev-qa-db-fra.com

Le carrelage est tirable et s'étire parfois

J'ai un ListView dont les éléments ont un fond en mosaïque. Pour ce faire, j'utilise le code XML dessinable suivant:

<bitmap
    xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:src="@drawable/tile"
    Android:tileMode="repeat" />

Habituellement, cela fonctionne. Parfois, cependant, le dessin pouvant être dessiné n'est pas affiché en mosaïque, mais étendu pour remplir l'élément de liste entier. (J'ai plusieurs tuiles différentes comme celle-ci, et je les utilise mélangées dans une seule liste. S'il y a étirement au lieu de mosaïque, cela n'a jamais été fait en même temps, pour ce que ça vaut.)

J'ai aussi essayé d'ajouter Android:dither="true" à ce fichier xml, car j'ai lu quelque part que sans cela, il pourrait y avoir des bugs. Cela n'a rien changé.

Quelqu'un at-il eu le même problème? Comment l'avez-vous réparé?

53
benvd

J'ai aussi été piqué par ce problème. Très difficile à diagnostiquer, encore plus difficile à trouver des rapports similaires et des solutions utilisables.

"Tapas" sur le canal freenode # Android-dev irc est venu avec la méthode suivante:

public static void fixBackgroundRepeat(View view) {
    Drawable bg = view.getBackground();
    if (bg != null) {
        if (bg instanceof BitmapDrawable) {
            BitmapDrawable bmp = (BitmapDrawable) bg;
            bmp.mutate(); // make sure that we aren't sharing state anymore
            bmp.setTileModeXY(TileMode.REPEAT, TileMode.REPEAT);
        }
    }
}

Appliquez-le à toutes les vues pour lesquelles un arrière-plan en mosaïque est défini (par exemple, findViewById eux).

De plus, j'ai l'impression que ce bogue a commencé à s'aggraver après la définition de "anyDensity = true" dans AndroidManifest.xml.

38
Ivo van der Wijk

Je viens d'avoir exactement le même problème, sauf avec CLAMP TileMode. J'ai une image que je souhaite étirer en bas et la configurer en tant que BitmapDrawable défini par XML. Dans la fenêtre de prévisualisation graphique, tout semble bien, quelle que soit la taille de la ViewImage, elle dessine mon bitmap en haut. puis répète les derniers pixels à remplir jusqu'à la fin.

Le lancement de l'application sur diverses versions du SDK sur l'émulateur et sur mon propre téléphone a ensuite généré une distorsion de type 'remplissage' directe qui est totalement inutile.

La solution s'est simplement avérée être de réappliquer le TileMode chaque fois que je changeais la taille du ImageView dans mon code:

((BitmapDrawable)ascender.getDrawable()).setTileModeY(TileMode.CLAMP);

Maintenant, tout va bien. Alors oui, cela ressemble à un bug pour moi.

9
Zulaxia

Ce sujet fait beaucoup de bruit en ligne, avec diverses (et nombreuses) solutions suggérées. 

  • Si vous ne vous sentez toujours pas à l'aise, ma suggestion est de conservez toutes les ressources bitmap en mosaïque Au carré, dimensions de base 2 .

c'est-à-dire: 16 pixels sur 16 pixels pour un actif de mosaïque xhdpi. 

J'espérais que la plate-forme Android se "recouvrirait" de mosaïque pour remplir un espace si le bitmap ne tessellait pas parfaitement - puis supprimait les déchets. Cependant, le test d'une bitmap en mosaïque 10 pixels * 10 pixels sur mdpi, hdpi et xhdpi (et v2.3 à v4.0) a montré de manière "inconsistante" cet étirement. 

La dimension base 2 permet une division complète et uniforme à mesure que vous avancez dans les différentes résolutions et que chaque périphérique essaie de peindre les mosaïques chaque fois que la vue est créée. 

Dans le développement d'Android, nous contestons le matériel varié et les fournisseurs qui plongent leurs doigts dans la plate-forme. Parfois, cette sorte de magie noire triviale fonctionne.

Cela semble avoir résolu le problème au moins pour moi. Ça vaut le coup. 

6
mjw

Comme je n'ai pas vu le lien ici, cela a été a confirmé qu'il s'agissait d'un bogue dans Android. Il a été corrigé dans ICS. Voir Un bogue XML Bitmap tileMode dessinable? pour plus de détails.

6
Steve Pomeroy

Cela ressemble à un bug, même si je ne l'ai jamais vu moi-même. Si vous avez un fichier APK simple qui reproduit le problème, envoyez-le-moi (romainguy/at/Android.com) ou créez un bogue ici .

2
Romain Guy

Ce blog entry discute du problème

combiné avec cette solution de Tapas listée par Ivo van der Wijk, cela fonctionne pour moi.

La clé était de remove le paramètre de mosaïque du code XML, puis définissez-le sur mosaïque au moment de l'exécution. Cela ne fonctionne pas pour moi si les deux sont réglés en mosaïque.

Edit: en fait, j'ai menti. Même avec cela, il semble parfois échouer.

Ce serait très agréable d'avoir une solution de contournement fiable.

Edit 2: le mettre à quelque chose d'autre (par exemple. CLAMPED) puis le remettre en arrière jusqu'à présent semble fonctionner.

1
RabidMutant

Toujours souffert de ce problème sur les appareils plus anciens exécutant Lollipop, se produit sur les changements d'orientation. La programmation du mode mosaïque par programme ne fonctionnait pas, mais cette réponse remplissait les fonctions suivantes: https://stackoverflow.com/a/13480444/658727

0
batterj2

J'avais aussi le même problème. Ce qui me manquait, c'est que nous devions ajouter scaletype à fitXY dans l'imageview pour que le bitmap xml fonctionne correctement.

tile_bitmap.xml

<bitmap
    xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:src="@drawable/tile"
    Android:tileMode="repeat" />

layout.xml

<ImageView
    Android:layout_width="match_parent"
    Android:src="@drawable/tile_bitmap"
    Android:layout_height="match_parent"
    Android:scaleType="fitXY"/>
0
Nishant Chauhan

J'ai déplacé mon image du dossier drawable-xhdpi au dossier drawable et tout allait bien.

0
Waqar Khan