8motions Posté(e) 15 mars 2011 Share Posté(e) 15 mars 2011 Bonsoir, J'ai une View sur laquelle je voudrais dessiner un layout issu de mes ressources. J'ai donc surchargé la méthode onDraw(Canvas canvas) de ma View mais je ne trouve pas la méthode pour "monter en mémoire" mon layout et le dessiner dans le canvas. Voici mon code à l'heure actuelle : public class MyView extends View { @Override protected void onDraw(Canvas canvas) { // Inflate and instanciate view LayoutInflater inf = LayoutInflater.from(getContext()); View vView = inf.inflate(R.layout.custom_view, null); ImageView iView = (ImageView) vView.findViewById(R.id.custom_image); iView.setImageResources(R.drawable.custom_image); // GetBitmap from View Bitmap mViewBitmap = Bitmap.createBitmap(vView.getWidth(), vView.getHeight(), Bitmap.Config.ARGB_8888); Canvas cView = new Canvas(mViewBitmap); vView.draw(cView); // DrawBitmap in View's Canvas canvas.drawBitmap(mViewBitmap, x, y, null); } } avec custom_view.xml <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_height="wrap_content" android:layout_width="wrap_content" android:background="@drawable/custom_bubble"> <ImageView android:scaleType="center" android:layout_width="50dp" android:layout_height="50dp" android:id="@+id/custom_image"/> </LinearLayout> Le soucis c'est que lors de la création du bitmap, le vView.getWidth() et vView.getHeight() sont égaux à 0, cela provoque une exception lors de sa création. Je ne comprend pas trop comment marche l'inflation de view. Autant si mon layout était du genre MATCH_PARENT je veux bien qu'il soit perdu, mais la je suis en WRAP_CONTENT, il n'a aucune raison (selon moi) de ne pas connaitre son width et son height... J'ai essayé d'ajouter sans succès les méthodes assez obscures que sont : vView.forceLayout(); vView.setDrawingCacheEnabled(true); vView.buildDrawingCache(); vView.requestLayout(); Avez vous des idées? Merci Lien vers le commentaire Partager sur d’autres sites More sharing options...
Sakaroz Posté(e) 16 mars 2011 Share Posté(e) 16 mars 2011 Salut, je dois avouer que plus je relis ton code, plus j'ai du mal à comprendre ce que t'as voulu faire^^ Si tu veux ajouter un layout dans un autre, pourquoi ne pas faire tout simplement un addView (il faut que ton conteneur soit un viewGroup) ? Tu ne seras donc pas obligé de passer par onDraw. A quoi correspondent x et y ? Petite chose hors sujet mais toujours utile : la méthode onDraw est une méthode dite critique, elle utilisée souvent et rapidement par la classe View, il faut éviter de créer trop d'objet à l'intérieur par soucis d'optimisation de mémoire, le garbage collector n'a parfois pas le temps de supprimer tous les objets et tu peux te retrouver avec des OutOfMemory :) Essaye d'en mettre un maximum en attribut de ta classe. Lien vers le commentaire Partager sur d’autres sites More sharing options...
8motions Posté(e) 16 mars 2011 Auteur Share Posté(e) 16 mars 2011 Si tu veux ajouter un layout dans un autre, pourquoi ne pas faire tout simplement un addView (il faut que ton conteneur soit un viewGroup) ? Tu ne seras donc pas obligé de passer par onDraw. Non j'ai bel et bien besoin d'une View, pas d'un ViewGroup. Je dessine d'autres choses "à la mano" dans le canvas de cette View A quoi correspondent x et y ? x et y correspondent ici à la position dans ma view principale de mon layout à dessiner Petite chose hors sujet mais toujours utile : la méthode onDraw est une méthode dite critique, elle utilisée souvent et rapidement par la classe View, il faut éviter de créer trop d'objet à l'intérieur par soucis d'optimisation de mémoire, le garbage collector n'a parfois pas le temps de supprimer tous les objets et tu peux te retrouver avec des OutOfMemory :) Essaye d'en mettre un maximum en attribut de ta classe. Ce code est un résumé de ce que je veux faire, il y a juste les grandes lignes. Bien entendu dans mon draw je n'ai pas de réelle construction de ce "bitmap", celui ci est créé une fois puis sauvegardé et réutilisé pour chaque draw. Je n'ai pas voulu trop surcharger de code ce post. De même, mon layout ne contient pas qu'une image, je l'ai simplifié pour l'exemple. Lien vers le commentaire Partager sur d’autres sites More sharing options...
8motions Posté(e) 18 mars 2011 Auteur Share Posté(e) 18 mars 2011 up ? Lien vers le commentaire Partager sur d’autres sites More sharing options...
throrin19 Posté(e) 6 avril 2011 Share Posté(e) 6 avril 2011 J'ai le même souci que toi, dans le cadre de mon application je dois dessiner un certain nombre de bulles avec du texte dans mon ImageView. Le souci, c'est que je ne sais pas comment dessiner ce Layout perso (seule solution trouvée) dans ma vue. Tu as réussis à répondre partiellement à ma question mais Maintenant je suis bloqué au même endroit que toi :( Lien vers le commentaire Partager sur d’autres sites More sharing options...
8motions Posté(e) 6 avril 2011 Auteur Share Posté(e) 6 avril 2011 Si cela peux t'aider j'ai trouvé un moyen de faire, par contre je ne sais pas si cela est 100% sure de marcher. Cela marche dans mon cas précis mais il y a peut-être des effets de bord... // Default draw LayoutInflater inf = LayoutInflater.from(context); LinearLayout vView = (LinearLayout) inf.inflate(R.layout.overlayitem, null); vView.setBackgroundResource(R.drawable.bubble); ImageView iView = (ImageView) vView.findViewById(R.id.image); iView.setImageDrawable(d); iView.setVisibility(View.VISIBLE); TextView tView = (TextView) vView.findViewById(R.id.title); tView.setText("bla bla"); tView.setVisibility(View.VISIBLE); tView = (TextView) vView.findViewById(R.id.description); tView.setText("bla bla"); tView.setVisibility(View.VISIBLE); // Set max Size vView.measure(500, 500); vView.layout(0, 0, vView.getMeasuredWidth(), vView.getMeasuredHeight()); vView.forceLayout(); vView.setDrawingCacheEnabled(true); vView.buildDrawingCache(true); vView.requestLayout(); if ((mViewBitmap = vView.getDrawingCache(true)) == null) { mViewBitmap = Bitmap.createBitmap(vView.getMeasuredWidth(), vView.getMeasuredHeight(), Bitmap.Config.ARGB_8888); Canvas cView = new Canvas(mViewBitmap); vView.draw(cView); } Si tu as des remarques n'hésite pas... Lien vers le commentaire Partager sur d’autres sites More sharing options...
throrin19 Posté(e) 8 avril 2011 Share Posté(e) 8 avril 2011 Merci pour ton code, je test ça mais je ne vois pas où tu indique où dessiner ton mViewBitmap qui semble être en fait le visuel de ton vView. C'est bon, j'ai trouvé, c'était indiqué dans ton précédent Post. ça marche très bien ta méthode et je n'ai aucun problème de lenteur en plus. Merci beaucoup :) Lien vers le commentaire Partager sur d’autres sites More sharing options...
Recommended Posts
Archivé
Ce sujet est désormais archivé et ne peut plus recevoir de nouvelles réponses.