<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
 
 <title>Piwaï.info</title>
 <link href="http://www.piwai.info/atom.xml" rel="self"/>
 <link href="http://www.piwai.info"/>
 <updated>2022-09-08T23:09:09+00:00</updated>
 <id>http://www.piwai.info</id>
 <author>
   <name>Pierre-Yves Ricau</name>
   <email>py.ricau@gmail.com</email>
 </author>

 
 
 <entry>
   <title>Square Cash - you owe me money!</title>
   <link href="http://www.piwai.info/square-cash-mailto"/>
   <updated>2013-10-17T00:00:00+00:00</updated>
   <id>http://www.piwai.info/square-cash-mailto</id>
   <content type="html">&lt;p&gt;This week, Square introduced &lt;a href=&quot;http://square.com/cash&quot;&gt;Square Cash&lt;/a&gt;, a new service that lets you send money to your friends through email.&lt;/p&gt;

&lt;p&gt;To use it, just send your friend an email with the &lt;strong&gt;amount&lt;/strong&gt; in the &lt;strong&gt;subject&lt;/strong&gt; and &lt;strong&gt;Cc&lt;/strong&gt; &lt;strong&gt;cash@square.com&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;That’s it, you don’t need to install any new app, go through a painful signup process, or use a specific email provider.&lt;/p&gt;

&lt;p&gt;It’s &lt;strong&gt;free&lt;/strong&gt;, &lt;strong&gt;simple&lt;/strong&gt;, &lt;a href=&quot;https://squareup.com/help/en-us/article/5144-square-cash-security&quot;&gt;secure&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Here is a trick I’d like to share with you: you can make it even simpler for friends who owe you money by sending them a &lt;strong&gt;mailto&lt;/strong&gt; link. Then, they just need to click on the link to open their favorite email app and send that worthy email.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-html&quot; data-lang=&quot;html&quot;&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;a&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;href=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;mailto:your@email.com?subject=$1&amp;amp;amp;cc=cash@square.com&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;Send me money!&lt;span class=&quot;nt&quot;&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;&lt;a class=&quot;btn&quot; href=&quot;mailto:py.ricau+casharticle@gmail.com?subject=$1&amp;amp;cc=cash@square.com&quot;&gt;&lt;i class=&quot;icon-envelope&quot;&gt;&lt;/i&gt; Send me money! &amp;raquo;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I think that’s a pretty cool way to collect money from your friends :) .&lt;/p&gt;

&lt;p&gt;Side note: as of now, Square Cash only works in the US.&lt;/p&gt;

&lt;h1 id=&quot;comments&quot;&gt;Comments&lt;/h1&gt;

&lt;!--

To comment, copy and paste the following block

## [Nickname](http://website)
Comment

--&gt;
</content>
 </entry>
 
 
 
 <entry>
   <title>Transparency with JPEGs done right</title>
   <link href="http://www.piwai.info/transparent-jpegs-done-right"/>
   <updated>2013-04-23T00:00:00+00:00</updated>
   <id>http://www.piwai.info/transparent-jpegs-done-right</id>
   <content type="html">&lt;p&gt;A few months ago, Square published a great article on &lt;a href=&quot;http://corner.squareup.com/2013/01/transparent-jpegs.html&quot;&gt;Transparency with JPEGs&lt;/a&gt; on Android. It’s definitely worth reading! Just don’t use the provided code yet :) .&lt;/p&gt;

&lt;p&gt;Romain Guy suggested in the comments that you can do this in a much more efficient and simpler way, either by &lt;a href=&quot;http://www.curious-creature.org/2012/12/13/android-recipe-2-fun-with-shaders/&quot;&gt;using a BitmapShader&lt;/a&gt; or by playing with Porter-Duff blending modes.&lt;/p&gt;

&lt;p&gt;Using a bitmap shader is great for dynamic masks. To apply a static mask to a bitmap loaded from a JPEG, Porter-Duff is the way to go, as we will see in this article.&lt;/p&gt;

&lt;h2 id=&quot;principle&quot;&gt;&lt;a id=&quot;Principle&quot; href=&quot;#Principle&quot;&gt;Principle&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;We just need to load the bitmap, and then draw the mask on top of it with the right &lt;a href=&quot;http://en.wikipedia.org/wiki/Alpha_compositing#Description&quot;&gt;Porter-Duff&lt;/a&gt; mode.&lt;/p&gt;

&lt;p&gt;Here is what the &lt;a href=&quot;http://developer.android.com/reference/android/graphics/PorterDuff.Mode.html&quot;&gt;Android documentation&lt;/a&gt; has to say about the different modes:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;ADD 	Saturate(S + D)&lt;/li&gt;
  &lt;li&gt;CLEAR 	[0, 0]&lt;/li&gt;
  &lt;li&gt;DARKEN 	[Sa + Da - Sa&lt;em&gt;Da, Sc&lt;/em&gt;(1 - Da) + Dc*(1 - Sa) + min(Sc, Dc)]&lt;/li&gt;
  &lt;li&gt;DST 	[Da, Dc]&lt;/li&gt;
  &lt;li&gt;DST_ATOP 	[Sa, Sa * Dc + Sc * (1 - Da)]&lt;/li&gt;
  &lt;li&gt;DST_IN 	[Sa * Da, Sa * Dc]&lt;/li&gt;
  &lt;li&gt;DST_OUT 	[Da * (1 - Sa), Dc * (1 - Sa)]&lt;/li&gt;
  &lt;li&gt;DST_OVER 	[Sa + (1 - Sa)&lt;em&gt;Da, Rc = Dc + (1 - Da)&lt;/em&gt;Sc]&lt;/li&gt;
  &lt;li&gt;LIGHTEN 	[Sa + Da - Sa&lt;em&gt;Da, Sc&lt;/em&gt;(1 - Da) + Dc*(1 - Sa) + max(Sc, Dc)]&lt;/li&gt;
  &lt;li&gt;MULTIPLY 	[Sa * Da, Sc * Dc]&lt;/li&gt;
  &lt;li&gt;OVERLAY&lt;/li&gt;
  &lt;li&gt;SCREEN 	[Sa + Da - Sa * Da, Sc + Dc - Sc * Dc]&lt;/li&gt;
  &lt;li&gt;SRC 	[Sa, Sc]&lt;/li&gt;
  &lt;li&gt;SRC_ATOP 	[Da, Sc * Da + (1 - Sa) * Dc]&lt;/li&gt;
  &lt;li&gt;SRC_IN 	[Sa * Da, Sc * Da]&lt;/li&gt;
  &lt;li&gt;SRC_OUT 	[Sa * (1 - Da), Sc * (1 - Da)]&lt;/li&gt;
  &lt;li&gt;SRC_OVER 	[Sa + (1 - Sa)&lt;em&gt;Da, Rc = Sc + (1 - Sa)&lt;/em&gt;Dc]&lt;/li&gt;
  &lt;li&gt;XOR 	[Sa + Da - 2 * Sa * Da, Sc * (1 - Da) + (1 - Sa) * Dc]&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Crystal clear! Hopefully the &lt;a href=&quot;http://gitorious.org/freebroid/development/blobs/62e92d7a2a3fd2798901ec2e7c452ff0e4067163/samples/ApiDemos/src/com/example/android/apis/graphics/Xfermodes.java&quot;&gt;Xfermodes example&lt;/a&gt; in the API Demos demonstrates what the different modes do:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/static/blog_img/porter-duff.png&quot; alt=&quot;Porter-Duff&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;yellow&lt;/strong&gt; circle is the &lt;strong&gt;destination&lt;/strong&gt; bitmap and the &lt;strong&gt;blue&lt;/strong&gt; rectangle is the &lt;strong&gt;source&lt;/strong&gt; bitmap. The destination is drawn normally, then the source is drawn on top of that using the given Porter-Duff mode.&lt;/p&gt;

&lt;p&gt;To apply the &lt;strong&gt;alpha mask&lt;/strong&gt;, we will therefore use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DST_IN&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;applying-the-mask&quot;&gt;&lt;a id=&quot;ApplyingTheMask&quot; href=&quot;#ApplyingTheMask&quot;&gt;Applying the mask&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;Let’s say we have a nice JPEG:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/static/blog_img/golden_gate.jpg&quot; alt=&quot;Golden Gate&quot; /&gt;&lt;/p&gt;

&lt;p&gt;And a PNG that we want to use as a mask:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/static/blog_img/troll_face.png&quot; alt=&quot;Troll Face&quot; /&gt;&lt;/p&gt;

&lt;p&gt;First, we load the bitmap:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;&lt;span class=&quot;nc&quot;&gt;BitmapFactory&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;Options&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;options&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;BitmapFactory&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;Options&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Build&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;VERSION&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;SDK_INT&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Build&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;VERSION_CODES&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;HONEYCOMB&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;// Starting with Honeycomb, we can load the bitmap as mutable.&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;options&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;inMutable&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// We could also use ARGB_4444, but not RGB_565 (we need an alpha layer).&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;options&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;inPreferredConfig&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Bitmap&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;Config&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;ARGB_8888&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;Resources&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;res&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;getResources&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;Bitmap&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;source&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;BitmapFactory&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;decodeResource&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;res&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;R&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;drawable&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;golden_gate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;options&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;Bitmap&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bitmap&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;source&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;isMutable&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;())&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;bitmap&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;source&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;bitmap&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;source&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;copy&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Bitmap&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;Config&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;ARGB_8888&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;source&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;recycle&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// The bitmap is opaque, we need to enable alpha compositing.&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;bitmap&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;setHasAlpha&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Next we draw the mask on the bitmap with a canvas, using the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DST_IN&lt;/code&gt; Porter-Duff mode:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;&lt;span class=&quot;nc&quot;&gt;Canvas&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;canvas&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Canvas&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bitmap&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;Bitmap&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mask&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;BitmapFactory&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;decodeResource&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;res&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;R&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;drawable&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;troll_face&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;Paint&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;paint&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Paint&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;paint&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;setXfermode&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;PorterDuffXfermode&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;PorterDuff&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;Mode&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;DST_IN&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;canvas&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;drawBitmap&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mask&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;paint&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// We do not need the mask bitmap anymore.&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;mask&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;recycle&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Finally we just use the bitmap:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;&lt;span class=&quot;nc&quot;&gt;ImageView&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;trollFace&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;ImageView&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;findViewById&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;R&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;troll_face&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;trollFace&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;setImageBitmap&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bitmap&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;result&quot;&gt;&lt;a id=&quot;Result&quot; href=&quot;#Result&quot;&gt;Result&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;There you go, Troll Face Golden Gate!
&lt;img src=&quot;/static/blog_img/troll_face_screenshot.png&quot; alt=&quot;Troll Face&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Here is a helper method to do this all at once:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Bitmap&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;getMaskedBitmap&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Resources&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;res&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sourceResId&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;maskResId&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nc&quot;&gt;BitmapFactory&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;Options&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;options&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;BitmapFactory&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;Options&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Build&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;VERSION&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;SDK_INT&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Build&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;VERSION_CODES&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;HONEYCOMB&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;options&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;inMutable&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;options&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;inPreferredConfig&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Bitmap&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;Config&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;ARGB_8888&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;nc&quot;&gt;Bitmap&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;source&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;BitmapFactory&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;decodeResource&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;res&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sourceResId&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;options&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;nc&quot;&gt;Bitmap&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bitmap&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;source&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;isMutable&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;())&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;bitmap&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;source&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;bitmap&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;source&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;copy&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Bitmap&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;Config&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;ARGB_8888&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;source&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;recycle&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;bitmap&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;setHasAlpha&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;nc&quot;&gt;Canvas&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;canvas&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Canvas&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bitmap&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;nc&quot;&gt;Bitmap&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mask&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;BitmapFactory&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;decodeResource&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;res&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;maskResId&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;nc&quot;&gt;Paint&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;paint&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Paint&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;paint&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;setXfermode&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;PorterDuffXfermode&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;PorterDuff&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;Mode&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;DST_IN&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;canvas&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;drawBitmap&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mask&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;paint&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;mask&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;recycle&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bitmap&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;update&quot;&gt;&lt;a id=&quot;Update&quot; href=&quot;#Update&quot;&gt;Update&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;If you want to understand Porter-Duff blending modes in details, you should read this great article: &lt;a href=&quot;http://ssp.impulsetrain.com/2013/03/17/porterduff-compositing-and-blend-modes/&quot;&gt;Porter/Duff Compositing and Blend Modes&lt;/a&gt; (special thanks to &lt;a href=&quot;http://cyrilmottier.com/&quot;&gt;Cyril Mottier&lt;/a&gt; for the link).&lt;/p&gt;

&lt;h1 id=&quot;comments&quot;&gt;Comments&lt;/h1&gt;

&lt;!--

To comment, copy and paste the following block

## [Nickname](http://website)
Comment

--&gt;

&lt;h2 id=&quot;dreamingindroids&quot;&gt;&lt;a href=&quot;http://www.google.com&quot;&gt;DreamingInDroids&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Brilliant! Thanks for the pictures demonstrating the different Porter-Duff modes! I had been wondering about them for a long time!&lt;/p&gt;

&lt;h2 id=&quot;casey&quot;&gt;&lt;a href=&quot;http://www.google.com&quot;&gt;Casey&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Very useful! I’m writing a children’s puzzle app and this is a quick and easy way to create a base (ie. a square with the puzzle shape cut out of it) for the puzzle with an interesting texture. Thanks =)&lt;/p&gt;
</content>
 </entry>
 
 
 
 <entry>
   <title>Chathead Basics</title>
   <link href="http://www.piwai.info/chatheads-basics"/>
   <updated>2013-04-14T00:00:00+00:00</updated>
   <id>http://www.piwai.info/chatheads-basics</id>
   <content type="html">&lt;p&gt;Facebook recently released a new feature in Facebook Messenger: &lt;a href=&quot;http://www.engadget.com/2013/04/12/facebook-messenger-updated/&quot;&gt;Chatheads&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/static/blog_img/sheldon_chathead.png&quot; alt=&quot;Sheldon Chathead&quot; /&gt;&lt;/p&gt;

&lt;p&gt;I was surprised that chatheads could be drawn on top of any app. Here is a quick explanation of how it works.&lt;/p&gt;

&lt;h2 id=&quot;no-activity&quot;&gt;&lt;a id=&quot;NoActivity&quot; href=&quot;#NoActivity&quot;&gt;No Activity?&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;At first you may think it’s a trick with a transparent activity. Let’s see:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;adb shell dumpsys activity
Running activities &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;most recent first&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;:
  TaskRecord&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;42b03c38 &lt;span class=&quot;c&quot;&gt;#2 A com.android.launcher U 0}&lt;/span&gt;
    Run &lt;span class=&quot;c&quot;&gt;#0: ActivityRecord{42adf3f8 u0 com.android.launcher/com.android.launcher2.Launcher}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;No activity! And that’s because Messenger uses a service:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;adb shell dumpsys activity services
ACTIVITY MANAGER SERVICES &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;dumpsys activity services&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt; ServiceRecord&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;43242ae0 u0 com.facebook.orca/.chatheads.ChatHeadService&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;nv&quot;&gt;intent&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;={&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;act&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;com.facebook.orca.chatheads.ACTION_HIDE_CHATHEADS &lt;span class=&quot;nv&quot;&gt;cmp&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;com.facebook.orca/.chatheads.ChatHeadService&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;nv&quot;&gt;packageName&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;com.facebook.orca
  &lt;span class=&quot;nv&quot;&gt;processName&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;com.facebook.orca
  &lt;span class=&quot;nv&quot;&gt;baseDir&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;/data/app/com.facebook.orca-1.apk
  &lt;span class=&quot;nv&quot;&gt;dataDir&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;/data/data/com.facebook.orca
  &lt;span class=&quot;nv&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;ProcessRecord&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;42a11228 32622:com.facebook.orca/u0a10126&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;nv&quot;&gt;createTime&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-9m19s542ms&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;lastActivity&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-3m20s499ms&lt;/span&gt;
  &lt;span class=&quot;nv&quot;&gt;executingStart&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-3m20s499ms&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;restartTime&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-9m19s542ms&lt;/span&gt;
  &lt;span class=&quot;nv&quot;&gt;startRequested&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;true &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;stopIfKilled&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;false &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;callStart&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;true &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;lastStartId&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;65&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;principle&quot;&gt;&lt;a id=&quot;Principle&quot; href=&quot;#Principle&quot;&gt;Principle&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;It’s simple: just add a view to a &lt;a href=&quot;http://developer.android.com/reference/android/view/Window.html&quot;&gt;Window&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;As you probably know, an Activity has a Window instance. Dialogs also have their own dedicated Window. Even Services can have Window: &lt;a href=&quot;http://developer.android.com/reference/android/inputmethodservice/InputMethodService.html&quot;&gt;InputMethodService&lt;/a&gt; uses a Window to receive touch events and draw a keyboard on top of another Window, and &lt;a href=&quot;http://developer.android.com/reference/android/service/dreams/DreamService.html&quot;&gt;DreamService&lt;/a&gt; is used to create screensavers.&lt;/p&gt;

&lt;h2 id=&quot;permission&quot;&gt;&lt;a id=&quot;Permission&quot; href=&quot;#Permission&quot;&gt;Permission&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;To open a new window in which you will draw the chathead, you need the &lt;a href=&quot;http://developer.android.com/reference/android/Manifest.permission.html#SYSTEM_ALERT_WINDOW&quot;&gt;SYSTEM_ALERT_WINDOW&lt;/a&gt; permission.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Allows an application to open windows using the type TYPE_SYSTEM_ALERT, shown on top of all other applications. Very few applications should use this permission; these windows are intended for system-level interaction with the user.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-xml&quot; data-lang=&quot;xml&quot;&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;uses-permission&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;android:name=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;android.permission.SYSTEM_ALERT_WINDOW&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This is what your users will see when installing the app:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/static/blog_img/draw_permission.png&quot; alt=&quot;Draw Permission&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;android-head&quot;&gt;&lt;a id=&quot;AndroidHead&quot; href=&quot;#AndroidHead&quot;&gt;Android Head&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;Now that you have the right permission, you just need to call &lt;a href=&quot;http://developer.android.com/reference/android/view/ViewManager.html#addView(android.view.View, android.view.ViewGroup.LayoutParams)&quot;&gt;WindowManager#addView()&lt;/a&gt; with the view and the corresponding layout params:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ChatHeadService&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Service&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;

  &lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;WindowManager&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;windowManager&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ImageView&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;chatHead&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;nd&quot;&gt;@Override&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;IBinder&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;onBind&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Intent&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;intent&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// Not used&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;nd&quot;&gt;@Override&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;onCreate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;super&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;onCreate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;windowManager&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;WindowManager&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;getSystemService&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;WINDOW_SERVICE&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;chatHead&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ImageView&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;chatHead&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;setImageResource&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;R&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;drawable&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;android_head&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;nc&quot;&gt;WindowManager&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;LayoutParams&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;params&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;WindowManager&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;LayoutParams&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;nc&quot;&gt;WindowManager&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;LayoutParams&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;WRAP_CONTENT&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;nc&quot;&gt;WindowManager&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;LayoutParams&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;WRAP_CONTENT&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;nc&quot;&gt;WindowManager&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;LayoutParams&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;TYPE_PHONE&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;nc&quot;&gt;WindowManager&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;LayoutParams&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;FLAG_NOT_FOCUSABLE&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;nc&quot;&gt;PixelFormat&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;TRANSLUCENT&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;gravity&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Gravity&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;TOP&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Gravity&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;LEFT&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;y&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;windowManager&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;addView&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;chatHead&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;nd&quot;&gt;@Override&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;onDestroy&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;super&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;onDestroy&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;chatHead&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;windowManager&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;removeView&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;chatHead&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Don’t forget to start the service somehow:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;&lt;span class=&quot;n&quot;&gt;startService&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Intent&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;context&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ChatHeadService&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;&lt;img src=&quot;/static/blog_img/chathead_android.png&quot; alt=&quot;Chathead Android&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;drag-the-head&quot;&gt;&lt;a id=&quot;draghead&quot; href=&quot;#draghead&quot;&gt;Drag the head&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;You can now interact with the view. For example, here is a &lt;strong&gt;quick hack&lt;/strong&gt; to drag the Android head around:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;&lt;span class=&quot;n&quot;&gt;chatHead&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;setOnTouchListener&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;View&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;OnTouchListener&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;initialX&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;initialY&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;float&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;initialTouchX&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;float&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;initialTouchY&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;nd&quot;&gt;@Override&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;boolean&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;onTouch&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;View&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MotionEvent&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;switch&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getAction&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;())&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MotionEvent&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;ACTION_DOWN&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;initialX&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;initialY&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;initialTouchX&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getRawX&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;initialTouchY&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getRawY&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MotionEvent&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;ACTION_UP&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MotionEvent&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;ACTION_MOVE&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;initialX&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getRawX&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;initialTouchX&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;y&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;initialY&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getRawY&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;initialTouchY&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;windowManager&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;updateViewLayout&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;chatHead&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;});&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;&lt;a id=&quot;Conclusion&quot; href=&quot;#Conclusion&quot;&gt;Conclusion&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;Prior to Facebook Chatheads, this trick was already used by some apps. A few examples:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Display a side &lt;a href=&quot;https://play.google.com/store/apps/details?id=com.schiztech.swapps&quot;&gt;app launcher&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Take &lt;a href=&quot;https://play.google.com/store/apps/details?id=com.liveov.shotux&quot;&gt;screenshots&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Draw &lt;a href=&quot;https://play.google.com/store/apps/details?id=com.ntkachov.penandpaper&quot;&gt;notes over apps&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Reduce the &lt;a href=&quot;https://play.google.com/store/apps/details?id=pt.bbarao.nightmode&quot;&gt;screen brightness&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This feature is nice, but remember that &lt;em&gt;with great power comes great responsibility&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Please take care of your user pixels.&lt;/p&gt;

&lt;h1 id=&quot;comments&quot;&gt;Comments&lt;/h1&gt;

&lt;h2 id=&quot;hidden-markov&quot;&gt;hidden-markov&lt;/h2&gt;
&lt;p&gt;Does this imply that Facebook Chatheads (or any application with SYSTEM_ALERT_WINDOW permission) is able to conduct keylogging and take screenshots at arbitrary time?&lt;/p&gt;

&lt;h2 id=&quot;kvgr&quot;&gt;kvgr&lt;/h2&gt;
&lt;p&gt;Great tutorial!
Is there a way to display image only in launcher? When some activity is started, the icon should disapear.
I thing there may be two ways:&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;parameter for WindowManager&lt;/li&gt;
  &lt;li&gt;detecting running app
But I wasnt lucky to find the solution…&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;pickledolives&quot;&gt;pickledolives&lt;/h2&gt;
&lt;p&gt;Your tutorial is missing the point, that you need to register your service in the Android manifest file under the application tab.&lt;/p&gt;

&lt;!--

To comment, copy and paste the following block

## [Nickname](http://website)
Comment

--&gt;
</content>
 </entry>
 
 
 
 <entry>
   <title>Android String Placeholders</title>
   <link href="http://www.piwai.info/android-string-placeholders"/>
   <updated>2013-01-10T00:00:00+00:00</updated>
   <id>http://www.piwai.info/android-string-placeholders</id>
   <content type="html">&lt;p&gt;This article reviews different ways to create dynamic translatable strings in Android.&lt;/p&gt;

&lt;h2 id=&quot;quick-reminder&quot;&gt;&lt;a id=&quot;Quick-reminder&quot; href=&quot;#Quick-reminder&quot;&gt;Quick reminder&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;In Android, message strings are extracted to XML files, and the system loads the resources corresponding to the current configuration.&lt;/p&gt;

&lt;p&gt;&lt;span class=&quot;label label-info&quot;&gt;res/values/strings.xml&lt;/span&gt;&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-xml&quot; data-lang=&quot;xml&quot;&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;resources&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;string&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;sexy_button_title&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;Click me, I'm famous!&lt;span class=&quot;nt&quot;&gt;&amp;lt;/string&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/resources&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;&lt;span class=&quot;label label-info&quot;&gt;res/values-fr/strings.xml&lt;/span&gt;&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-xml&quot; data-lang=&quot;xml&quot;&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;resources&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;string&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;sexy_button_title&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;Cliquez-moi, parce que je le vaux bien !&lt;span class=&quot;nt&quot;&gt;&amp;lt;/string&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/resources&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;&lt;span class=&quot;nc&quot;&gt;Resources&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;resources&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;context&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getResources&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sexyButtonTitle&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;resources&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getString&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;R&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;sexy_button_title&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;formatting-strings&quot;&gt;&lt;a id=&quot;Formatting-strings&quot; href=&quot;#Formatting-strings&quot;&gt;Formatting strings&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;Let’s say we want to display a dynamic string, such as &lt;em&gt;Player &lt;strong&gt;Foo&lt;/strong&gt; - Score: &lt;strong&gt;42&lt;/strong&gt;&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;We may be tempted to implement that quickly with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;String.format()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;span class=&quot;label label-important&quot;&gt;Wrong&lt;/span&gt;&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-xml&quot; data-lang=&quot;xml&quot;&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;string&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;score_format&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;Player %s - Score: %d&lt;span class=&quot;nt&quot;&gt;&amp;lt;/string&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;&lt;span class=&quot;nc&quot;&gt;Resources&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;resources&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;context&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getResources&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;scoreString&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;resources&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getString&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;R&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;score_format&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;player&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;score&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;You will get a compile time error message on the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt;string /&amp;gt;&lt;/code&gt; definition.&lt;/p&gt;

&lt;div class=&quot;alert alert-error&quot;&gt;
&lt;h4 class=&quot;alert-heading&quot;&gt;Error&lt;/h4&gt;
&lt;p&gt;Multiple substitutions specified in non-positional format; did you mean to add the formatted=&quot;false&quot; attribute?&lt;/p&gt;
&lt;/div&gt;

&lt;p&gt;This error message is misleading, because one may believe that using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;formatted=&quot;false&quot;&lt;/code&gt; is the way to go.&lt;/p&gt;

&lt;p&gt;&lt;span class=&quot;label label-important&quot;&gt;Still Wrong&lt;/span&gt;&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-xml&quot; data-lang=&quot;xml&quot;&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;string&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;score_format&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;formatted=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;false&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;Player %s - Score: %d&lt;span class=&quot;nt&quot;&gt;&amp;lt;/string&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Although the error message now disappears, the real solution is to use a positional format.&lt;/p&gt;

&lt;p&gt;&lt;span class=&quot;label label-success&quot;&gt;Right&lt;/span&gt;&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-xml&quot; data-lang=&quot;xml&quot;&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;string&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;score_format&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;Player %1$s - Score: %2$d&lt;span class=&quot;nt&quot;&gt;&amp;lt;/string&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;When translating strings, the word order will change.
For instance, &lt;em&gt;Name: &lt;strong&gt;John Smith&lt;/strong&gt;&lt;/em&gt; in English becomes &lt;em&gt;Nom : &lt;strong&gt;Smith John&lt;/strong&gt;&lt;/em&gt; in French.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;&lt;span class=&quot;nc&quot;&gt;Resources&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;resources&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;context&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getResources&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;scoreString&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;resources&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getString&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;R&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;firstname&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;lastname&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;&lt;span class=&quot;label label-info&quot;&gt;res/values/strings.xml&lt;/span&gt;&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-xml&quot; data-lang=&quot;xml&quot;&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;resources&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;string&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;name&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;Name: %1$s %2$s&lt;span class=&quot;nt&quot;&gt;&amp;lt;/string&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/resources&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;&lt;span class=&quot;label label-info&quot;&gt;res/values-fr/strings.xml&lt;/span&gt;&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-xml&quot; data-lang=&quot;xml&quot;&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;resources&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;string&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;name&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;Nom : %2$s %1$s&lt;span class=&quot;nt&quot;&gt;&amp;lt;/string&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/resources&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Using positional format prevents translation mistakes.&lt;/p&gt;

&lt;h2 id=&quot;getstring&quot;&gt;&lt;a id=&quot;getString&quot; href=&quot;#getString&quot;&gt;getString()&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;Did you know that instead of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;String.format()&lt;/code&gt;, you can use an overloaded version of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;getString()&lt;/code&gt; that handles formatting?&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;&lt;span class=&quot;nc&quot;&gt;Resources&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;resources&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;context&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getResources&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;scoreString&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;resources&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getString&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;R&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;score_format&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;player&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;score&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Is that stricly equivalent to the previous code? Let’s look at the Android source!&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Resources&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// …&lt;/span&gt;

    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;getString&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Object&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;...&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;formatArgs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;throws&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;NotFoundException&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;raw&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;getString&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mConfiguration&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;locale&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;raw&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;formatArgs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Almost the same, except that we are using the resource configuration locale, whereas we were previously using the default locale.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;final&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;implements&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Serializable&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Comparable&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;CharSequence&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// …&lt;/span&gt;

    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Object&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;...&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Locale&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getDefault&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Locale.getDefault()&lt;/code&gt; is usually equal to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mConfiguration.locale&lt;/code&gt;, so this won’t really be a problem until you start messing with the default locale.&lt;/p&gt;

&lt;p&gt;By the way, you probably know that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;getString()&lt;/code&gt; is also available on &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Context&lt;/code&gt;.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;scoreString&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;context&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getString&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;R&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;score_format&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;player&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;score&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;What’s the difference? None. It just delegates to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Resources&lt;/code&gt;.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;abstract&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Context&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// …&lt;/span&gt;

    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;final&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;getString&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;resId&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Object&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;...&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;formatArgs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;getResources&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getString&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;resId&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;formatArgs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;blockquote&gt;
  &lt;p&gt;If someone knows the story behind this weird shortcut method, let me know. For now, I’ll just assume this is a consequence of &lt;strong&gt;D&lt;/strong&gt;runk &lt;strong&gt;D&lt;/strong&gt;riven &lt;strong&gt;D&lt;/strong&gt;evelopment.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2 id=&quot;professional-translation&quot;&gt;&lt;a id=&quot;Professional-Translation&quot; href=&quot;#Professional-Translation&quot;&gt;Professional Translation&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;Your users deserve better than &lt;em&gt;Google translate&lt;/em&gt;. XML resource files should be translated by a professional translator.&lt;/p&gt;

&lt;p&gt;This translator will know nothing about your app internals. Therefore, it may be really hard to find out what those &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;%1$s&lt;/code&gt; cryptic signs mean.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-xml&quot; data-lang=&quot;xml&quot;&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;string&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;score_format&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;Player %1$s - Score: %2$d&lt;span class=&quot;nt&quot;&gt;&amp;lt;/string&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;You can use comments to help the translator.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-xml&quot; data-lang=&quot;xml&quot;&gt;&lt;span class=&quot;c&quot;&gt;&amp;lt;!-- %1$s is the player nickname and %2$d is the player score --&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;string&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;score_format&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;Player %1$s - Score: %2$d&lt;span class=&quot;nt&quot;&gt;&amp;lt;/string&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;blockquote&gt;
  &lt;p&gt;By the way, if you need excellent quality software translation, I know someone that’s been &lt;a href=&quot;http://rtsi.fr/&quot;&gt;translating software&lt;/a&gt; for more than 25 years. Yes, he is my father :) .&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2 id=&quot;using-placeholders&quot;&gt;&lt;a id=&quot;Using-placeholders&quot; href=&quot;#Using-placeholders&quot;&gt;Using placeholders&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;Another interesting approach is to use named placeholders instead of format specifiers.&lt;/p&gt;

&lt;p&gt;I won’t discuss which syntax is better for this kind of problem, let’s just pick a simple one: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;{placeholder}&lt;/code&gt;.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-xml&quot; data-lang=&quot;xml&quot;&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;string&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;score_format&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;Player {nickname} - Score: {score}&lt;span class=&quot;nt&quot;&gt;&amp;lt;/string&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;I find this much more readable! Now, you’ll need an API to transform that format to the final string.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;&lt;span class=&quot;nc&quot;&gt;TagFormat&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;scoreFormat&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;TagFormat&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;getString&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;R&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;score_format&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;scoreFormat&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;with&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;nickname&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;player&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;scoreFormat&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;with&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;score&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;score&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;scoreString&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;scoreFormat&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Implementing this API is fairly straightforward.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;TagFormat&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;

	&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;TagFormat&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;TagFormat&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
	&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

	&lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;final&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;final&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Map&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Object&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tags&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;LinkedHashMap&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Object&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;();&lt;/span&gt;

	&lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;TagFormat&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;format&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

	&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;TagFormat&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;with&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Object&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;tags&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;put&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;\\{&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;key&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;\\}&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

	&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;formatted&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Entry&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Object&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tag&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tags&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;entrySet&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;())&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
			&lt;span class=&quot;c1&quot;&gt;// bottleneck, creating temporary String objects!&lt;/span&gt;
			&lt;span class=&quot;n&quot;&gt;formatted&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;formatted&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;replaceAll&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tag&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getKey&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tag&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getValue&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;toString&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;());&lt;/span&gt;
		&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;formatted&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This is just an example implementation, I’ll leave a better one to you as an exercice. An interesting point here is that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;with()&lt;/code&gt; returns &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;this&lt;/code&gt;, so you can use it as a fluid API.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;scoreString&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;TagFormat&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;getString&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;R&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;score_format&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;))&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;with&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;nickname&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;player&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;with&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;score&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;score&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;&lt;a id=&quot;Conclusion&quot; href=&quot;#Conclusion&quot;&gt;Conclusion&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;I shamelessly stole this &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;{placeholder}&lt;/code&gt; idea from &lt;a href=&quot;https://twitter.com/burke_eric&quot;&gt;Eric Burke&lt;/a&gt;, and thought it was worth sharing.&lt;/p&gt;

&lt;p&gt;Of course, you may already use Java libraries that can do this. If you are aware of a good one that does a decent job, let me know!&lt;/p&gt;

&lt;h1 id=&quot;comments&quot;&gt;Comments&lt;/h1&gt;

&lt;!--

To comment, copy and paste the following block

## [Nickname](http://website)
Comment

--&gt;
</content>
 </entry>
 
 
 
 <entry>
   <title>Android Adapter Good Practices</title>
   <link href="http://www.piwai.info/android-adapter-good-practices"/>
   <updated>2012-12-27T00:00:00+00:00</updated>
   <id>http://www.piwai.info/android-adapter-good-practices</id>
   <content type="html">&lt;p&gt;In Android, the standard way to display a list of items is to use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ListView&lt;/code&gt; together with a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ListAdapter&lt;/code&gt;. The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ListView&lt;/code&gt; draws the currently shown items, and the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ListAdapter&lt;/code&gt; provides the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ListView&lt;/code&gt; with the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;View&lt;/code&gt; corresponding to each item.&lt;/p&gt;

&lt;p&gt;The aim is to create only the necessary number of views to fill the screen, and reuse these views as soon as they disappear.&lt;/p&gt;

&lt;p&gt;This article will explain various &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ListAdapter&lt;/code&gt; patterns and good practices.&lt;/p&gt;

&lt;h2 id=&quot;arrayadapter-sucks&quot;&gt;&lt;a id=&quot;ArrayAdapter-sucks&quot; href=&quot;#ArrayAdapter-sucks&quot;&gt;ArrayAdapter sucks&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;Let’s say you want to display a list of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;BananaPhone&lt;/code&gt; that can be updated.&lt;/p&gt;

&lt;p&gt;Some Android tutorials advise using an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ArrayAdapter&lt;/code&gt;, because it is supposedly easier. &lt;strong&gt;This couldn’t be any less true&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ArrayAdapter&lt;/code&gt; has many limitations, which limits its use in real world apps.&lt;/p&gt;

&lt;p&gt;An &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ArrayAdapter&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Can only display text.&lt;/li&gt;
  &lt;li&gt;Forces you to provide a list of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CharSequence&lt;/code&gt; items or to rely on the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;toString()&lt;/code&gt; method of the given items.&lt;/li&gt;
  &lt;li&gt;Requires that you provide a layout resource that contains only a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TextView&lt;/code&gt;, or that you provide a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;textViewResourceId&lt;/code&gt; that corresponds to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TextView&lt;/code&gt; id in the layout hierarchy.&lt;/li&gt;
  &lt;li&gt;Uses a lock to enable updates from background threads. This lock cannot be acquired to implement external atomic operations.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;According to the Javadoc:&lt;/p&gt;

&lt;p&gt;&lt;span class=&quot;label label-important&quot;&gt;Don’t do this!&lt;/span&gt;&lt;/p&gt;
&lt;blockquote&gt;
  &lt;p&gt;To use something other than TextViews for the array display, for instance, ImageViews, or to have some of data besides toString() results fill the views, override getView(int,android.view.View,android.view.ViewGroup) to return the type of view you want.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If you &lt;a href=&quot;http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/4.1.1_r1/android/widget/ArrayAdapter.java&quot;&gt;read the source&lt;/a&gt;, you’ll realize that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ArrayAdapter&lt;/code&gt; is designed to deal with a lot of use cases which you probably do not care about.&lt;/p&gt;

&lt;h2 id=&quot;baseadapter-rocks&quot;&gt;&lt;a id=&quot;BaseAdapter-rocks&quot; href=&quot;#BaseAdapter-rocks&quot;&gt;BaseAdapter rocks&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;In most apps, it’s actually a lot simpler to implement your own &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;BaseAdapter&lt;/code&gt;:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;BananaPhoneAdapter&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;BaseAdapter&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;

	&lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;BananaPhone&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bananaPhones&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Collections&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;emptyList&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;

	&lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;final&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Context&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;context&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;

	&lt;span class=&quot;c1&quot;&gt;// the context is needed to inflate views in getView()&lt;/span&gt;
	&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;BananaPhoneAdapter&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Context&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;context&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;context&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;context&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

	&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;updateBananas&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;BananaPhone&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bananaPhones&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;bananaPhones&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bananaPhones&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;notifyDataSetChanged&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
	&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

	&lt;span class=&quot;nd&quot;&gt;@Override&lt;/span&gt;
	&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;getCount&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bananaPhones&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
	&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

	&lt;span class=&quot;c1&quot;&gt;// getItem(int) in Adapter returns Object but we can override&lt;/span&gt;
	&lt;span class=&quot;c1&quot;&gt;// it to BananaPhone thanks to Java return type covariance&lt;/span&gt;
	&lt;span class=&quot;nd&quot;&gt;@Override&lt;/span&gt;
	&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;BananaPhone&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;getItem&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;position&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bananaPhones&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;position&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
	&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

	&lt;span class=&quot;c1&quot;&gt;// getItemId() is often useless, I think this should be the default&lt;/span&gt;
	&lt;span class=&quot;c1&quot;&gt;// implementation in BaseAdapter&lt;/span&gt;
	&lt;span class=&quot;nd&quot;&gt;@Override&lt;/span&gt;
	&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;long&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;getItemId&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;position&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;position&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

	&lt;span class=&quot;nd&quot;&gt;@Override&lt;/span&gt;
	&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;View&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;getView&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;position&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;View&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;convertView&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ViewGroup&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parent&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;c1&quot;&gt;// Let's look at that later&lt;/span&gt;
	&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;thread-safety&quot;&gt;&lt;a id=&quot;Thread-safety&quot; href=&quot;#Thread-safety&quot;&gt;Thread safety&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;I mentioned that the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ArrayAdapter&lt;/code&gt; uses a lock to ensure thread safety. That’s fine, but there is an even better way: &lt;strong&gt;get rid of threading&lt;/strong&gt;. Make sure your adapter is used only from one thread, the Main thread.&lt;/p&gt;

&lt;p&gt;You can easily enforce that with a fail fast strategy:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;updateBananas&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;BananaPhone&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bananaPhones&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;nc&quot;&gt;ThreadPreconditions&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;checkOnMainThread&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;bananaPhones&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bananaPhones&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;notifyDataSetChanged&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Here is an example implementation:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ThreadPreconditions&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;checkOnMainThread&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;BuildConfig&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;DEBUG&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
			&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Thread&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;currentThread&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Looper&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getMainLooper&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getThread&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;())&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
				&lt;span class=&quot;k&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;IllegalStateException&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;This method should be called from the Main Thread&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
			&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
		&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
	&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;getview-recycling&quot;&gt;&lt;a id=&quot;getView-recycling&quot; href=&quot;#getView-recycling&quot;&gt;getView() recycling&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;A naive implementation of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;getView()&lt;/code&gt; could be:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;&lt;span class=&quot;nd&quot;&gt;@Override&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;View&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;getView&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;position&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;View&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;convertView&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ViewGroup&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parent&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;

	&lt;span class=&quot;nc&quot;&gt;View&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rootView&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;LayoutInflater&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;context&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
	  &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;inflate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;R&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;layout&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;banana_phone&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parent&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;

	&lt;span class=&quot;nc&quot;&gt;ImageView&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bananaView&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;ImageView&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rootView&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;findViewById&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;R&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;banana&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
	&lt;span class=&quot;nc&quot;&gt;TextView&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;phoneView&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;TextView&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rootView&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;findViewById&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;R&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;phone&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;

	&lt;span class=&quot;nc&quot;&gt;BananaPhone&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bananaPhone&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;getItem&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;position&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;phoneView&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;setText&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bananaPhone&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getPhone&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;());&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;bananaView&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;setImageResource&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bananaPhone&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getBanana&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;());&lt;/span&gt;

	&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rootView&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;However, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ListView&lt;/code&gt; recycles the views that are not shown any more, and gives them back through &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;convertView&lt;/code&gt;. Let’s take advantage of this:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;&lt;span class=&quot;nd&quot;&gt;@Override&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;View&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;getView&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;position&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;View&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;convertView&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ViewGroup&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parent&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;

	&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;convertView&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;convertView&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;LayoutInflater&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;context&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
		  &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;inflate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;R&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;layout&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;banana_phone&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parent&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
	&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

	&lt;span class=&quot;nc&quot;&gt;ImageView&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bananaView&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;ImageView&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;convertView&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;findViewById&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;R&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;banana&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
	&lt;span class=&quot;nc&quot;&gt;TextView&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;phoneView&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;TextView&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;convertView&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;findViewById&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;R&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;phone&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;

	&lt;span class=&quot;nc&quot;&gt;BananaPhone&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bananaPhone&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;getItem&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;position&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;phoneView&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;setText&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bananaPhone&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getPhone&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;());&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;bananaView&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;setImageResource&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bananaPhone&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getBanana&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;());&lt;/span&gt;

	&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;convertView&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;findviewbyid-mi-amor&quot;&gt;&lt;a id=&quot;findViewById-mi-amor&quot; href=&quot;#findViewById-mi-amor&quot;&gt;findViewById() mi amor&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;There is still one subtle problem with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;getView()&lt;/code&gt;: each time it is called, it retrieves &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bananaView&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;phoneView&lt;/code&gt; through &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;findViewById()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;How does &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;findViewById()&lt;/code&gt; work exactly ? Here is a simplified version:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;View&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;findViewById&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;id&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;View&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;child&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;children&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;nc&quot;&gt;View&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;view&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;child&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;findViewById&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;view&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
			&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;view&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
		&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
	&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;As you can see, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;findViewById()&lt;/code&gt; navigates through the whole view hierarchy until it finds the requested view, each time you call it.&lt;/p&gt;

&lt;p&gt;Whether or not this is a problem is up to you. If your &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ListView&lt;/code&gt; scrolls fine even on crap devices, don’t bother optimizing. Otherwise, start &lt;a href=&quot;http://developer.android.com/tools/help/traceview.html&quot;&gt;traceview&lt;/a&gt; and measure how much time is spent in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;findViewById()&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;viewholder-pattern&quot;&gt;&lt;a id=&quot;ViewHolder-Pattern&quot; href=&quot;#ViewHolder-Pattern&quot;&gt;ViewHolder Pattern&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;The &lt;strong&gt;ViewHolder Pattern&lt;/strong&gt; is a well known pattern to limit the number of calls to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;findViewById()&lt;/code&gt;. The idea is that you call it once, then store the child view references in a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ViewHolder&lt;/code&gt; instance that will be associated with the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;convertView&lt;/code&gt; thanks to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;View.setTag()&lt;/code&gt;.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;&lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ViewHolder&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;final&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ImageView&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bananaView&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;final&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;TextView&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;phoneView&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;

	&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;ViewHolder&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;ImageView&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bananaView&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;TextView&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;phoneView&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;bananaView&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bananaView&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;phoneView&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;phoneView&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;nd&quot;&gt;@Override&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;View&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;getView&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;position&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;View&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;convertView&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ViewGroup&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parent&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;

	&lt;span class=&quot;nc&quot;&gt;ImageView&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bananaView&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;nc&quot;&gt;TextView&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;phoneView&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;convertView&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;convertView&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;LayoutInflater&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;context&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
		  &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;inflate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;R&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;layout&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;banana_phone&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parent&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;bananaView&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;ImageView&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;convertView&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;findViewById&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;R&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;banana&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;phoneView&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;TextView&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;convertView&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;findViewById&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;R&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;phone&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;convertView&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;setTag&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ViewHolder&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bananaView&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;phoneView&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;
	&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;nc&quot;&gt;ViewHolder&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;viewHolder&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;ViewHolder&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;convertView&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getTag&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;bananaView&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;viewHolder&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;bananaView&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;phoneView&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;viewHolder&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;phoneView&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

	&lt;span class=&quot;nc&quot;&gt;BananaPhone&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bananaPhone&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;getItem&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;position&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;phoneView&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;setText&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bananaPhone&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getPhone&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;());&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;bananaView&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;setImageResource&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bananaPhone&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getBanana&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;());&lt;/span&gt;

	&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;convertView&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;tag-with-id&quot;&gt;&lt;a id=&quot;Tag-with-id&quot; href=&quot;#Tag-with-id&quot;&gt;Tag with id&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;Here is an alternative to the &lt;strong&gt;ViewHolder Pattern&lt;/strong&gt; that you can start using with Android 4.0 (API level 15). &lt;strong&gt;Do not use it prior to ICS&lt;/strong&gt; (more on this below).&lt;/p&gt;

&lt;p&gt;Since Android 1.6, there is an overloaded version of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;View.setTag(int, Object)&lt;/code&gt; that takes an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;int&lt;/code&gt; key. The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;key =&amp;gt; tag&lt;/code&gt; association is stored in a &lt;a href=&quot;http://developer.android.com/reference/android/util/SparseArray.html&quot;&gt;SparseArray&lt;/a&gt; that belongs to the view. A key lookup is basically a binary search in an array containing the sorted keys.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;By the way, the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SparseArray&lt;/code&gt; javadoc says that &lt;em&gt;it is intended to be more efficient than using a HashMap to map Integers to Objects&lt;/em&gt;. The intent is nice, but that is quite a vague assertion. Is it more efficient in terms of space? runtime? Less GC? Under which conditions? Why does it need key ordering? E.g it could have been a hashtable implementation with int keys.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Notice how we reuse the view ids as tag keys:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;&lt;span class=&quot;nd&quot;&gt;@Override&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;View&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;getView&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;position&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;View&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;convertView&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ViewGroup&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parent&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;

	&lt;span class=&quot;nc&quot;&gt;ImageView&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bananaView&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;nc&quot;&gt;TextView&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;phoneView&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;convertView&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;convertView&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;LayoutInflater&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;context&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
		  &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;inflate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;R&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;layout&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;banana_phone&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parent&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;bananaView&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;ImageView&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;convertView&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;findViewById&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;R&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;banana&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;phoneView&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;TextView&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;convertView&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;findViewById&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;R&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;phone&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;convertView&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;setTag&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;R&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;banana&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bananaView&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;convertView&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;setTag&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;R&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;phone&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;phoneView&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
	&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;bananaView&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;ImageView&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;convertView&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getTag&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;R&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;banana&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;phoneView&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;TextView&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;convertView&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getTag&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;R&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;phone&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
	&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

	&lt;span class=&quot;nc&quot;&gt;BananaPhone&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bananaPhone&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;getItem&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;position&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;phoneView&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;setText&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bananaPhone&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getPhone&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;());&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;bananaView&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;setImageResource&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bananaPhone&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getBanana&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;());&lt;/span&gt;

	&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;convertView&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;As mentioned before, although the API is available since Android 1.6, you shouldn’t use it prior to Android 4.0, because the implementation wasn’t a per-view &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SparseArray&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;View.setTag(int, Object)&lt;/code&gt; clearly wasn’t designed with the &lt;strong&gt;ViewHolder Pattern&lt;/strong&gt; in mind. The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;key =&amp;gt; tag&lt;/code&gt; association was stored in a static &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;WeakHashMap&lt;/code&gt; using the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;View&lt;/code&gt; object as the key. A &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;WeakHashMap&lt;/code&gt; stores weak references to its keys. The idea was that as soon as a view wasn’t referenced anywhere else then in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;WeakHashMap&lt;/code&gt;, the entry could be garbage collected. However, if the value of a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;WeakHashMap&lt;/code&gt; entry contains a hard reference to its key (the view), it will never be garbage collected, and you’ll get a &lt;strong&gt;memory leak&lt;/strong&gt;. More on this &lt;a href=&quot;https://plus.google.com/u/0/104906570725395999813/posts/2cH1tw3bCy9&quot;&gt;here&lt;/a&gt;, also see the &lt;a href=&quot;http://code.google.com/p/android/issues/detail?id=18273&quot;&gt;issue&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;custom-item-viewgroup&quot;&gt;&lt;a id=&quot;Custom-item-ViewGroup&quot; href=&quot;#Custom-item-ViewGroup&quot;&gt;Custom item ViewGroup&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;There is a third way that provides better decoupling. The idea is to create a custom ViewGroup, e.g. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;BananaPhoneView&lt;/code&gt;, for each item. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;BananaPhoneView&lt;/code&gt; will keep the references to it child views. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;BananaPhoneView&lt;/code&gt; is now responsible for updating &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bananaView&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;phoneView&lt;/code&gt;.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;&lt;span class=&quot;nd&quot;&gt;@Override&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;View&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;getView&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;position&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;View&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;convertView&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ViewGroup&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parent&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;nc&quot;&gt;BananaPhoneView&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bananaPhoneView&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;convertView&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;bananaPhoneView&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;BananaPhoneView&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;LayoutInflater&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;context&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
		  &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;inflate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;R&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;layout&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;banana_phone&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parent&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
	&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;bananaPhoneView&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;BananaPhoneView&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;convertView&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

	&lt;span class=&quot;nc&quot;&gt;BananaPhone&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bananaPhone&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;getItem&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;position&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;

	&lt;span class=&quot;n&quot;&gt;bananaPhoneView&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;update&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bananaPhone&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;

	&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bananaPhoneView&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;custom-item-view&quot;&gt;&lt;a id=&quot;Custom-item-view&quot; href=&quot;#Custom-item-view&quot;&gt;Custom item view&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;Your performance measurements may tell you that you spend too much time going through the view hierarchy when measuring and drawing. You can flatten your view hierarchy by combining components, or by creating a custom view that draws the whole item manually. That’s how the mail list in Gmail works.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/static/blog_img/gmail_screenshot.png&quot; alt=&quot;Gmail Screenshot&quot; /&gt;&lt;/p&gt;

&lt;p&gt;If you haven’t already, take at look at &lt;a href=&quot;http://www.curious-creature.org/2012/12/01/android-performance-case-study/&quot;&gt;Android Performance Case Study&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;&lt;a id=&quot;Conclusion&quot; href=&quot;#Conclusion&quot;&gt;Conclusion&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;Adapters in Android are frightening at first, but when you get to know them, they are actually quite friendly beasts. The best way to get there is to read the Android source, as well as other apps source, such as &lt;a href=&quot;https://github.com/github/android&quot;&gt;GitHub Android&lt;/a&gt;, &lt;a href=&quot;https://github.com/WhiteHouse/wh-app-android&quot;&gt;White House for Android&lt;/a&gt;, or &lt;a href=&quot;http://code.google.com/p/iosched/&quot;&gt;ioshed&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Many thanks to &lt;a href=&quot;http://twitter.com/franklinharper&quot;&gt;Frank Harper&lt;/a&gt;, &lt;a href=&quot;http://twitter.com/ebottard&quot;&gt;Eric Bottard&lt;/a&gt; and &lt;a href=&quot;http://twitter.com/JoanZap&quot;&gt;Joan Zapata&lt;/a&gt; for reviewing this article.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2 id=&quot;update&quot;&gt;&lt;a id=&quot;Update&quot; href=&quot;#Update&quot;&gt;Update&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;Benoît Lubek suggested another solution on &lt;a href=&quot;http://plus.google.com/107264729678111825621/posts/aykMojDjYxU&quot;&gt;Google+&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The idea is to reproduce the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;View.setTag(int, Object)&lt;/code&gt; ICS+ behavior as an external API, relying on &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;View.setTag(Object)&lt;/code&gt;:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ViewHolder&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// I added a generic return type to reduce the casting noise in client code&lt;/span&gt;
	&lt;span class=&quot;nd&quot;&gt;@SuppressWarnings&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;unchecked&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;T&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;View&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;T&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;View&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;view&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;nc&quot;&gt;SparseArray&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;View&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;viewHolder&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;SparseArray&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;View&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;)&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;view&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getTag&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;viewHolder&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
			&lt;span class=&quot;n&quot;&gt;viewHolder&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;SparseArray&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;View&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;();&lt;/span&gt;
			&lt;span class=&quot;n&quot;&gt;view&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;setTag&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;viewHolder&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
		&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
		&lt;span class=&quot;nc&quot;&gt;View&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;childView&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;viewHolder&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;childView&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
			&lt;span class=&quot;n&quot;&gt;childView&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;view&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;findViewById&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
			&lt;span class=&quot;n&quot;&gt;viewHolder&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;put&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;childView&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
		&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;childView&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This solution is elegant, and the code looks even simpler:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;&lt;span class=&quot;nd&quot;&gt;@Override&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;View&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;getView&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;position&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;View&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;convertView&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ViewGroup&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parent&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;

	&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;convertView&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;convertView&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;LayoutInflater&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;context&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
		  &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;inflate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;R&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;layout&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;banana_phone&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parent&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
	&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

	&lt;span class=&quot;nc&quot;&gt;ImageView&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bananaView&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ViewHolder&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;convertView&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;R&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;banana&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
	&lt;span class=&quot;nc&quot;&gt;TextView&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;phoneView&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ViewHolder&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;convertView&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;R&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;phone&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;

	&lt;span class=&quot;nc&quot;&gt;BananaPhone&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bananaPhone&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;getItem&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;position&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;phoneView&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;setText&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bananaPhone&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getPhone&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;());&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;bananaView&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;setImageResource&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bananaPhone&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getBanana&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;());&lt;/span&gt;

	&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;convertView&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;I really like this approach!&lt;/p&gt;

&lt;h1 id=&quot;comments&quot;&gt;Comments&lt;/h1&gt;

&lt;!--

To comment, copy and paste the following block

## [Nickname](http://website)
Comment

--&gt;
&lt;h2 id=&quot;hub&quot;&gt;&lt;a href=&quot;&quot;&gt;hub&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;You explain a difficult thing in a simple way.
Thank you very much.&lt;/p&gt;

&lt;h2 id=&quot;james&quot;&gt;&lt;a href=&quot;&quot;&gt;James&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Clear illustration of the choice of different adapters, very practical and very useful! Thanks!&lt;/p&gt;

&lt;h2 id=&quot;xiao&quot;&gt;&lt;a href=&quot;&quot;&gt;Xiao&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I was looking for a way to replace the entire list of items inside an ArrayAdapter without calling clear()/addAll() which generates garbage. This looks like a good solution (referring to the updateBananas() function).&lt;/p&gt;

&lt;h2 id=&quot;imherolddev&quot;&gt;&lt;a href=&quot;http://www.imherolddev.com&quot;&gt;imherolddev&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I have done a lot of research, written different adapters, duct taped and glued some together, and now that I come back to revisit ListView, I find your post! I hope to see a comparison between RecylerView and the ViewHolders you have described here. However, the BaseAdapter example has me excited to write my next Adapter, which should be far more complex than what I have done to date… Thank you for your write up here! I will be sure to share with my circles.&lt;/p&gt;

&lt;h2 id=&quot;robertoallende&quot;&gt;&lt;a href=&quot;http://robertoallende.com&quot;&gt;robertoallende&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Great article, you’ve saved my day. Thank you very much!&lt;/p&gt;

&lt;h2 id=&quot;mário-valney&quot;&gt;&lt;a href=&quot;http://mariovalney.com&quot;&gt;Mário Valney&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I really loved your article. Great explanation!
I confess I started with another approach, but when I read your article I just changed everything because it’s much more elegant!&lt;/p&gt;
</content>
 </entry>
 
 
 
 <entry>
   <title>Happy Birthday AndroidAnnotations!</title>
   <link href="http://www.piwai.info/happy-birthday-androidannotations"/>
   <updated>2012-12-22T00:00:00+00:00</updated>
   <id>http://www.piwai.info/happy-birthday-androidannotations</id>
   <content type="html">&lt;p&gt;Two years ago, I created &lt;a href=&quot;http://androidannotations.org&quot;&gt;AndroidAnnotations&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/excilys/androidannotations/commit/df8981f2e224bb0e85f0c299c03945ceaf9e2ec7&quot;&gt;&lt;img src=&quot;/static/blog_img/first_commit.png&quot; alt=&quot;First commit&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Lesson n°1: think before writing your first commit message&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Time to take a look back at the last two years!&lt;/p&gt;

&lt;div class=&quot;alert alert-block&quot;&gt;
  &lt;h4&gt;Warning!&lt;/h4&gt;
  This article contains trivia, useless statistics, and too much &lt;em&gt;me&lt;/em&gt; and &lt;em&gt;I&lt;/em&gt;.&lt;br /&gt;
You have been warned.
&lt;/div&gt;

&lt;h2 id=&quot;background&quot;&gt;@Background&lt;/h2&gt;

&lt;p&gt;I started writing Android apps in 2009. I came from the Java/JEE world, in which you can find tons of frameworks and good practices. Android didn’t feel right: my whole codebase was tied to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Activity&lt;/code&gt; class, and I didn’t find the code to be much readable and maintainable.&lt;/p&gt;

&lt;p&gt;I wanted to decouple my code components using &lt;a href=&quot;http://en.wikipedia.org/wiki/Dependency_injection&quot;&gt;IoC &amp;amp; Dependency Injection&lt;/a&gt;, so I tried a few things:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/Spring_Framework&quot;&gt;Spring IoC&lt;/a&gt;, which relied on JDK classes not available in Android, and crashed.&lt;/li&gt;
  &lt;li&gt;Creating the dependency graph manually, in code. Worked great, until the dependency graph became too big and hard to maintain.&lt;/li&gt;
  &lt;li&gt;Creating a small &lt;a href=&quot;http://code.google.com/p/yasdic/&quot;&gt;DI container&lt;/a&gt; that didn’t rely on reflection. It wasn’t typesafe though, and it required tons of anonymous classes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then I discovered &lt;a href=&quot;http://roboguice.org&quot;&gt;RoboGuice&lt;/a&gt;, started using it and &lt;a href=&quot;https://github.com/emmby/roboguice/graphs/contributors&quot;&gt;contributing&lt;/a&gt;. I really liked that you could inject Android specific components such as views and resource. This isn’t really dependency injection, but it still makes your code much more readable. The bad part though was the performance hit on startup, because RoboGuice relied on reflection.&lt;/p&gt;

&lt;p&gt;On the 14th of december 2010, Olivier Croisier presented the Annotation Processors &lt;a href=&quot;http://www.parisjug.org/xwiki/bin/view/Meeting/20101214&quot;&gt;at the ParisJUG&lt;/a&gt;. A few days later, AndroidAnnotations was born.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;The name &lt;strong&gt;AndroidAnnotations&lt;/strong&gt; comes from the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AndroidAnnotationProcessor&lt;/code&gt; class that handles the annotation processing.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The focus in AndroidAnnotations has never really been about dependency injection, but rather about creating annotations to simplify your code and make your life easier, at compile time. It started with view injection, then event binding (based on GWT &lt;a href=&quot;http://google-web-toolkit.googlecode.com/svn/javadoc/2.0/com/google/gwt/uibinder/client/UiHandler.html&quot;&gt;@UiHandler&lt;/a&gt;), resource injection, simplified threading…&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/static/blog_img/logo.png&quot; alt=&quot;AndroidAnnotations logo&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;timeline&quot;&gt;@Timeline&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;December 2010&lt;/strong&gt; First commit&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;January 2011&lt;/strong&gt; First external &lt;a href=&quot;http://code.google.com/p/androidannotations/issues/detail?id=1&quot;&gt;code contribution&lt;/a&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;April 2011&lt;/strong&gt; Release of the &lt;strong&gt;2.0&lt;/strong&gt; version&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;August 2011&lt;/strong&gt; Roy Clarkson mentions AndroidAnnotations on the &lt;a href=&quot;http://blog.springsource.com/2011/08/26/clean-code-with-android/&quot;&gt;SpringSource Blog&lt;/a&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;September 2011&lt;/strong&gt; &lt;em&gt;eBusiness Information&lt;/em&gt; becomes the official sponsor&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;October 2011&lt;/strong&gt; Matthias Kaeppler mentions AndroidAnnotations at DroidCon London 2011&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;January 2012&lt;/strong&gt; Migration from Google Code to GitHub&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;April 2012&lt;/strong&gt; Talk at &lt;a href=&quot;http://www.parleys.com/#id=3259&quot;&gt;Devoxx France&lt;/a&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;October 2012&lt;/strong&gt; Talk at &lt;a href=&quot;http://www.parleys.com/#id=3550&quot;&gt;Devoxx&lt;/a&gt;&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src=&quot;/static/blog_img/ddd.png&quot; alt=&quot;Diet Driven Development&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;randomstats&quot;&gt;@RandomStats&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;953&lt;/strong&gt; commits and more than &lt;strong&gt;35000&lt;/strong&gt; lines of code&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;124&lt;/strong&gt; Pull Requests&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;15&lt;/strong&gt; code &lt;a href=&quot;https://github.com/excilys/androidannotations/graphs/contributors&quot;&gt;contributors&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;More than &lt;strong&gt;400&lt;/strong&gt; apps on Google Play (&lt;a href=&quot;http://www.appbrain.com/stats/libraries/details/android-annotations/androidannotations&quot;&gt;source&lt;/a&gt;)&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;89&lt;/strong&gt; members on the &lt;a href=&quot;http://groups.google.com/group/androidannotations&quot;&gt;mailing list&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;36&lt;/strong&gt; &lt;a href=&quot;http://stackoverflow.com/questions/tagged/android-annotations&quot;&gt;StackOverflow&lt;/a&gt; questions&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;319&lt;/strong&gt; &lt;a href=&quot;https://twitter.com/andannotations&quot;&gt;@AndAnnotations&lt;/a&gt; followers&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;355&lt;/strong&gt; followers &amp;amp; &lt;strong&gt;419&lt;/strong&gt; &lt;em&gt;+1&lt;/em&gt;  on &lt;a href=&quot;https://plus.google.com/u/0/106206799999983258245/posts&quot;&gt;Google+&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;654&lt;/strong&gt; stargazers &amp;amp; &lt;strong&gt;101&lt;/strong&gt; forks on &lt;a href=&quot;https://github.com/excilys/androidannotations&quot;&gt;GitHub&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;future&quot;&gt;@Future&lt;/h2&gt;

&lt;p&gt;AndroidAnnotations will continue to concentrate on simplifying your Android code with compile time code generation. I think Android developers should be able to pickup their frameworks of choice and use them all together.&lt;/p&gt;

&lt;p&gt;Here is a &lt;a href=&quot;https://github.com/pyricau/CleanAndroidCode&quot;&gt;sample project&lt;/a&gt; that uses &lt;a href=&quot;http://square.github.com/dagger/&quot;&gt;Dagger&lt;/a&gt; for dependency injection, AndroidAnnotations for boilerplate removal, and &lt;a href=&quot;http://square.github.com/otto/&quot;&gt;Otto&lt;/a&gt; as an event bus.&lt;/p&gt;

&lt;p&gt;Let’s see what happens over the next two years!&lt;/p&gt;

&lt;h1 id=&quot;comments&quot;&gt;Comments&lt;/h1&gt;

&lt;!--

To comment, copy and paste the following block

## [Nickname](http://website)
Comment

--&gt;
</content>
 </entry>
 
 
 
 <entry>
   <title>Renaming the Android Manifest package</title>
   <link href="http://www.piwai.info/renaming-android-manifest-package"/>
   <updated>2012-12-20T00:00:00+00:00</updated>
   <id>http://www.piwai.info/renaming-android-manifest-package</id>
   <content type="html">&lt;p&gt;I recently needed to be able to change the package name of an app at build time. This is a common need when you have a paid and a free version of an app. It’s also useful if you want to be able to install multiple versions of an app on your phone, such as a “dev” and a “stable” build.&lt;/p&gt;

&lt;p&gt;One way to do it is to transform the whole project as a library project, and then create one final project for each version, that depends on the library project.&lt;/p&gt;

&lt;h2 id=&quot;aapt-magic&quot;&gt;Aapt magic&lt;/h2&gt;

&lt;p&gt;There is another way: &lt;strong&gt;aapt&lt;/strong&gt; has a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;--rename-manifest-package&lt;/code&gt; parameter that rewrites the package name of the binary &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AndroidManifest.xml&lt;/code&gt; file in the final APK.&lt;/p&gt;

&lt;p&gt;Here is what &lt;strong&gt;aapt&lt;/strong&gt; help says:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;   &lt;span class=&quot;nt&quot;&gt;--rename-manifest-package&lt;/span&gt;
       Rewrite the manifest so that its package name is the package name
       given here.  Relative class names &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;example .Foo&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; will be
       changed to absolute names with the old package so that the code
       does not need to change.&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;The great advantage is that your code won’t change, the R class stays identical.&lt;/p&gt;

&lt;h2 id=&quot;ant&quot;&gt;Ant&lt;/h2&gt;

&lt;p&gt;Since &lt;a href=&quot;http://code.google.com/p/android/issues/detail?id=21336&quot;&gt;r17&lt;/a&gt;, this option is available in the &lt;strong&gt;aapt&lt;/strong&gt; Ant task, through the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;manifestpackage&lt;/code&gt; attribute. You’ll need to override the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-package-resources&lt;/code&gt; target, copied from the SDK &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;build.xml&lt;/code&gt;:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-xml&quot; data-lang=&quot;xml&quot;&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;target&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;-package-resources&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;depends=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;-crunch&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;do-only-if-not-library&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;elseText=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Library project: do not package resources...&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;aapt&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;executable=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;${aapt}&quot;&lt;/span&gt;
     &lt;span class=&quot;na&quot;&gt;manifestpackage=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;com.my.package&quot;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
...
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;/aapt&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;/do-only-if-not-library&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/target&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;maven&quot;&gt;Maven&lt;/h2&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;android:apk&lt;/code&gt; goal of the &lt;strong&gt;android-maven-plugin&lt;/strong&gt; has a &lt;a href=&quot;http://maven-android-plugin-m2site.googlecode.com/svn/apk-mojo.html#renameManifestPackage&quot;&gt;renameManifestPackage&lt;/a&gt; parameter.&lt;/p&gt;

&lt;h2 id=&quot;one-last-thing&quot;&gt;One last thing&lt;/h2&gt;

&lt;p&gt;If you load some resource ids at runtime, you may need to update your code.&lt;/p&gt;

&lt;p&gt;I used to do this:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;packageName&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;context&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getPackageName&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;Resources&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;res&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;context&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getResources&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;id&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;res&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getIdentifier&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;my_drawable&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;drawable&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;packageName&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This usually works great, especially in library projects where you do not know the package name.&lt;/p&gt;

&lt;p&gt;However, the problem here is that the resources were processed before the package name was finally updated. So &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;packageName&lt;/code&gt; is wrong.&lt;/p&gt;

&lt;p&gt;It’s easy to fix though, by retrieving the package name of another resource with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Resources.getResourcePackageName()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Let’s create a resource id dedicated to that purpose, for example in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;res/values/ids.xml&lt;/code&gt;:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-xml&quot; data-lang=&quot;xml&quot;&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;resources&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;xmlns:android=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;http://schemas.android.com/apk/res/android&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;item&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;used_for_package_name_retrieval&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;type=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;id&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/resources&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;And now we get the right package:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;&lt;span class=&quot;nc&quot;&gt;Resources&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;res&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;context&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getResources&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;packageName&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;res&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getResourcePackageName&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;R&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;used_for_package_name_retrieval&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;id&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;res&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getIdentifier&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;some_drawable&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;drawable&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;packageName&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;This tip helps creating different versions of the same app.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/static/blog_img/manifest_package.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;As you can see on this screenshot, the package name can then be set as a build parameter, to create parameterized builds in Jenkins.&lt;/p&gt;

&lt;h1 id=&quot;comments&quot;&gt;Comments&lt;/h1&gt;

&lt;!--

To comment, copy and paste the following block

## [Nickname](http://website)
Comment

--&gt;
</content>
 </entry>
 
 
 
 <entry>
   <title>Blog meets Monster Octocat</title>
   <link href="http://www.piwai.info/blog-meets-monster-octocat"/>
   <updated>2012-12-19T00:00:00+00:00</updated>
   <id>http://www.piwai.info/blog-meets-monster-octocat</id>
   <content type="html">&lt;p&gt;I initially created this blog on Wordpress.com, mostly because I didn’t want to invest any time in maintaining it.&lt;/p&gt;

&lt;p&gt;I’ve been using GitHub and Markdown on an everyday basis ever since. I got bored of Wordpress, therefore I decided to migrate this blog to &lt;a href=&quot;https://github.com/mojombo/jekyll&quot;&gt;Jekyll&lt;/a&gt;, using the built-in &lt;a href=&quot;http://pages.github.com/&quot;&gt;GitHub support&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://www.github.com&quot;&gt;&lt;img src=&quot;/static/blog_img/murakamicat.png&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This means I can write my articles in Markdown with &lt;a href=&quot;http://mouapp.com/&quot;&gt;Mou&lt;/a&gt;, and just commit and push to publish an article.&lt;/p&gt;

&lt;p&gt;Even better, anyone can now &lt;a href=&quot;https://github.com/pyricau/pyricau.github.com/blob/master/_posts/2012-12-19-blog-meets-monster-octocat.markdown&quot;&gt;improve this article&lt;/a&gt; with a pull request. I really like this!&lt;/p&gt;

&lt;p&gt;Jekyll generates static html pages. What about comments? Most Jekyll hosted blogs use external javascript services to dynamically include comments at the end of their blog posts. This doesn’t feel right to me, because I think comments ought to be part of the content they are linked to.&lt;/p&gt;

&lt;p&gt;That’s why comments are now part of the source of the post. All you need to do is &lt;a href=&quot;https://github.com/pyricau/pyricau.github.com/blob/master/_posts/2012-12-19-blog-meets-monster-octocat.markdown&quot;&gt;click here&lt;/a&gt;, edit the post on GitHub and add your comments at the end.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;## [Piwaï](http://piwai.info)&lt;/span&gt;
Hello!&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Let’s see if that’s something you are able to do ;-) .&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;By the way, I also started writing in English, trying to reach a broader audience and practice my writing. Let me know if you find weird french looking sentences.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1 id=&quot;comments&quot;&gt;Comments&lt;/h1&gt;

&lt;!--

To comment, copy and paste the following block

## [Nickname](http://website)
Comment

--&gt;

&lt;h2 id=&quot;gnupat&quot;&gt;&lt;a href=&quot;http://bisouland.piwai.info&quot;&gt;gnupat&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;Great idea, I can’t wait to see how the PR driven comments are going :D .&lt;/p&gt;

&lt;p&gt;By the way, am I doing this right?&lt;/p&gt;

&lt;h2 id=&quot;aurélien&quot;&gt;&lt;a href=&quot;http://blogpro.toutantic.net&quot;&gt;Aurélien&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;It’s turtles all the way down !
And the comment button is displayed twice at the end of your post.&lt;/p&gt;

&lt;h2 id=&quot;piwaï&quot;&gt;&lt;a href=&quot;http://piwai.info&quot;&gt;Piwaï&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Turns out, all comments pull request are located at the same position so this leads to merge conflicts (easy to fix though). Comments is displayed twice on purpose, as you can see now that there are actual comments. Maybe I should remove the first one.&lt;/p&gt;

</content>
 </entry>
 
 
 
 <entry>
   <title>Paris Android Dev Lab</title>
   <link href="http://www.piwai.info/2011/11/06/paris-android-dev-lab/"/>
   <updated>2011-11-06T20:03:59+00:00</updated>
   <id>http://www.piwai.info/2011/11/06/paris-android-dev-lab</id>
   <content type="html">&lt;h2 id=&quot;introduction&quot;&gt;Introduction&lt;/h2&gt;

&lt;p&gt;Un &lt;a href=&quot;http://android-developers.blogspot.com/2011/08/android-developer-labs-2011.html&quot;&gt;Android Developer Labs&lt;/a&gt; (ADL) s’est déroulé à Paris jeudi 27 et vendredi 28 octobre 2011, traitant de l’&lt;strong&gt;optimisation&lt;/strong&gt; des applications &lt;strong&gt;Android&lt;/strong&gt; pour les &lt;strong&gt;tablettes&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;J’ai eu la chance d’être invité à cet évènement ; j’en ai donc profité pour prendre des notes afin de pouvoir retranscrire le déroulement de cette journée (l’ADL du vendredi).&lt;/p&gt;

&lt;h2 id=&quot;apéro-android&quot;&gt;Apéro Android&lt;/h2&gt;

&lt;p&gt;Avant tout, laissez-moi vous parler de l’&lt;a href=&quot;http://www.paug.fr/2011/10/apero-android-le-27-octobre-avec-les.html&quot;&gt;apéro Android&lt;/a&gt;. Sachant que les places pour l’ADL étaient limitées, le Paris Android User Group (&lt;a href=&quot;http://www.paug.fr/&quot;&gt;PAUG&lt;/a&gt;) a organisé un &lt;strong&gt;apéro Android&lt;/strong&gt; le jeudi soir, pour permettre à tous de discuter et de rencontrer les &lt;em&gt;Android Developer Advocates&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/static/blog_img/aperoandroid.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Les Googlers sont très ouverts et abordables, et nous avons passé une soirée sympatique, en partie aux frais de &lt;a href=&quot;http://www.frandroid.com/&quot;&gt;FrAndroid&lt;/a&gt;. Je vous conseille vivement ce type de rencontre ; c’est un bon moyen d’apprendre et de rencontrer des gens intéressants tout en passant un bon moment.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://code.google.com/p/androidannotations/&quot;&gt;&lt;img src=&quot;/static/blog_img/logo.png&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Au cours de la soirée, j’ai eu le plaisir de constater que deux &lt;em&gt;Android Developer Advocates&lt;/em&gt; (&lt;a href=&quot;https://plus.google.com/118292708268361843293/posts&quot;&gt;Nick Butcher&lt;/a&gt; et &lt;a href=&quot;https://plus.google.com/115995639636688350464/posts&quot;&gt;Richard Hyndman&lt;/a&gt;) connaissaient &lt;a href=&quot;http://code.google.com/p/androidannotations/&quot;&gt;AndroidAnnotations&lt;/a&gt;, suite au &lt;a href=&quot;http://uk.droidcon.com/programme/day-2#kaeppler-development&quot;&gt;talk&lt;/a&gt; de &lt;a href=&quot;http://twitter.com/twoofour&quot;&gt;Matthias Kaeppler&lt;/a&gt; à la &lt;strong&gt;DroidCon&lt;/strong&gt; 2011.&lt;/p&gt;

&lt;h2 id=&quot;ladl&quot;&gt;L’ADL&lt;/h2&gt;

&lt;p&gt;Le programme de la journée était le suivant :&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Introduction aux tablettes&lt;/li&gt;
  &lt;li&gt;Quoi de neuf dans Ice Cream Sandwich&lt;/li&gt;
  &lt;li&gt;Android Market pour développeurs&lt;/li&gt;
  &lt;li&gt;Développer pour téléphones et tablettes&lt;/li&gt;
  &lt;li&gt;Codelab&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;J’ai pris des notes du mieux possible ; j’espère que vous me saurez gré des lacunes éventuelles et de la faible mise en forme.&lt;/p&gt;

&lt;h3 id=&quot;introduction-aux-tablettes&quot;&gt;Introduction aux tablettes&lt;/h3&gt;

&lt;p&gt;Cette présentation fut consacrée aux spécificités liées à &lt;strong&gt;Honeycomb&lt;/strong&gt; et au développement pour &lt;strong&gt;tablettes&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Notez qu’Honeycomb est uniquement orienté tablette : l’équipe Android n’avait pas le temps de réaliser un OS pour téléphones en parallèle.&lt;/p&gt;

&lt;h4 id=&quot;system-bar&quot;&gt;System bar&lt;/h4&gt;

&lt;p&gt;Auparavant, les informations système et les notifications étaient situées dans une barre &lt;strong&gt;en haut&lt;/strong&gt; de l’écran.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/static/blog_img/top_bar.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Désormais, cette barre se situe &lt;strong&gt;en bas&lt;/strong&gt; de l’écran, et contient en outre les boutons de &lt;strong&gt;navigation&lt;/strong&gt;. Cela permet de se débarrasser des boutons &lt;strong&gt;physiques&lt;/strong&gt;, qui étaient mal placés lorsque l’on passait en &lt;strong&gt;mode paysage&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/static/blog_img/bottom_bar.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Les &lt;strong&gt;notifications&lt;/strong&gt; sont désormais accessibles sans couvrir totalement l’écran, de même qu’un certain nombre de &lt;strong&gt;réglages&lt;/strong&gt; et &lt;strong&gt;informations&lt;/strong&gt; bien pratiques.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/static/blog_img/bottom_bar_notif.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Cette barre peut distraire l’&lt;strong&gt;attention visuelle&lt;/strong&gt; lorsque vous souhaitez une &lt;strong&gt;expérience immersive&lt;/strong&gt;. Il est possible de la &lt;strong&gt;cacher&lt;/strong&gt; en utilisant le code suivant :&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;&lt;span class=&quot;n&quot;&gt;mView&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;setSystemUiVisibility&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;View&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;STATUS_BAR_HIDDEN&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;&lt;em&gt;Note : je me demande bien pourquoi cette méthode n’est pas statique et appartient à View ; si vous avez une idée, n’hésitez pas à commenter.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Dans le screenshot suivant, comme vous le voyez, la barre ne disparaît &lt;strong&gt;pas totalement&lt;/strong&gt;. Elle devient noire, mais les icônes sont remplacés par des points gris &lt;strong&gt;toujours cliquables&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/static/blog_img/bottom_bar_dark.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note : ce screenshot montre le dernier niveau de &lt;a href=&quot;https://market.android.com/details?id=com.robotinvader.knightmare&quot;&gt;Wind-up Knight&lt;/a&gt;, un &lt;strong&gt;jeu sympa&lt;/strong&gt; qui est un bon exemple de l’efficacité du paiement &lt;strong&gt;in-app&lt;/strong&gt; (la preuve, je n’ai pas résisté et ce fût l’occasion de réaliser mon premier paiement in-app).&lt;/em&gt;&lt;/p&gt;

&lt;h4 id=&quot;action-bar&quot;&gt;Action bar&lt;/h4&gt;

&lt;p&gt;Vous souvenez-vous d’Android 1.X, où la barre de titre occupait une place énorme qui ne servait à rien ?&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/static/blog_img/title_1_5.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Autant utiliser cet espace !&lt;/p&gt;

&lt;p&gt;C’est le principe de l’&lt;strong&gt;action bar&lt;/strong&gt;. Celle-ci comporte tout d’abord une &lt;strong&gt;icône cliquable&lt;/strong&gt; qui permet de retourner à tout moment à l’&lt;strong&gt;écran d’accueil&lt;/strong&gt;.Elle affiche ensuite des éléments liés à la &lt;strong&gt;navigation&lt;/strong&gt;, et pour finir des &lt;strong&gt;icônes d’action&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Cette &lt;strong&gt;action bar&lt;/strong&gt; n’est pas nécessairement un composant Android, il s’agit plutôt d’un &lt;strong&gt;design pattern&lt;/strong&gt; de &lt;strong&gt;UI&lt;/strong&gt;, que toute application Android digne de ce nom devrait respecter.&lt;/p&gt;

&lt;p&gt;Le projet &lt;strong&gt;ActionBarCompat&lt;/strong&gt;, disponible dans les samples depuis &lt;strong&gt;ADT 14&lt;/strong&gt;, met à disposition tout le code et les ressources nécessaires à la création d’une action bar fonctionnant sur toutes les versions d’Android.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/static/blog_img/action_bar_compat.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;ActionBarCompat sur mon Nexus One (Gingerbread)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Les &lt;strong&gt;menu items&lt;/strong&gt; dans l’&lt;strong&gt;Options Menu&lt;/strong&gt; peuvent être rendus disponibles dans les boutons d’action. Il suffit juste d’ajouter l’attribut suivant aux items dans votre &lt;strong&gt;menu.xml&lt;/strong&gt; :&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-xml&quot; data-lang=&quot;xml&quot;&gt;    android:showAsAction=&quot;ifRoom|withText&quot;;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h4 id=&quot;les-fragments&quot;&gt;Les fragments&lt;/h4&gt;

&lt;p&gt;Sans trop rentrer dans les détails : les fragments sont des composants de UI, réutilisables. L’utilisation de Fragment permet de repenser la UI, il ne suffit plus de se contenter d’avoir un design fluide qui s’élargit par rapport à la taille de l’écran, il faut organiser les fragments différents suivant l’écran et la place disponible.&lt;/p&gt;

&lt;p&gt;Pour être tout à fait honnête, je ne suis qu’à moitié convaincu par ce nouveau système de fragment. Le principe reste proche de celui des activités : il s’agit d’un &lt;strong&gt;controller&lt;/strong&gt;, chargé d’&lt;strong&gt;orchestrer&lt;/strong&gt; le &lt;strong&gt;code métier&lt;/strong&gt; lié à un assemblage de composants graphiques (des &lt;strong&gt;View&lt;/strong&gt;).&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/static/blog_img/fragment.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;En soit, ce n’est pas une mauvaise idée. Par contre, on se retrouve encore avec un &lt;strong&gt;modèle par héritage&lt;/strong&gt;, comme pour les &lt;strong&gt;activités&lt;/strong&gt;. Tout fragment doit hériter de &lt;strong&gt;Fragment&lt;/strong&gt;. Il existe un &lt;strong&gt;ListFragment&lt;/strong&gt;, un &lt;strong&gt;XXXFragment&lt;/strong&gt;, etc, qui tous héritent de &lt;strong&gt;Fragment&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Le problème, c’est que dès lors que l’on souhaite factoriser du code commun à plusieurs Fragments, il va falloir recréer une sous classe pour chacun des types de Fragment. &lt;strong&gt;AbstractCustomFragment&lt;/strong&gt;, &lt;strong&gt;AbstractCustomListFragment&lt;/strong&gt;, etc. Et évidemment, si deux frameworks s’amusent à créer leurs propres fragments à étendre, il devient compliqué de les combiner.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/static/blog_img/fragment_inheritance.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Pour faire un parallèle, j’ai l’impression que l’équipe Android persiste à proposer des &lt;strong&gt;servlets&lt;/strong&gt;, quand il serait bien plus utile de proposer des &lt;strong&gt;controllers&lt;/strong&gt; Spring.&lt;/p&gt;

&lt;p&gt;A bien y réfléchir, une &lt;strong&gt;Activity&lt;/strong&gt; et un &lt;strong&gt;Fragment&lt;/strong&gt; ont ceci de commun qu’ils répondent à des &lt;strong&gt;évènements&lt;/strong&gt; (principe des &lt;strong&gt;callbacks&lt;/strong&gt; type &lt;strong&gt;onCreate()&lt;/strong&gt;), qu’ils renvoient des éléments de configuration (e.g. getLastNonConfigurationInstance()), et qu’ils fournissent des helpers (&lt;strong&gt;getLoaderManager()&lt;/strong&gt;, &lt;strong&gt;getPreferences()&lt;/strong&gt;, etc).&lt;/p&gt;

&lt;p&gt;Pour moi, ces différentes responsabilités devraient appartenir à différents composants.&lt;/p&gt;

&lt;h4 id=&quot;les-loaders&quot;&gt;Les Loaders&lt;/h4&gt;

&lt;p&gt;Les &lt;a href=&quot;http://developer.android.com/guide/topics/fundamentals/loaders.html&quot;&gt;Loaders&lt;/a&gt; sont un nouveau moyen pour récupérer des données en tâche de fond, en gérant convenablement les problématiques liées au cycle de vie des composants Android.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://commons.wikimedia.org/wiki/File:Samsung_loader.JPEG&quot;&gt;&lt;img src=&quot;/static/blog_img/Samsung_loader.jpeg&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Samsung loader, by A1C Beatrice Cassetty, U.S. Air Force (public domain)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;C’est une alternative très intéressante à l’&lt;a href=&quot;http://developer.android.com/reference/android/os/AsyncTask.html&quot;&gt;AsyncTask&lt;/a&gt;, qui malgré plusieurs bonnes idées souffre de quelques problèmes :&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;Pas de gestion du cycle de vie (activité mise en pause, détruite définitivement, détruite mais pour raison de changement de configuration, etc)&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Pas facile à utiliser : le paramètre générique PARAM n’est pas vraiment utile (en plus, c’est une &lt;strong&gt;vararg&lt;/strong&gt;, quelle horreur !), il n’y a pas de gestion des exceptions.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A noter qu’un des premiers risques avec les &lt;strong&gt;AsyncTask&lt;/strong&gt;, c’est d’en faire des classes anonymes et de leaker des références vers leur &lt;strong&gt;outer class&lt;/strong&gt;, qui est bien souvent une &lt;strong&gt;activité&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Et pour simplifier votre code de gestion des Threads sur Android, pourquoi ne pas essayer &lt;a href=&quot;http://code.google.com/p/androidannotations/wiki/WorkingWithThreads&quot;&gt;@Background et @UiThread&lt;/a&gt; sur &lt;a href=&quot;http://code.google.com/p/androidannotations&quot;&gt;AndroidAnnotations&lt;/a&gt; ?&lt;/p&gt;

&lt;h4 id=&quot;hardwareaccelerated&quot;&gt;hardwareAccelerated&lt;/h4&gt;

&lt;p&gt;Pensez à activer le flag suivant dans votre manifest :&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-xml&quot; data-lang=&quot;xml&quot;&gt;android:hardwareAccelerated=&quot;true&quot;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Cela permet de bénéficier de l’accélération matérielle pour le rendering, gratos. Il est désactivé par défaut car certaines implémentations dessinant via des canvas peuvent ralentir ou faire crasher votre appli.&lt;/p&gt;

&lt;p&gt;Ce n’est normalement pas le cas des composants standards. Comment décider s’il faut l’utiliser ? C’est simple :&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;Activez &lt;strong&gt;hardwareAccelerated&lt;/strong&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Testez votre application sur Honeycomb. Si elle ne plante pas, c’est bon, vous pouvez dormir tranquille!&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;renderscript&quot;&gt;Renderscript&lt;/h4&gt;

&lt;p&gt;&lt;a href=&quot;http://developer.android.com/guide/topics/renderscript/index.html&quot;&gt;Renderscript&lt;/a&gt; est une &lt;em&gt;nouvelle&lt;/em&gt; API C permettant de faire du &lt;strong&gt;3D rendering&lt;/strong&gt; haute performance. Nouvelle… pas tant que ça! Si j’ai bonne mémoire, &lt;a href=&quot;https://plus.google.com/111962077049890418486/&quot;&gt;Romain Guy&lt;/a&gt; nous présentait déjà Renderscript au précédent Android Dev Lab, il y a de cela deux ans. Bon, il est vrai que l’API n’a probablement plus rien à voir (initialement, ça n’était même pas du C), seul le concept reste identique.&lt;/p&gt;

&lt;p&gt;Les applications &lt;strong&gt;Google Books&lt;/strong&gt; et &lt;strong&gt;YouTube&lt;/strong&gt; utilisent renderscript : Google Books pour &lt;strong&gt;tourner les pages&lt;/strong&gt;, et YouTube pour l’écran avec toutes les vidéos visibles en même temps.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/static/blog_img/youtube.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;h4 id=&quot;développement-pour-tablettes-quelques-règles-simples&quot;&gt;Développement pour tablettes, quelques règles simples&lt;/h4&gt;

&lt;ul&gt;
  &lt;li&gt;Mesurer en &lt;a href=&quot;http://developer.android.com/guide/practices/screens_support.html#density-independence&quot;&gt;dp&lt;/a&gt; plutôt qu’en pixels&lt;/li&gt;
  &lt;li&gt;Utiliser des layouts extensibles&lt;/li&gt;
  &lt;li&gt;Centraliser les dimensions dans &lt;strong&gt;dimens.xml&lt;/strong&gt;, de façon à pouvoir les overrider grâce au mécanisme de ressources&lt;/li&gt;
  &lt;li&gt;Supporter le mode paysage et ne pas bloquer en mode portrait. N’oubliez pas que la manière d’utiliser une tablette est essentiellement en paysage. Beaucoup d’application ont un écran de chargement de l’application en portrait, ce n’est pas très malin !&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;mettre-à-jour-votre-application-pour-honeycomb&quot;&gt;Mettre à jour votre application pour Honeycomb&lt;/h4&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;Ajoutez des graphiques pour les hautes résolutions (&lt;strong&gt;xhdpi&lt;/strong&gt;)&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Utilisez des fragments, même pour les anciennes versions d’Android (grâce à la &lt;a href=&quot;http://developer.android.com/sdk/compatibility-library.html&quot;&gt;compatibility library&lt;/a&gt;)&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;N’oubliez pas d’ajouter &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt;uses-sdk android:targetSdkVersion=&quot;14&quot; /&amp;gt;&lt;/code&gt; dans votre manifest, notamment pour bénéficier automatique de la nouvelle Action bar sur Honeycomb&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Voilà qui conclu la première moitié de ce compte rendu sur l’Android Dev Lab, je vous conterai la fin de cette journée lors du prochain article.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Edit: en fait, il n’y a jamais eu de prochain article :)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1 id=&quot;comments&quot;&gt;Comments&lt;/h1&gt;

&lt;h2 id=&quot;frank-harper-franklinharper&quot;&gt;&lt;a href=&quot;http://twitter.com/franklinharper&quot;&gt;Frank Harper (@franklinharper)&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;Tout à fait d’accord quand tu soulignes la pénibilité de sous classer chacun des types de Fragment/Activity! J’espérais qu’une solution plus élégante allait apparaître avec Android 4.0.&lt;/p&gt;

&lt;p&gt;Pour activer l’Action bar un targetSdkVersion=”11″ devrait suffire; mais si on peut tester avec ICS pourquoi pas aller directement en targetSdkVersion=”14″!&lt;/p&gt;
</content>
 </entry>
 
 
 
 <entry>
   <title>Coup de balai : déblayer les branches d'un repo Git</title>
   <link href="http://www.piwai.info/2011/10/30/coup-de-balai-deblayer-les-branches-dun-repo-git/"/>
   <updated>2011-10-30T23:30:34+00:00</updated>
   <id>http://www.piwai.info/2011/10/30/coup-de-balai-deblayer-les-branches-dun-repo-git</id>
   <content type="html">&lt;p&gt;Comme je vous l’indiquais dans un &lt;a href=&quot;http://blog.piwai.info/2011/10/14/tas-mis-a-jour-les-specs/&quot;&gt;précédent article&lt;/a&gt;, chez &lt;a href=&quot;http://www.siine.com/&quot;&gt;Siine&lt;/a&gt;, nous hébergeons nos projets sur &lt;a href=&quot;http://github.com/&quot;&gt;GitHub&lt;/a&gt;, et chaque User Story fait l’objet d’une &lt;a href=&quot;http://blog.piwai.info/2011/10/09/roooh-jai-encore-oublie-ma-branche-git/&quot;&gt;branche dédiée&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Lorsqu’une &lt;strong&gt;branche&lt;/strong&gt; qui a fait l’objet d’une &lt;strong&gt;pull request&lt;/strong&gt; est validée, elle est &lt;strong&gt;mergée&lt;/strong&gt; sur la branche d’intégration. Nous n’avons cependant pas pris l’habitude de &lt;strong&gt;supprimer&lt;/strong&gt; ces branches une fois mergées. Je pense que nous aurions probablement du les supprimer au fur et à mesure, car nous nous retrouvons aujourd’hui avec de &lt;strong&gt;nombreuses branches mergées&lt;/strong&gt;, qui ne servent à rien et qui &lt;strong&gt;polluent&lt;/strong&gt; nos repository.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://commons.wikimedia.org/wiki/File:Branches_konary.jpg&quot;&gt;&lt;img src=&quot;/static/blog_img/Branches_konary.jpeg&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Branches konary by Krzysztof&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Notez que GitHub conserve &lt;strong&gt;l’historique&lt;/strong&gt; des pull request même quand les branches sont supprimées. Je ne vois vraiment aucune raison de conserver des branches mergées. Et vous ?&lt;/p&gt;

&lt;p&gt;Quoi qu’il en soit, il est tout à fait possible de corriger cela, en quelques &lt;strong&gt;commandes&lt;/strong&gt; &lt;strong&gt;Git&lt;/strong&gt; bien senties.&lt;/p&gt;

&lt;p&gt;On récupère toutes les données du &lt;strong&gt;repository remote&lt;/strong&gt;&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;git fetch &lt;span class=&quot;nt&quot;&gt;--all&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;On supprime de notre &lt;strong&gt;repository local&lt;/strong&gt; toutes les branches remote qui n’existent plus&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;git remote prune origin&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;&lt;a href=&quot;http://commons.wikimedia.org/wiki/File:Valor_prune.jpg&quot;&gt;&lt;img src=&quot;/static/blog_img/Valor_prune.jpeg&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Valor prune by Glysiak&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;On compte toutes les **branches remote mergées **:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;git branch &lt;span class=&quot;nt&quot;&gt;-r&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;--merged&lt;/span&gt; origin/integration | &lt;span class=&quot;nb&quot;&gt;wc&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-l&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Le paramètre &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-r&lt;/code&gt; signifie &lt;strong&gt;remote&lt;/strong&gt;, et &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;--merged origin/integration&lt;/code&gt; permet de lister les branches mergées dans &lt;strong&gt;origin/integration&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Vous l’aurez noté, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;wc -l&lt;/code&gt; est une commande Unix permettant de compter le &lt;strong&gt;nombre de lignes&lt;/strong&gt; du flux d’entrée. Ainsi, on pourrait l’utiliser pour compter le &lt;strong&gt;nombre de branches&lt;/strong&gt; du repository remote :&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;git branch &lt;span class=&quot;nt&quot;&gt;-r&lt;/span&gt; | &lt;span class=&quot;nb&quot;&gt;wc&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-l&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Il n’y a plus qu’à &lt;strong&gt;supprimer les branches mergées&lt;/strong&gt; :&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;# Supprimer la branche sur le remote&lt;/span&gt;
git push origin :my_branch
&lt;span class=&quot;c&quot;&gt;# Et supprimer la branche qui la track en local&lt;/span&gt;
git branch &lt;span class=&quot;nt&quot;&gt;-d&lt;/span&gt; my_branch&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Notez aussi que GitHub met à disposition ce listing sans avoir à entrer une seule ligne de commande, en cliquant sur &lt;a href=&quot;https://github.com/pyricau/FunkyJFunctional/branches&quot;&gt;Branches&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/static/blog_img/capture-d_c3a9cran-2011-10-30-c3a0-23-16-37.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Pour finir : si lister les branches mergées permet de faire le ménage, à l’inverse il peut être intéressant de prendre connaissance des &lt;strong&gt;branches non mergées&lt;/strong&gt;, car il se peut que certaines d’entre elles aient été oubliées et soient à &lt;strong&gt;l’abandon&lt;/strong&gt;. Pour cela, rien de plus simple :&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;git branch &lt;span class=&quot;nt&quot;&gt;-r&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;--no-merged&lt;/span&gt; origin/integration&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h1 id=&quot;comments&quot;&gt;Comments&lt;/h1&gt;

&lt;h2 id=&quot;dvins&quot;&gt;&lt;a href=&quot;http://gravatar.com/dvins&quot;&gt;Dvins&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;Salut Piwai !
Cet historique des branches supprimées est-il propre à Github ou est-ce inclus de base dans Git ?
J’utilise Git depuis peu (ASI = SVN comme tu le sais) et je commence en effet à me retrouver avec un tas de branches mergées qui polluent le dépôt !
Merci d’avance !&lt;/p&gt;

&lt;h2 id=&quot;piwaï&quot;&gt;&lt;a href=&quot;/contact.html&quot;&gt;Piwaï&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Salut Dvins!&lt;/p&gt;

&lt;p&gt;Github conserve l’historique des “pull request”, pas des “branches supprimées”. Il n’y a pas de notion “d’historique des branches supprimées” dans git. Les branches, tout comme les tags, sont de simples marqueurs sur un graphe, qui identifient des commits particuliers.&lt;/p&gt;

&lt;p&gt;Supprimer une branche, c’est supprimer un marqueur, ni plus ni moins  .&lt;/p&gt;

&lt;p&gt;Par ailleurs, effectivement, les commandes que je donne ici sont des commandes Git, et donc fonctionnent sur n’importe quel repo git.&lt;/p&gt;
</content>
 </entry>
 
 
 
 <entry>
   <title>Sexy dialogs, huhu</title>
   <link href="http://www.piwai.info/2011/10/23/sexy-dialogs-huhu/"/>
   <updated>2011-10-23T20:58:00+00:00</updated>
   <id>http://www.piwai.info/2011/10/23/sexy-dialogs-huhu</id>
   <content type="html">&lt;h2 id=&quot;introduction&quot;&gt;Introduction&lt;/h2&gt;

&lt;p&gt;On reproche souvent aux &lt;strong&gt;applications Android&lt;/strong&gt; d’être… &lt;strong&gt;moches&lt;/strong&gt;. Et ce serait la faute du framework Android, qui fournirait des composants qui n’ont pas la &lt;em&gt;Apple sexy touch&lt;/em&gt;. Peut-être est-ce le cas, mais faudrait voir à ne pas être trop &lt;strong&gt;paresseux&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Prenons le cas des &lt;strong&gt;boîtes de dialogue&lt;/strong&gt;. A priori, il n’y a rien de plus &lt;strong&gt;ennuyeux&lt;/strong&gt;, et rien ne ressemble plus à une boîte de dialogue… qu’une autre boîte de dialogue. Sauf si vous décidez de changer leur style graphique, ce qui risque d’une part de perdre vos utilisateurs, et d’autre part de vous demander du boulot.&lt;/p&gt;

&lt;p&gt;Je vous propose d’aborder quelques techniques simples pour donner &lt;strong&gt;un peu de vie&lt;/strong&gt; à vos &lt;strong&gt;boîtes de dialogues&lt;/strong&gt;, sans trop vous fatiguer.&lt;/p&gt;

&lt;h2 id=&quot;dialogue-fadasse&quot;&gt;Dialogue fadasse&lt;/h2&gt;

&lt;p&gt;Voici un exemple classique de boîte de dialogue :&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;AlertDialog&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;Builder&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
		&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;setMessage&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Un message pas sexy&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
		&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;setPositiveButton&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;android&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;R&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;ok&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;DialogInterface&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;OnClickListener&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
			&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;onClick&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;DialogInterface&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dialog&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;which&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
				&lt;span class=&quot;c1&quot;&gt;// Do something&lt;/span&gt;
			&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
		&lt;span class=&quot;o&quot;&gt;})&lt;/span&gt;
		&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;show&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;&lt;em&gt;Je préfère créer et gérer manuellement mes boîtes de dialogue plutôt qu’utiliser &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;showDialog()&lt;/code&gt; et &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;onCreateDialog()&lt;/code&gt;, que je n’ai jamais réussi à utiliser correctement dès que les cas d’utilisation se corsent.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/static/blog_img/pas_sexy.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;une-vue-custom&quot;&gt;Une vue custom&lt;/h2&gt;

&lt;p&gt;Je vous propose de personnaliser le message affiché par notre boîte de dialogue. Plutôt que &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;setMessage()&lt;/code&gt;, il suffit d’appeller &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;setView()&lt;/code&gt;, qui prend en paramètre n’importe quel type de &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;View&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Par exemple une &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TextView&lt;/code&gt;, définie ici dans un &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;layout&lt;/code&gt; :&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-xml&quot; data-lang=&quot;xml&quot;&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;TextView&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;xmlns:android=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;http://schemas.android.com/apk/res/android&quot;&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;android:layout_width=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;fill_parent&quot;&lt;/span&gt; 
    &lt;span class=&quot;na&quot;&gt;android:layout_height=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;wrap_content&quot;&lt;/span&gt; 
    &lt;span class=&quot;na&quot;&gt;android:textSize=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;30sp&quot;&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;android:padding=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;20dp&quot;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;&lt;em&gt;Petit rappel, vos layouts xml n’ont &lt;strong&gt;aucune raison&lt;/strong&gt; de commencer systématiquement par un &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LinearLayout&lt;/code&gt; ou un &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RelativeLayout&lt;/code&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Ensuite, il suffit de gonfler (&lt;em&gt;inflate&lt;/em&gt; ;)) ce &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;layout&lt;/code&gt;, et de le définir comme vue de la boîte de dialogue :&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;&lt;span class=&quot;nc&quot;&gt;TextView&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;messageView&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;TextView&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;View&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;inflate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;R&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;layout&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;dialog&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;messageView&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;setText&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Un message à peine plus sexy&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;AlertDialog&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;Builder&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;//&lt;/span&gt;
		&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;setView&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;messageView&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;//&lt;/span&gt;
		&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;setPositiveButton&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;android&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;R&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;ok&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;DialogInterface&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;OnClickListener&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
			&lt;span class=&quot;nd&quot;&gt;@Override&lt;/span&gt;
			&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;onClick&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;DialogInterface&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dialog&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;which&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
				&lt;span class=&quot;c1&quot;&gt;// Do something&lt;/span&gt;
			&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
		&lt;span class=&quot;o&quot;&gt;})&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;//&lt;/span&gt;
		&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;show&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;&lt;em&gt;Notez l’utilisation de &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;View.inflate()&lt;/code&gt;, plutôt que &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LayoutInflater.from(context).inflate()&lt;/code&gt;, ou encore &lt;strong&gt;pire&lt;/strong&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;((LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate()&lt;/code&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Et voilà le travail :&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/static/blog_img/sexy1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;un-peu-de-style&quot;&gt;Un peu de style&lt;/h2&gt;

&lt;p&gt;Dans un &lt;a href=&quot;/2011/10/01/un-peu-de-style-dans-la-textview/&quot;&gt;précédent article&lt;/a&gt;, nous avons découvert &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Html.fromHtml()&lt;/code&gt; qui se marie très bien avec une &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TextView&lt;/code&gt;. Mettons-le à profit :&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;&lt;span class=&quot;nc&quot;&gt;TextView&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;messageView&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;TextView&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;View&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;inflate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;R&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;layout&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;dialog&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;CharSequence&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;message&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Html&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;fromHtml&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;I like &amp;lt;b&amp;gt;sexy&amp;lt;/b&amp;gt; &amp;lt;font color=\&quot;#42dd42\&quot;&amp;gt;turtles&amp;lt;/font&amp;gt;!&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;messageView&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;setText&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;&lt;img src=&quot;/static/blog_img/sexy2.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Évidemment, c’est mieux avec l’i18n, ajoutons donc une entrée à &lt;strong&gt;strings.xml&lt;/strong&gt; :&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-xml&quot; data-lang=&quot;xml&quot;&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;resources&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;c&quot;&gt;&amp;lt;!-- ... --&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;string&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;dialog_message&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;![CDATA[I like &amp;lt;b&amp;gt;sexy&amp;lt;/b&amp;gt; &amp;lt;font color=&quot;#42dd42&quot;&amp;gt;turtles&amp;lt;/font&amp;gt;!&quot;]]&amp;gt;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;/string&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/resources&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Et notre code devient :&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;&lt;span class=&quot;nc&quot;&gt;CharSequence&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;message&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Html&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;fromHtml&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;getString&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;R&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;dialog_message&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;et-avec-une-photo-sexy-&quot;&gt;Et avec une photo sexy ?&lt;/h2&gt;

&lt;p&gt;Saviez-vous que &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Html.fromHtml()&lt;/code&gt; supporte la balise &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;img&lt;/code&gt;, et permet de charger des images locales, grâce à un &lt;a href=&quot;http://developer.android.com/reference/android/text/Html.ImageGetter.html&quot;&gt;ImageGetter&lt;/a&gt; ?&lt;/p&gt;

&lt;p&gt;Ajoutons une image à notre message :&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-xml&quot; data-lang=&quot;xml&quot;&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;resources&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;c&quot;&gt;&amp;lt;!-- ... --&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;string&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;dialog_message&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;![CDATA[I like &amp;lt;img src=&quot;turtle&quot; /&amp;gt; &amp;lt;b&amp;gt;sexy&amp;lt;/b&amp;gt; &amp;lt;font color=\&quot;#42dd42\&quot;&amp;gt;turtles&amp;lt;/font&amp;gt;!&quot;]]&amp;gt;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;/string&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/resources&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Ainsi que la &lt;strong&gt;ressource&lt;/strong&gt; correspondante :&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/static/blog_img/turtle_res.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Il n’y a plus qu’à créer un &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ImageGetter&lt;/code&gt; qui sait charger un &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Drawable&lt;/code&gt; à partir de son &lt;strong&gt;nom&lt;/strong&gt; de ressource :&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;&lt;span class=&quot;nc&quot;&gt;ImageGetter&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;imageGetter&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ImageGetter&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;nd&quot;&gt;@Override&lt;/span&gt;
	&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Drawable&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;getDrawable&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;source&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;source&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;replace&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;/&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
		&lt;span class=&quot;nc&quot;&gt;Resources&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;resources&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;getResources&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
		&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;drawableId&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;resources&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getIdentifier&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;drawable&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;getPackageName&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;());&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;drawableId&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
			&lt;span class=&quot;nc&quot;&gt;Drawable&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;drawable&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;resources&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getDrawable&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;drawableId&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
			&lt;span class=&quot;n&quot;&gt;drawable&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;setBounds&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;drawable&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getIntrinsicWidth&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;drawable&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getIntrinsicHeight&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;());&lt;/span&gt;
			&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;drawable&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
		&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
			&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
		&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
	&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;};&lt;/span&gt;

&lt;span class=&quot;nc&quot;&gt;CharSequence&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;message&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Html&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;fromHtml&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;getString&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;R&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;dialog_message&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;imageGetter&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Et le tour est joué :&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://commons.wikimedia.org/wiki/File:Trachemys_scripta_elegans.JPG&quot;&gt;&lt;img src=&quot;/static/blog_img/sexy3.png&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;turtle’s head by Betta.1&lt;/em&gt;&lt;/p&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;Ces quelques lignes de code permettent de &lt;strong&gt;rapidement&lt;/strong&gt; mettre en avant les &lt;strong&gt;informations importantes&lt;/strong&gt; au sein d’une &lt;strong&gt;boîte de dialogue&lt;/strong&gt;, sans pour autant &lt;strong&gt;déstabiliser&lt;/strong&gt; l’utilisateur.&lt;/p&gt;

&lt;p&gt;Bien entendu, &lt;strong&gt;l’abus&lt;/strong&gt; de boîte de dialogues est &lt;strong&gt;dangereux&lt;/strong&gt; pour la santé mentale des utilisateurs, à afficher avec &lt;strong&gt;modération&lt;/strong&gt; !&lt;/p&gt;

&lt;h1 id=&quot;comments&quot;&gt;Comments&lt;/h1&gt;

</content>
 </entry>
 
 
 
 <entry>
   <title>T'as mis à jour les specs ?</title>
   <link href="http://www.piwai.info/2011/10/14/tas-mis-a-jour-les-specs/"/>
   <updated>2011-10-14T20:49:18+00:00</updated>
   <id>http://www.piwai.info/2011/10/14/tas-mis-a-jour-les-specs</id>
   <content type="html">&lt;h2 id=&quot;introduction&quot;&gt;Introduction&lt;/h2&gt;

&lt;p&gt;Il est généralement admis qu’utiliser un système de &lt;strong&gt;gestion de version&lt;/strong&gt; (&lt;strong&gt;décentralisé&lt;/strong&gt; de préférence) pour le &lt;strong&gt;code&lt;/strong&gt; d’un projet est une &lt;strong&gt;bonne chose&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Mais qu’en est-il des documents de &lt;strong&gt;spécifications&lt;/strong&gt; fonctionnelles et techniques ? Loin de l’approche monolithique du cycle en V, les adeptes des &lt;strong&gt;méthodes agiles&lt;/strong&gt; ont à coeur de &lt;strong&gt;faire évoluer&lt;/strong&gt; ces documents très fréquemment. D’aucuns pourraient penser que les posts-it de Scrum remplacent avantageusement tout document de spécification…&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://secure.wikimedia.org/wikipedia/commons/wiki/File:Archaeological_post-it_label_-_geograph.org.uk_-_1303183.jpg&quot;&gt;&lt;img src=&quot;/static/blog_img/Archaeological_post-it_label_-_geograph.org.uk_-_1303183.jpeg&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Archaeological post-it label by Evelyn Simak&lt;/em&gt;&lt;/p&gt;

&lt;h2 id=&quot;versionner-les-spécifications&quot;&gt;Versionner les spécifications&lt;/h2&gt;

&lt;p&gt;N’oubliez pas, &lt;em&gt;être agile&lt;/em&gt; ne constitue pas une excuse pour ne pas écrire de documentation. Pareil pour le &lt;a href=&quot;http://en.wikipedia.org/wiki/Emergent_Design&quot;&gt;design émergeant&lt;/a&gt;. Bien au contraire, il est d’autant plus important de consigner et conserver le savoir fonctionnel et technique.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://secure.wikimedia.org/wikipedia/commons/wiki/File:SteacieLibrary.jpg&quot;&gt;&lt;img src=&quot;/static/blog_img/SteacieLibrary.jpeg&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Steacie Science and Engineering Library at York University, by Raysonho@Open Grid Scheduler&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Vous qui posez un tag sur votre code dans votre système de gestion de version (VCS) lors d’une nouvelle release, êtes-vous capables de retrouver &lt;strong&gt;plus tard&lt;/strong&gt; les spécifications fonctionnelles et techniques correspondant à cette release ?&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/static/blog_img/git_tag.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Un moyen simple pour y parvenir est d’héberger ces documents dans le &lt;strong&gt;même VCS que le code&lt;/strong&gt;. Ainsi, tout tag/branche contiendra automatiquement la bonne version des spécifications.&lt;/p&gt;

&lt;h2 id=&quot;diff-de-specs-&quot;&gt;Diff de specs ?&lt;/h2&gt;

&lt;p&gt;Allons plus loin : un VCS n’a pas pour seul but de conserver l’&lt;strong&gt;historique d’un projet&lt;/strong&gt; ; il permet aussi d’appréhender les &lt;strong&gt;changements&lt;/strong&gt; réalisés, grâce aux outils de &lt;strong&gt;diff&lt;/strong&gt;. C’est évidemment essentiel pour assembler le travail parallèle des différents développeurs, pour comprendre l’origine d’un bug, pour toute revue de code, etc.&lt;/p&gt;

&lt;p&gt;Le problème des outils de diff est qu’ils fonctionnent très bien pour tout ce qui est &lt;strong&gt;textuel&lt;/strong&gt;, et beaucoup moins bien lorsqu’ils ont affaire à des fichiers &lt;strong&gt;binaires&lt;/strong&gt;. Malheureusement, les &lt;strong&gt;documents de spécifications&lt;/strong&gt; sont bien souvent des fichiers &lt;strong&gt;Word&lt;/strong&gt; ou &lt;strong&gt;LibreOffice&lt;/strong&gt;, qui entrent dans cette catégorie.&lt;/p&gt;

&lt;p&gt;Il existe pourtant un format textuel tout à fait adapté: &lt;a href=&quot;http://fr.wikipedia.org/wiki/Markdown&quot;&gt;Markdown&lt;/a&gt;. La syntaxe de ce langage est réellement accessible, même pour les membres non techniques de votre équipe :&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;# Titre du document
## Mon sous titre

Un paragraphe contenant un [lien absolu](http://www.google.com), un
[lien relatif](../autrePage), et une ![image](image.png).

* une liste à puces
* avec une sous liste
  * contenant un élément *en italique*
  * et un élément **en gras**&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;De plus, les documents Markdown peuvent aisément être visualisés en HTML ou PDF, si vous ne disposez pas d’un &lt;a href=&quot;http://mouapp.com/&quot;&gt;éditeur dédié&lt;/a&gt;. Il existe même &lt;a href=&quot;http://freewisdom.org/projects/python-markdown/odt2txt&quot;&gt;des scripts&lt;/a&gt; pour convertir de l’ODT en Markdown.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://www.canalplus.fr/c-divertissement/pid3848-c-bref.html?tab=1&quot;&gt;Bref&lt;/a&gt;, vous n’avez aucune excuse valable ;-).&lt;/p&gt;

&lt;h2 id=&quot;retour-dexpérience&quot;&gt;Retour d’expérience&lt;/h2&gt;

&lt;p&gt;Chez &lt;a href=&quot;http://www.siine.com&quot;&gt;Siine&lt;/a&gt;, nous hébergeons nos projets sur &lt;a href=&quot;http://github.com&quot;&gt;GitHub&lt;/a&gt;, et chaque &lt;strong&gt;User Story&lt;/strong&gt; fait l’objet d’une &lt;a href=&quot;http://blog.piwai.info/2011/10/09/roooh-jai-encore-oublie-ma-branche-git/&quot;&gt;branche dédiée&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Les &lt;strong&gt;spécifications&lt;/strong&gt; fonctionnelles et techniques relatives à une User Story sont écrites en &lt;strong&gt;Markdown&lt;/strong&gt;, sur la &lt;strong&gt;branche dédiée&lt;/strong&gt; à cette User Story.&lt;/p&gt;

&lt;p&gt;Lorsque la &lt;strong&gt;User Story&lt;/strong&gt; est prête à être intégrée sur la branche de développement, le développeur crée une &lt;a href=&quot;http://help.github.com/send-pull-requests/&quot;&gt;pull request&lt;/a&gt;. Il suffit alors d’ouvrir l’onglet &lt;strong&gt;Diff&lt;/strong&gt; de la pull request pour tout de suite identifier les &lt;strong&gt;changements&lt;/strong&gt; fonctionnels et techniques introduits par cette User Story.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/static/blog_img/spec_diff.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;diagrammes&quot;&gt;Diagrammes&lt;/h2&gt;

&lt;p&gt;Tous les &lt;strong&gt;fichiers binaires&lt;/strong&gt; ne peuvent pas forcément être remplacés par des fichiers &lt;strong&gt;textuels&lt;/strong&gt; ; c’est le cas des &lt;strong&gt;diagrammes techniques&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;A moins que… en êtes-vous si sûr ?&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://websequencediagrams.com&quot;&gt;websequencediagrams.com&lt;/a&gt; et &lt;a href=&quot;http://yuml.me&quot;&gt;yuml.me&lt;/a&gt; vous proposent d’exprimer le contenu de vos diagrammes sous forme de texte, et se chargent de générer l’image correspondante.&lt;/p&gt;

&lt;h3 id=&quot;websequencediagrams&quot;&gt;websequencediagrams&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;websequencediagrams&lt;/strong&gt; permet de générer des diagrammes de séquence, et offre même le luxe de choisir le style utilisé.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;UI-&amp;gt;StuffManager: doSomeStuff()
note over StuffManager: HandlesStuff
activate StuffManager
StuffManager-&amp;gt;DataStore:gimmeDaStuff()
activate DataStore
DataStore-&amp;gt;StuffManager:
deactivate DataStore
StuffManager-&amp;gt;DataStore:updateDaStuff()
activate DataStore
DataStore-&amp;gt;StuffManager:
deactivate DataStore
StuffManager--&amp;gt;UI:
deactivate StuffManager&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;&lt;a href=&quot;http://www.websequencediagrams.com/?lz=VUktPlN0dWZmTWFuYWdlcjogZG9Tb21lAA8FKCkKbm90ZSBvdmVyIAAYDkhhbmRsZXMANgUKYWN0aXZhdGUAFw0KAEsMLT5EYXRhU3RvcmU6Z2ltbWVEYQBaCAA0CQAZCQoAIwkAgQ0PCmRlABsTAFAYdXBkYXQAEFktPlVJAIEEDQCCOgw&amp;amp;s=qsd&quot;&gt;&lt;img src=&quot;/static/blog_img/websequencediagrams1.png&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3 id=&quot;yuml&quot;&gt;yUML&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;yUML&lt;/strong&gt; permet de générer des diagrammes UML de &lt;a href=&quot;http://yuml.me/diagram/class/draw&quot;&gt;classe&lt;/a&gt;, d’&lt;a href=&quot;http://yuml.me/diagram/activity/draw&quot;&gt;activité&lt;/a&gt;, et de &lt;a href=&quot;http://yuml.me/diagram/usecase/draw&quot;&gt;cas d’utilisation&lt;/a&gt;.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;[Activity]^[MyActivity]
[MyActivity]-[note: I like turtles!]
[Step]^[FirstStep]
[Step]^[SecondStep]
[Step]^[FinalStep]
[MyActivity]++-&amp;gt;[StateHolder]
[MyActivity]++-*&amp;gt;[Step]
[FirstStep]+-&amp;gt;[StateHolder]
[SecondStep]+-&amp;gt;[StateHolder]&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;&lt;a href=&quot;http://yuml.me/diagram/class/[Activity]^[MyActivity], [MyActivity]-[note: I like turtles!], [Step]^[FirstStep], [Step]^[SecondStep], [Step]^[FinalStep], [MyActivity]++-&amp;gt;[StateHolder], [MyActivity]++-*&amp;gt;[Step], [FirstStep]+-&amp;gt;[StateHolder], [SecondStep]+-&amp;gt;[StateHolder].&quot;&gt;&lt;img src=&quot;/static/blog_img/yuml_class.png&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Connaissez-vous d’autres outils bien pratiques de ce type ?&lt;/p&gt;

&lt;h1 id=&quot;comments&quot;&gt;Comments&lt;/h1&gt;

&lt;h2 id=&quot;maxime-sinclair&quot;&gt;&lt;a href=&quot;http://eclectic.eklablog.com/&quot;&gt;Maxime Sinclair&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;Tout à fait en ligne avec ton article. Ce qu’il faut versionner, c’est le produit logiciel. Et le logiciel ce n’est pas juste du code, c’est aussi l’ensemble de la documentation associée (spécification, cahier de tests, manuel utilisateur,…).&lt;/p&gt;

&lt;p&gt;Pour la documentation, il faut savoir que Word propose un mode différentiel où il affiche les différences sous la forme de marques de révision. Je me souviens que ceci marchait très bien avec TortoiseSVN.
En ce qui concerne les diagrammes, il y a &lt;a href=&quot;http://plantuml.sourceforge.net&quot;&gt;PlantUML&lt;/a&gt; qui supporte tous les diagrammes UML mais aussi les diagrammes &lt;a href=&quot;http://ditaa.sourceforge.net&quot;&gt;Ditaa&lt;/a&gt;, qui est aussi disponible en mode cloud et, ce qui ne gâte rien, qui est open source.
Allez, un petit &lt;a href=&quot;http://www.plantuml.com/plantuml/img/AovDoSyk1G00&quot;&gt;sudoku&lt;/a&gt; pour conclure.&lt;/p&gt;

&lt;h2 id=&quot;piwaï&quot;&gt;&lt;a href=&quot;/contact.html&quot;&gt;Piwaï&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Merci Maxime pour le complément d’info, je ne connaissais pas ces deux derniers !&lt;/p&gt;
</content>
 </entry>
 
 
 
 <entry>
   <title>Roooh, j'ai encore oublié ma branche Git !</title>
   <link href="http://www.piwai.info/2011/10/09/roooh-jai-encore-oublie-ma-branche-git/"/>
   <updated>2011-10-09T08:15:31+00:00</updated>
   <id>http://www.piwai.info/2011/10/09/roooh-jai-encore-oublie-ma-branche-git</id>
   <content type="html">&lt;h2 id=&quot;introduction&quot;&gt;Introduction&lt;/h2&gt;

&lt;p&gt;La &lt;strong&gt;startup&lt;/strong&gt; pour laquelle je bosse &lt;a href=&quot;/2011/08/31/whenpiwai-quitexcilys-thenreturnnew-blog/&quot;&gt;depuis peu&lt;/a&gt; héberge son &lt;strong&gt;code source&lt;/strong&gt; sur &lt;a href=&quot;http://github.com&quot;&gt;GitHub&lt;/a&gt;, et ça, c’est carrément cool.&lt;/p&gt;

&lt;p&gt;En plus, nous sommes récemment passé d’un &lt;strong&gt;workflow&lt;/strong&gt; old school (tout le monde commit comme des sauvages sur la même branche) à un workflow de type &lt;a href=&quot;http://nvie.com/posts/a-successful-git-branching-model&quot;&gt;feature branching&lt;/a&gt;. Encore plus cool !&lt;/p&gt;

&lt;p&gt;Le merge d’une &lt;strong&gt;feature branch&lt;/strong&gt; sur la branche d’&lt;strong&gt;intégration&lt;/strong&gt; ne se fait qu’après &lt;strong&gt;validation&lt;/strong&gt; (revue de code et tests fonctionnels) par quelqu’un qui n’a pas développé la feature. Dans cette optique, les &lt;a href=&quot;http://help.github.com/send-pull-requests/&quot;&gt;pull requests&lt;/a&gt; de GitHub se révèlent particulièrement pratiques.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/static/blog_img/pull_request.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Mais trêve de bavardage, venons-en à l’objet de cet article.&lt;/p&gt;

&lt;h2 id=&quot;roooh-jai-encore-oublié-ma-branche-git-&quot;&gt;Roooh, j’ai encore oublié ma branche Git !&lt;/h2&gt;

&lt;p&gt;Avec le &lt;strong&gt;feature branching&lt;/strong&gt;, on se retrouve à changer fréquemment de branche.&lt;/p&gt;

&lt;p&gt;Du coup, j’ai tendance à ne plus savoir sur &lt;strong&gt;quelle branche je me trouve&lt;/strong&gt;, ou encore à oublier le nom précis de la branche, et à taper &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git branch&lt;/code&gt; toutes les trois commandes.&lt;/p&gt;

&lt;p&gt;Un membre de l’équipe nous a envoyé un &lt;strong&gt;script&lt;/strong&gt; plutôt pratique, qui ajoute le &lt;strong&gt;nom de la branche&lt;/strong&gt; en cours au prompt de votre terminal :&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/static/blog_img/terminal.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Le petit truc cool en plus, c’est que le nom s’affiche en &lt;strong&gt;rouge&lt;/strong&gt; si vous avez des &lt;strong&gt;modifications locales&lt;/strong&gt; (dirty working tree), et en &lt;strong&gt;vert&lt;/strong&gt; dans le cas contraire.&lt;/p&gt;

&lt;p&gt;Instructions à ajouter à votre fichier &lt;strong&gt;~/.bashrc&lt;/strong&gt; (ou &lt;strong&gt;~/.profile&lt;/strong&gt; sur Mac) :&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;# git branch name in prompt&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;c_red&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sb&quot;&gt;`&lt;/span&gt;tput setaf 1&lt;span class=&quot;sb&quot;&gt;`&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;c_green&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sb&quot;&gt;`&lt;/span&gt;tput setaf 2&lt;span class=&quot;sb&quot;&gt;`&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;c_sgr0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sb&quot;&gt;`&lt;/span&gt;tput sgr0&lt;span class=&quot;sb&quot;&gt;`&lt;/span&gt;

parse_git_branch &lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;if &lt;/span&gt;git rev-parse &lt;span class=&quot;nt&quot;&gt;--git-dir&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;/dev/null 2&amp;gt;&amp;amp;1
  &lt;span class=&quot;k&quot;&gt;then
          &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;gitver&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;$(&lt;/span&gt;git branch 2&amp;gt;/dev/null| &lt;span class=&quot;nb&quot;&gt;sed&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-n&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'/^\*/s/^\* //p'&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;else
          return &lt;/span&gt;0
  &lt;span class=&quot;k&quot;&gt;fi
  &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-e&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$gitver&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;) &quot;&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

branch_color &lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if &lt;/span&gt;git rev-parse &lt;span class=&quot;nt&quot;&gt;--git-dir&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;/dev/null 2&amp;gt;&amp;amp;1
        &lt;span class=&quot;k&quot;&gt;then
                &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;color&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&quot;&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;if &lt;/span&gt;git diff &lt;span class=&quot;nt&quot;&gt;--quiet&lt;/span&gt; 2&amp;gt;/dev/null &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&amp;amp;2
                &lt;span class=&quot;k&quot;&gt;then
                        &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;color&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;c_green&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;else
                        &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;color&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;c_red&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;fi
        else
                return &lt;/span&gt;0
        &lt;span class=&quot;k&quot;&gt;fi
        &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-ne&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$color&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;nv&quot;&gt;PS1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\[\$&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;(branch_color)&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\]\$&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;(parse_git_branch)&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\[&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;$(&lt;/span&gt;tput sgr0&lt;span class=&quot;si&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\]&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$PS1&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Dans le même ordre d’idée, voici un &lt;a href=&quot;http://www.codethatmatters.com/2010/01/git-autocomplete-in-mac-os-x/&quot;&gt;article bien pratique&lt;/a&gt; pour disposer de l’autocomplétion des noms de branches.&lt;/p&gt;

&lt;p&gt;À vous, partagez vos astuces ;-) !&lt;/p&gt;

&lt;h1 id=&quot;comments&quot;&gt;Comments&lt;/h1&gt;

&lt;h2 id=&quot;olivier-bazoud&quot;&gt;&lt;a href=&quot;http://www.twitter.com/obazoud&quot;&gt;Olivier Bazoud&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Je préfère utiliser celui ci livré par Git, utiliser la variable __git_ps1 et en plus ça gère beaucoup plus de cas (modifications locales, fichier non trackes, stash, uptream, commit locaux, commits remote, …)&lt;/p&gt;

&lt;p&gt;Dans mon ~/.bashrc:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-f&lt;/span&gt; /etc/bash_completion.d/git &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;then&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;.&lt;/span&gt; /etc/bash_completion.d/git
&lt;span class=&quot;k&quot;&gt;fi
&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;GIT_PS1_SHOWDIRTYSTATE&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;true
&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;GIT_PS1_SHOWSTASHSTATE&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;true
&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;GIT_PS1_SHOWUNTRACKEDFILES&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;true
&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;GIT_PS1_SHOWUPSTREAM&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;verbose&quot;&lt;/span&gt;

&lt;span class=&quot;nv&quot;&gt;PS1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'\A [${debian_chroot:+($debian_chroot)}\[33[01;32m\]\u@\[33[0;33m\]\h\[33[00m\]]\[33[01;31m\]$(__git_ps1)\[33[00m\]% '&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;@obazoud&lt;/p&gt;

&lt;h2 id=&quot;piwaï&quot;&gt;&lt;a href=&quot;/contact.html&quot;&gt;Piwaï&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;Merci Olivier, j’avais découvert &lt;strong&gt;bash_completion.d&lt;/strong&gt; dans l’&lt;a href=&quot;http://www.codethatmatters.com/2010/01/git-autocomplete-in-mac-os-x/&quot;&gt;article&lt;/a&gt; cité plus haut, mais je n’avais pas testé la partie modification du PS1.&lt;/p&gt;

&lt;p&gt;Je m’en vais essayer ça de ce pas !&lt;/p&gt;

&lt;p&gt;PS : je me suis permis d’ajouter la coloration syntaxique à ton commentaire ;).&lt;/p&gt;

&lt;h2 id=&quot;sam-bessalah-samklr&quot;&gt;&lt;a href=&quot;http://twitter.com/samklr&quot;&gt;Sam Bessalah (@samklr)&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;Ou bien tu peux utiliser &lt;a href=&quot;https://github.com/robbyrussell/oh-my-zsh&quot;&gt;oh-my-zsh&lt;/a&gt;, qui prend en compte git nativement et t’averti dans quelle branche tu te trouves, etc ..
En tout cas impossible d’utiliser le shell sans, pour moi.&lt;/p&gt;

&lt;h2 id=&quot;piwaï-1&quot;&gt;&lt;a href=&quot;/contact.html&quot;&gt;Piwaï&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;@Olivier : après avoir testé, c’est effectivement pas mal mais il manque la couleur :).&lt;/p&gt;

&lt;p&gt;@Sam : depuis le temps qu’un de mes potes me bassine avec ZSH, je crois que c’est l’occasion de tester :).&lt;/p&gt;

&lt;h2 id=&quot;sam-bessalah-samklr-1&quot;&gt;&lt;a href=&quot;http://twitter.com/samklr&quot;&gt;Sam Bessalah (@samklr)&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;Tu devrais, j’étais dubitatif moi aussi, mais là côté productivité on fais pas mieux. :)&lt;/p&gt;

&lt;h2 id=&quot;piwaï-2&quot;&gt;&lt;a href=&quot;/contact.html&quot;&gt;Piwaï&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;Merci Sam, ça fait à peine 40 minutes, je sais que j’ai déjà switché définitivement vers ZSH :). oh-my-zsh est magique, et les themes dispos sont bien sympas :).&lt;/p&gt;

&lt;h2 id=&quot;hugoch&quot;&gt;&lt;a href=&quot;http://gravatar.com/hugoch&quot;&gt;hugoch&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Ah c’est assez niquel ! Merci pour l’astuce.
A quand un article sur zsh du coup ?!&lt;/p&gt;

&lt;h2 id=&quot;piwaï-3&quot;&gt;&lt;a href=&quot;/contact.html&quot;&gt;Piwaï&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Oh, pas vraiment besoin d’un article, en gros ça marche comme bash mais en mieux, et il suffit de suivre les instructions du &lt;a href=&quot;https://github.com/robbyrussell/oh-my-zsh&quot;&gt;lien&lt;/a&gt; donné par @samklr pour démarrer ;).&lt;/p&gt;
</content>
 </entry>
 
 
 
 <entry>
   <title>Un peu de style dans la TextView</title>
   <link href="http://www.piwai.info/2011/10/01/un-peu-de-style-dans-la-textview/"/>
   <updated>2011-10-01T11:00:41+00:00</updated>
   <id>http://www.piwai.info/2011/10/01/un-peu-de-style-dans-la-textview</id>
   <content type="html">&lt;p&gt;Les designers qui définissent les écrans de votre &lt;strong&gt;application Android&lt;/strong&gt; se sont fait plaisir, et vous ont demandé une &lt;strong&gt;mise en forme&lt;/strong&gt; bien chiadée pour les &lt;strong&gt;textes&lt;/strong&gt; de votre application.&lt;/p&gt;

&lt;p&gt;Avant de vous jeter sur Photoshop pour créer des images correspondant au pixel près à ce qu’ils attendent, pourquoi ne pas garder votre bonne vieille &lt;a href=&quot;http://developer.android.com/reference/android/widget/TextView.html&quot;&gt;TextView&lt;/a&gt; ?&lt;/p&gt;

&lt;p&gt;Pour changer un peu des récents articles sur GWT, voici quelques petites astuces pour Android.&lt;/p&gt;

&lt;h2 id=&quot;tweak-la-police&quot;&gt;Tweak la police&lt;/h2&gt;

&lt;p&gt;Par défaut, Android ne propose que trois polices de caractères pour les TextView : &lt;strong&gt;monospace&lt;/strong&gt;, &lt;strong&gt;sans&lt;/strong&gt; et &lt;strong&gt;serif&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Toutefois, il est tout à fait possible d’utiliser votre police préférée, à condition de l’&lt;strong&gt;embarquer&lt;/strong&gt; dans votre application.&lt;/p&gt;

&lt;p&gt;Il suffit de copier la police dans le répertoire &lt;strong&gt;assets&lt;/strong&gt; de votre projet Android, puis de la charger &lt;strong&gt;au Runtime&lt;/strong&gt; :&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;&lt;span class=&quot;nd&quot;&gt;@Override&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;protected&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;onCreate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Bundle&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;savedInstanceState&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{.&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;super&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;onCreate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;savedInstanceState&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;

  &lt;span class=&quot;n&quot;&gt;setContentView&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;R&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;layout&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;nc&quot;&gt;TextView&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;myTextView&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;TextView&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;findViewById&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;R&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;myTextView&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;

  &lt;span class=&quot;nc&quot;&gt;Typeface&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;myFont&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Typeface&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;createFromAsset&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;getAssets&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;MyFont.otf&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;myTextView&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;setTypeface&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;myFont&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Il n’est pas possible de le faire directement dans votre fichier de layout, sauf en créant des &lt;a href=&quot;http://stackoverflow.com/questions/2973270/using-a-custom-typeface-in-android/5185587#5185587&quot;&gt;composants alternatifs&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;stylé-&quot;&gt;Stylé !&lt;/h2&gt;

&lt;p&gt;Votre texte doit comporter des morceaux en couleur, en italique… ; bref, il doit être &lt;strong&gt;mis en forme&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Avant d’envisager la création d’une TextView pour chaque morceau de texte différent, jetez un oeil à &lt;a href=&quot;http://developer.android.com/reference/android/text/Spannable.html&quot;&gt;Spannable&lt;/a&gt;, et surtout à son cousin germain &lt;a href=&quot;http://developer.android.com/reference/android/text/Html.html&quot;&gt;Html&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://developer.android.com/reference/android/text/Html.html#fromHtml%28java.lang.String%29&quot;&gt;Html.fromHtml()&lt;/a&gt; retourne un &lt;a href=&quot;http://developer.android.com/reference/android/text/Spanned.html&quot;&gt;Spanned&lt;/a&gt;, qui peut être utilisé pour définir le contenu d’une TextView.&lt;/p&gt;

&lt;p&gt;Par exemple :&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;&lt;span class=&quot;nc&quot;&gt;Spanned&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;spanned&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Html&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;fromHtml&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Hello &amp;lt;b&amp;gt;World&amp;lt;/b&amp;gt;!&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;myTextView&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;setText&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;spanned&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Bien entendu, une &lt;strong&gt;String&lt;/strong&gt; en dur dans le code, &lt;strong&gt;c’est moche&lt;/strong&gt; (pas très &lt;a href=&quot;http://en.wikipedia.org/wiki/Internationalization_and_localization&quot;&gt;i18n&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;Pour y remédier, il suffit d’encadrer dans un &lt;strong&gt;CDATA&lt;/strong&gt; le texte contenant le markup Html, au sein de vos fichiers de ressources.&lt;/p&gt;

&lt;p&gt;Exemple de &lt;em&gt;res/values/strings.xml&lt;/em&gt; :&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-xml&quot; data-lang=&quot;xml&quot;&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;resources&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;string&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;styled_content&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;![CDATA[I like turtles!&amp;lt;br /&amp;gt;Hello &amp;lt;font color=&quot;#99cc33&quot;&amp;gt;&amp;lt;b&amp;gt;World&amp;lt;/b&amp;gt;&amp;lt;/font&amp;gt;!]]&amp;gt;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;/string&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/resources&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Malheureusement, vous ne pouvez pas utiliser ces ressources directement dans vos fichiers de &lt;strong&gt;layout&lt;/strong&gt; ; il faut en passer par du &lt;strong&gt;code Java&lt;/strong&gt; :&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;&lt;span class=&quot;nd&quot;&gt;@Override&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;protected&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;onCreate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Bundle&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;savedInstanceState&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{.&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;super&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;onCreate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;savedInstanceState&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;

  &lt;span class=&quot;n&quot;&gt;setContentView&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;R&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;layout&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;nc&quot;&gt;TextView&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;myTextView&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;TextView&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;findViewById&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;R&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;myTextView&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;

  &lt;span class=&quot;n&quot;&gt;myTextView&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;setText&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Html&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;fromHtml&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;getString&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;R&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;styled_content&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)));&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Notez que le support du HTML reste &lt;strong&gt;limité&lt;/strong&gt; (nombre de balises supportées, HTML mal formé, balises les unes dans les autres…)&lt;/p&gt;

&lt;h2 id=&quot;bonus&quot;&gt;Bonus&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Linkify&lt;/strong&gt; permet de créer des TextViews contenant des liens cliquables de toute sorte. A ce sujet, je vous recommande l’&lt;a href=&quot;http://developer.android.com/resources/articles/wikinotes-linkify.html&quot;&gt;excellent article&lt;/a&gt; disponible sur la doc Android.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Quels liens entre design Web et design Android ? Un &lt;a href=&quot;http://android-developers.blogspot.com/2011/09/thinking-like-web-designer.html&quot;&gt;article tout récent&lt;/a&gt; sur le blog Android aborde le sujet.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;comments&quot;&gt;Comments&lt;/h1&gt;

</content>
 </entry>
 
 
 
 <entry>
   <title>Quand mamie craque du Wifi</title>
   <link href="http://www.piwai.info/2011/09/23/quand-mamie-craque-du-wifi/"/>
   <updated>2011-09-23T00:35:02+00:00</updated>
   <id>http://www.piwai.info/2011/09/23/quand-mamie-craque-du-wifi</id>
   <content type="html">&lt;p&gt;Imaginons que vous ayez besoin de &lt;strong&gt;craquer&lt;/strong&gt; le mot de passe de votre propre réseau Wifi, protégé par une &lt;strong&gt;clé WEP&lt;/strong&gt;. Je parle bien de &lt;em&gt;votre propre réseau Wifi&lt;/em&gt;, car je suis sûr qu’il ne vous viendrait jamais à l’idée de craquer l’accès de votre voisin, sachant que c’est totalement &lt;strong&gt;illégal&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Craquer une clé WEP peut être l’affaire de quelques minutes, et pourtant, aujourd’hui encore, de très nombreux réseaux Wifi de particuliers sont protégés par WEP. Même le &lt;a href=&quot;http://www.nytimes.com/2011/02/17/technology/personaltech/17basics.html&quot;&gt;New York Times&lt;/a&gt; en parle. Faites passer le mot, il faut que cela change.&lt;/p&gt;

&lt;p&gt;Les techniques pour y parvenir se sont considérablement améliorées ces dernières années. Parallèlement à ces techniques, c’est aussi leur facilité de mise en œuvre qui a formidablement évolué.&lt;/p&gt;

&lt;p&gt;Aujourd’hui, quelques clics suffisent : même &lt;strong&gt;mamie peut craquer du Wifi&lt;/strong&gt;, et c’est l’objet de cet article.&lt;/p&gt;

&lt;h2 id=&quot;mise-en-place&quot;&gt;Mise en place&lt;/h2&gt;

&lt;h3 id=&quot;matos&quot;&gt;Matos&lt;/h3&gt;

&lt;p&gt;En termes de matériel, une carte Wifi suffit. La plupart des cartes conviennent et disposent aujourd’hui de drivers adaptés.&lt;/p&gt;

&lt;p&gt;Vous obtiendrez de très bons résultats avec l’&lt;a href=&quot;http://www.amazon.com/s/ref=nb_sb_noss?url=search-alias%3Daps&amp;amp;field-keywords=AWUS036H&amp;amp;x=0&amp;amp;y=0&quot;&gt;Alfa AWUS036H&lt;/a&gt;, a priori la carte la plus puissante du marché (1000mW). Attention par contre, il me semble qu’elle est interdite à la vente en France, effet micro onde garanti ;-).&lt;/p&gt;

&lt;h3 id=&quot;os&quot;&gt;OS&lt;/h3&gt;

&lt;p&gt;Les drivers patchés pour le crack Wifi sont essentiellement disponibles sous Linux. Plus précisément, la distribution &lt;a href=&quot;http://www.backtrack-linux.org/downloads/&quot;&gt;Backtrack&lt;/a&gt; contient tout le nécessaire. Elle est disponible en &lt;strong&gt;Live CD&lt;/strong&gt; et en &lt;strong&gt;Live USB&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Version mamie : vous trouvez une clé USB avec quelques gigas de libres ; vous suivez &lt;a href=&quot;http://www.backtrack-linux.org/tutorials/usb-live-install/&quot;&gt;ce tutoriel&lt;/a&gt; ; vous branchez la clé USB ; et vous redémarrez pour booter sur la clé USB (cf. &lt;a href=&quot;http://www.siteduzero.com/tutoriel-3-12696-tester-et-installer-ubuntu.html#ss_part_2&quot;&gt;ce tutoriel&lt;/a&gt; &amp;gt; &lt;strong&gt;Modifier l’ordre de boot&lt;/strong&gt;).&lt;/p&gt;

&lt;p&gt;Backtrack démarre, se logue tout seul, et présente une ligne de commande une fois démarré.&lt;/p&gt;

&lt;p&gt;Il suffit de taper &lt;strong&gt;startx&lt;/strong&gt; pour lancer l’environnement graphique.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;root@root:~# startx&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;&lt;em&gt;Notez que le layout de clavier étant par défaut un qwerty, il vous faudra probablement taper &lt;strong&gt;stqrtx&lt;/strong&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Une fois l’environnement graphique démarré, vous pouvez changer le layout de clavier dans &lt;em&gt;System &amp;gt; Preferences &amp;gt; Keyboard &amp;gt; Layouts&lt;/em&gt;.&lt;/p&gt;

&lt;h2 id=&quot;wifite--à-un-clic-du-crack&quot;&gt;Wifite : à un clic du crack&lt;/h2&gt;

&lt;p&gt;Le plus dur est fait ! Il ne vous reste plus qu’à récupérer &lt;a href=&quot;http://code.google.com/p/wifite/&quot;&gt;Wifite&lt;/a&gt; et le lancer.&lt;/p&gt;

&lt;p&gt;Téléchargez le script python à cette adresse : &lt;a href=&quot;http://wifite.googlecode.com/svn/trunk/wifite.py&quot;&gt;http://wifite.googlecode.com/svn/trunk/wifite.py&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Rendez-le exécutable : &lt;strong&gt;chmod +x&lt;/strong&gt; ; ou bien clic-droit sur le fichier, sélectionnez &lt;em&gt;Properties &amp;gt; Permissions&lt;/em&gt; et cochez
z &lt;em&gt;Execute: Allow executing file as program&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Exécutez le script (double clic sur le fichier &amp;gt; &lt;em&gt;Run&lt;/em&gt;).&lt;/p&gt;

&lt;p&gt;Et hop, une bonne grosse interface à la &lt;strong&gt;clicouille&lt;/strong&gt; :&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/static/blog_img/wifite1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Sélectionnez l’interface réseau à utiliser (en général, il n’y en a qu’une). Étant donné que l’on s’intéresse ici au WEP, vous pouvez sélectionner uniquement &lt;em&gt;WEP&lt;/em&gt; dans &lt;em&gt;encryption type&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;De &lt;a href=&quot;http://code.google.com/p/wifite/&quot;&gt;nombreux paramètres&lt;/a&gt; sont disponibles, mais &lt;strong&gt;pour mamie&lt;/strong&gt;, il suffit de cliquer sur &lt;strong&gt;h4x0r 1t n40&lt;/strong&gt;, et d’aller &lt;strong&gt;prendre une tisane&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/static/blog_img/wifite2.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Wifite se charge de tout, et note les mots de passe crackés dans le fichier &lt;strong&gt;log.txt&lt;/strong&gt; créé à côté du script &lt;strong&gt;wifite.py&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/static/blog_img/wifite3.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bingo !&lt;/strong&gt;&lt;/p&gt;

&lt;h1 id=&quot;comments&quot;&gt;Comments&lt;/h1&gt;

&lt;h2 id=&quot;rémi&quot;&gt;Rémi&lt;/h2&gt;
&lt;p&gt;J’attendais avec impatience que quelqu’un fasse ce travail! Très intéressant en tout cas. Je me permets de m’abonner à ton flux RSS du coup.&lt;/p&gt;

&lt;h2 id=&quot;piwaï&quot;&gt;&lt;a href=&quot;/contact.html&quot;&gt;Piwaï&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Je t’y autorise avec plaisir&lt;/p&gt;

&lt;h2 id=&quot;bastien&quot;&gt;&lt;a href=&quot;http://blog.excilys.com/&quot;&gt;Bastien&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;C’est un peu dommage, du coup ça devient une boite noire à la IIS. On clique sur un bouton et ça fait tout, mais on sait pas vraiment ce que ça fait. Les plus intéressés devraient plutôt se tourner vers aerodump et cie, avec masse de tutos qui explique ce que ça fait, les différentes attaques etc.&lt;/p&gt;

&lt;h2 id=&quot;piwaï-1&quot;&gt;&lt;a href=&quot;/contact.html&quot;&gt;Piwaï&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Certes, mais Mamie n’en a rien à carrer de comprendre ce que ça fait ;-). Elle veut juste craquer son Wifi, elle est comme ça Mamie.&lt;/p&gt;
</content>
 </entry>
 
 
 
 <entry>
   <title>Les mains dans le cambUiBinder</title>
   <link href="http://www.piwai.info/2011/09/13/les-mains-dans-le-cambuibinder/"/>
   <updated>2011-09-13T08:13:02+00:00</updated>
   <id>http://www.piwai.info/2011/09/13/les-mains-dans-le-cambuibinder</id>
   <content type="html">&lt;p&gt;L’article précédent montrait comment faire de la &lt;a href=&quot;http://blog.piwai.info/2011/09/05/coloration-syntaxique-en-gwt/&quot;&gt;coloration syntaxique en GWT&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Toujours pour &lt;a href=&quot;http://pyricau.github.com/rockslide&quot;&gt;Rockslide&lt;/a&gt;, je souhaitais pouvoir écrire le code à mettre en forme dans des &lt;strong&gt;templates&lt;/strong&gt; &lt;a href=&quot;http://code.google.com/webtoolkit/doc/latest/DevGuideUiBinder.html&quot;&gt;UiBinder&lt;/a&gt;, plutôt que dans des Strings statiques portées par des classes Java.&lt;/p&gt;

&lt;p&gt;Est-ce possible ? Comment y parvenir ? En creusant ces questions, j’ai réalisé que UiBinder possède de nombreuses facettes &lt;strong&gt;non documentées&lt;/strong&gt; et qui méritent que l’on s’y attarde. Tour du propriétaire.&lt;/p&gt;

&lt;h2 id=&quot;widgets-customs&quot;&gt;Widgets customs&lt;/h2&gt;

&lt;p&gt;Vous le savez probablement, il est possible d’inclure ses propres widgets GWT dans un template UiBinder.&lt;/p&gt;

&lt;p&gt;Il suffit pour cela d’étendre la classe &lt;strong&gt;Widget&lt;/strong&gt;. Prenons l’exemple d’un bouton ouvrant une fenêtre d’alerte :&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;AlertButton&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Button&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;implements&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ClickHandler&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;

	&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;AlertButton&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;addClickHandler&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
	&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

	&lt;span class=&quot;nd&quot;&gt;@Override&lt;/span&gt;
	&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;onClick&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;ClickEvent&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;nc&quot;&gt;Window&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;alert&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;I like turtles&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
	&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Vous pouvez ensuite l’inclure dans vos templates UiBinder, en ajoutant un &lt;strong&gt;namespace&lt;/strong&gt; correspondant au &lt;strong&gt;package&lt;/strong&gt; de votre widget :&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-xml&quot; data-lang=&quot;xml&quot;&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;ui:UiBinder&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;xmlns:ui=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'urn:ui:com.google.gwt.uibinder'&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;xmlns:g=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'urn:import:com.google.gwt.user.client.ui'&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;xmlns:custom=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'urn:import:info.piwai.blog.ui'&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;

	&lt;span class=&quot;nt&quot;&gt;&amp;lt;g:FlowPanel&amp;gt;&lt;/span&gt;
		&lt;span class=&quot;nt&quot;&gt;&amp;lt;custom:AlertButton&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
	&lt;span class=&quot;nt&quot;&gt;&amp;lt;/g:FlowPanel&amp;gt;&lt;/span&gt;

&lt;span class=&quot;nt&quot;&gt;&amp;lt;/ui:UiBinder&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Un peu limité quand même…&lt;/p&gt;

&lt;h2 id=&quot;et-avec-des-paramètres-&quot;&gt;Et avec des paramètres ?&lt;/h2&gt;

&lt;p&gt;Il y a mieux ! Vous pouvez tout à fait passer des paramètres à votre widget. Il suffit d’ajouter des paramètres de &lt;strong&gt;constructeur&lt;/strong&gt; (donc obligatoires) ou des &lt;strong&gt;setters&lt;/strong&gt; (donc facultatifs) à votre widget :&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;AlertButton&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Button&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;implements&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ClickHandler&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;

	&lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;final&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;

	&lt;span class=&quot;nd&quot;&gt;@UiConstructor&lt;/span&gt;
	&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;AlertButton&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;msg&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;addClickHandler&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
	&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

	&lt;span class=&quot;nd&quot;&gt;@Override&lt;/span&gt;
	&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;onClick&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;ClickEvent&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;nc&quot;&gt;Window&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;alert&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
	&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;&lt;em&gt;Notez la présence de &lt;strong&gt;@UiConstructor&lt;/strong&gt;, nécessaire lorsque le constructeur par défaut n’est pas défini.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Puis d’utiliser les &lt;strong&gt;attributs correspondants&lt;/strong&gt; dans vos templates UiBinder :&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-xml&quot; data-lang=&quot;xml&quot;&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;ui:UiBinder&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;xmlns:ui=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'urn:ui:com.google.gwt.uibinder'&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;xmlns:g=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'urn:import:com.google.gwt.user.client.ui'&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;xmlns:custom=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'urn:import:info.piwai.blog.ui'&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;

	&lt;span class=&quot;nt&quot;&gt;&amp;lt;g:FlowPanel&amp;gt;&lt;/span&gt;
		&lt;span class=&quot;nt&quot;&gt;&amp;lt;custom:AlertButton&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;msg=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;I like turtles&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
	&lt;span class=&quot;nt&quot;&gt;&amp;lt;/g:FlowPanel&amp;gt;&lt;/span&gt;

&lt;span class=&quot;nt&quot;&gt;&amp;lt;/ui:UiBinder&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;les-attributs-ça-pue-&quot;&gt;Les attributs, ça pue ?&lt;/h2&gt;

&lt;p&gt;Si votre widget implémente &lt;a href=&quot;http://google-web-toolkit.googlecode.com/svn/javadoc/latest/com/google/gwt/user/client/ui/HasText.html&quot;&gt;HasText&lt;/a&gt;, vous pourrez alors définir ce texte directement au &lt;strong&gt;sein de la balise&lt;/strong&gt; au lieu d’utiliser des &lt;strong&gt;attributs&lt;/strong&gt;. Modifions &lt;strong&gt;AlertButton&lt;/strong&gt; :&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;AlertButton&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Button&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;implements&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ClickHandler&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;HasText&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;

	&lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Default Message&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;

	&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;AlertButton&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;addClickHandler&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
	&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

	&lt;span class=&quot;nd&quot;&gt;@Override&lt;/span&gt;
	&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;setText&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;msg&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

	&lt;span class=&quot;nd&quot;&gt;@Override&lt;/span&gt;
	&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;onClick&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;ClickEvent&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;nc&quot;&gt;Window&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;alert&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
	&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

	&lt;span class=&quot;nd&quot;&gt;@Override&lt;/span&gt;
	&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;getText&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;UnsupportedOperationException&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
	&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;&lt;em&gt;Notez que l’interface &lt;strong&gt;HasText&lt;/strong&gt; impose d’implémenter &lt;strong&gt;getText()&lt;/strong&gt;, mais cette méthode n’est pas nécessaire pour nos besoins.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;C’est déjà plus sympa :&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-xml&quot; data-lang=&quot;xml&quot;&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;ui:UiBinder&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;xmlns:ui=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'urn:ui:com.google.gwt.uibinder'&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;xmlns:g=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'urn:import:com.google.gwt.user.client.ui'&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;xmlns:custom=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'urn:import:info.piwai.blog.ui'&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;

	&lt;span class=&quot;nt&quot;&gt;&amp;lt;g:FlowPanel&amp;gt;&lt;/span&gt;
		&lt;span class=&quot;nt&quot;&gt;&amp;lt;custom:AlertButton&amp;gt;&lt;/span&gt;I like turtles&lt;span class=&quot;nt&quot;&gt;&amp;lt;/custom:AlertButton&amp;gt;&lt;/span&gt;
	&lt;span class=&quot;nt&quot;&gt;&amp;lt;/g:FlowPanel&amp;gt;&lt;/span&gt;

&lt;span class=&quot;nt&quot;&gt;&amp;lt;/ui:UiBinder&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;quid-du-html-&quot;&gt;Quid du HTML ?&lt;/h2&gt;

&lt;p&gt;Vous pouvez aussi inclure, au sein de vos widgets, du HTML défini dans votre template UiBinder, grâce à &lt;a href=&quot;http://google-web-toolkit.googlecode.com/svn/javadoc/latest/com/google/gwt/user/client/ui/HasHTML.html&quot;&gt;HasHTML&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Par exemple, supposons que je souhaite enrichir mon &lt;strong&gt;AlertButton&lt;/strong&gt; pour afficher de belles popups, en utilisant une &lt;a href=&quot;http://google-web-toolkit.googlecode.com/svn/javadoc/latest/com/google/gwt/user/client/ui/DialogBox.html&quot;&gt;DialogBox&lt;/a&gt; :&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;AlertButton&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Button&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;implements&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ClickHandler&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;HasHTML&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;

	&lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;html&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;

	&lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;title&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Default title&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;

	&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;AlertButton&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;addClickHandler&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
	&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

	&lt;span class=&quot;nd&quot;&gt;@Override&lt;/span&gt;
	&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;setHTML&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;html&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;html&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;html&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

	&lt;span class=&quot;nd&quot;&gt;@Override&lt;/span&gt;
	&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;setTitle&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;final&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;title&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

	&lt;span class=&quot;nd&quot;&gt;@Override&lt;/span&gt;
	&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;onClick&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;ClickEvent&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;nc&quot;&gt;DialogBox&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dialogBox&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;DialogBox&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;dialogBox&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;setWidget&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;HTML&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;html&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;dialogBox&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;setText&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;dialogBox&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;center&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
	&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

	&lt;span class=&quot;nd&quot;&gt;@Override&lt;/span&gt;
	&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;getText&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;UnsupportedOperationException&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
	&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

	&lt;span class=&quot;nd&quot;&gt;@Override&lt;/span&gt;
	&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;setText&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;UnsupportedOperationException&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
	&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

	&lt;span class=&quot;nd&quot;&gt;@Override&lt;/span&gt;
	&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;getHTML&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;UnsupportedOperationException&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
	&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;&lt;em&gt;La méthode &lt;strong&gt;setHTML()&lt;/strong&gt; est appelée avec en paramètre le HTML sous forme de String.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Je peux désormais spécifier le &lt;strong&gt;contenu HTML&lt;/strong&gt; de cette boîte de dialogue dans mon template UiBinder :&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-xml&quot; data-lang=&quot;xml&quot;&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;ui:UiBinder&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;xmlns:ui=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'urn:ui:com.google.gwt.uibinder'&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;xmlns:g=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'urn:import:com.google.gwt.user.client.ui'&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;xmlns:custom=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'urn:import:info.piwai.blog.ui'&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;

	&lt;span class=&quot;nt&quot;&gt;&amp;lt;g:FlowPanel&amp;gt;&lt;/span&gt;
		&lt;span class=&quot;nt&quot;&gt;&amp;lt;custom:AlertButton&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;title=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;I like turtles&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
			&lt;span class=&quot;nt&quot;&gt;&amp;lt;p&amp;gt;&lt;/span&gt;
				I &lt;span class=&quot;nt&quot;&gt;&amp;lt;strong&amp;gt;&lt;/span&gt;really&lt;span class=&quot;nt&quot;&gt;&amp;lt;/strong&amp;gt;&lt;/span&gt; like turtles!&lt;span class=&quot;nt&quot;&gt;&amp;lt;br&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
				What about &lt;span class=&quot;nt&quot;&gt;&amp;lt;em&amp;gt;&lt;/span&gt;you&lt;span class=&quot;nt&quot;&gt;&amp;lt;/em&amp;gt;&lt;/span&gt;?
			&lt;span class=&quot;nt&quot;&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
		&lt;span class=&quot;nt&quot;&gt;&amp;lt;/custom:AlertButton&amp;gt;&lt;/span&gt;
	&lt;span class=&quot;nt&quot;&gt;&amp;lt;/g:FlowPanel&amp;gt;&lt;/span&gt;

&lt;span class=&quot;nt&quot;&gt;&amp;lt;/ui:UiBinder&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;nbsp-&quot;&gt;&amp;amp;nbsp; ?&lt;/h2&gt;

&lt;p&gt;Comment utiliser des entités HTML dans vos templates UiBinder ? Il suffit d’ajouter &lt;a href=&quot;http://code.google.com/webtoolkit/doc/latest/DevGuideUiBinder.html#HTML_entities&quot;&gt;la DTD&lt;/a&gt; fournie par Google :&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-xml&quot; data-lang=&quot;xml&quot;&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;!DOCTYPE ui:UiBinder SYSTEM &quot;http://dl.google.com/gwt/DTD/xhtml.ent&quot;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;ui:UiBinder&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;xmlns:ui=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'urn:ui:com.google.gwt.uibinder'&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;xmlns:g=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'urn:import:com.google.gwt.user.client.ui'&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;xmlns:custom=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'urn:import:info.piwai.blog.ui'&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;

	&lt;span class=&quot;nt&quot;&gt;&amp;lt;g:FlowPanel&amp;gt;&lt;/span&gt;
		&lt;span class=&quot;nt&quot;&gt;&amp;lt;custom:AlertButton&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;title=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;I like turtles&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
			&lt;span class=&quot;nt&quot;&gt;&amp;lt;p&amp;gt;&lt;/span&gt;
				Turtles &lt;span class=&quot;ni&quot;&gt;&amp;amp;gt;&lt;/span&gt; Dolphins!
			&lt;span class=&quot;nt&quot;&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
		&lt;span class=&quot;nt&quot;&gt;&amp;lt;/custom:AlertButton&amp;gt;&lt;/span&gt;
	&lt;span class=&quot;nt&quot;&gt;&amp;lt;/g:FlowPanel&amp;gt;&lt;/span&gt;

&lt;span class=&quot;nt&quot;&gt;&amp;lt;/ui:UiBinder&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;paramètres-complexes&quot;&gt;Paramètres complexes&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;&lt;ui:with&gt;&lt;/ui:with&gt;&lt;/strong&gt; permet d’injecter un objet (créé via &lt;a href=&quot;http://google-web-toolkit.googlecode.com/svn/javadoc/latest/com/google/gwt/core/client/GWT.html#create%28java.lang.Class%29&quot;&gt;GWT.create()&lt;/a&gt;) dans votre template UiBinder.&lt;/p&gt;

&lt;p&gt;Un exemple d’utilisation serait l’injection d’une &lt;strong&gt;Enum&lt;/strong&gt; afin de paramétrer un widget.&lt;/p&gt;

&lt;p&gt;Reprenons notre fenêtre d’alerte initiale :&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;AlertButton&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Button&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;implements&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ClickHandler&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;

	&lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;final&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Animal&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;animal&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;

	&lt;span class=&quot;nd&quot;&gt;@UiConstructor&lt;/span&gt;
	&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;AlertButton&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Animal&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;animal&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;animal&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;animal&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;addClickHandler&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
	&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

	&lt;span class=&quot;nd&quot;&gt;@Override&lt;/span&gt;
	&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;onClick&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;ClickEvent&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;nc&quot;&gt;Window&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;alert&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;I like &quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;animal&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;toString&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;());&lt;/span&gt;
	&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;&lt;strong&gt;Animal&lt;/strong&gt; est une simple Enum :&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Enum&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Animal&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;no&quot;&gt;TURTLES&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;DOLPHINS&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Il ne reste plus qu’à utiliser l’Enum en question dans le template UiBinder :&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-xml&quot; data-lang=&quot;xml&quot;&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;ui:UiBinder&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;xmlns:ui=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'urn:ui:com.google.gwt.uibinder'&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;xmlns:g=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'urn:import:com.google.gwt.user.client.ui'&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;xmlns:custom=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'urn:import:info.piwai.blog.ui'&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
	&lt;span class=&quot;nt&quot;&gt;&amp;lt;ui:with&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;field=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;animal&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;type=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;info.piwai.blog.Animal&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;

	&lt;span class=&quot;nt&quot;&gt;&amp;lt;g:FlowPanel&amp;gt;&lt;/span&gt;
		&lt;span class=&quot;nt&quot;&gt;&amp;lt;custom:AlertButton&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;animal=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;{animal.TURTLES}&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
	&lt;span class=&quot;nt&quot;&gt;&amp;lt;/g:FlowPanel&amp;gt;&lt;/span&gt;

&lt;span class=&quot;nt&quot;&gt;&amp;lt;/ui:UiBinder&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;&lt;em&gt;Cerise sur le gateau, on bénéficie de l’autocomplétion : en tapant &lt;strong&gt;{animal.}&lt;/strong&gt;, l’IDE propose &lt;strong&gt;TURTLES&lt;/strong&gt; ou &lt;strong&gt;DOLPHINS&lt;/strong&gt; !&lt;/em&gt;&lt;/p&gt;

&lt;h2 id=&quot;bon-et-la-coloration-syntaxique-alors-&quot;&gt;Bon, et la coloration syntaxique alors ?&lt;/h2&gt;

&lt;p&gt;En combinant tout ce qui a été dit précédemment, il est possible d’écrire des exemples de code au sein de templates UiBinder, mis en forme par SyntaxHighlighter. On utilisera pour cela un widget implémentant &lt;a href=&quot;http://google-web-toolkit.googlecode.com/svn/javadoc/latest/com/google/gwt/user/client/ui/HasHTML.html&quot;&gt;HasHTML&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Avant de passer aux choses sérieuses, un rappel. Dans &lt;a href=&quot;http://blog.piwai.info/2011/09/05/coloration-syntaxique-en-gwt/&quot;&gt;l’article précédent&lt;/a&gt;, nous utilisions le code suivant pour faire de la coloration syntaxique en GWT :&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;bindTextAreaCodeToHtml&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;TextArea&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;textArea&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;HTML&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;html&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nc&quot;&gt;JavaScriptObject&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;brush&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;BrushFactory&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;newJavaBrush&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;code&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;textArea&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getValue&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;htmlCode&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;SyntaxHighlighter&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;highlight&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;code&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;brush&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;html&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;setHTML&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;htmlCode&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Une précision : Le &lt;strong&gt;parseur UiBinder&lt;/strong&gt; utilisé pour les widgets implémentant &lt;strong&gt;HasHTML&lt;/strong&gt; ne garde pas les retours à la ligne, ce qui se révèle gênant lorsque son contenu est du code mis en forme. Pour contourner cela, on peut utiliser une balise &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt;pre&amp;gt;&lt;/code&gt; dans le template UiBinder.&lt;/p&gt;

&lt;p&gt;Trêve de suspens, voici le résultat :&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Code&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Composite&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;implements&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;HasHTML&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;

	&lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;JavaScriptObject&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;brush&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;

	&lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;HTML&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;panel&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;HTML&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;

	&lt;span class=&quot;nd&quot;&gt;@UiConstructor&lt;/span&gt;
	&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Code&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;initWidget&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;panel&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
	&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

	&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;setBrush&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;JavaScriptObject&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;brush&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;brush&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;brush&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

	&lt;span class=&quot;nd&quot;&gt;@Override&lt;/span&gt;
	&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;setHTML&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;html&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;c1&quot;&gt;// On supprime la balise &amp;lt;pre&amp;gt;&lt;/span&gt;
		&lt;span class=&quot;kd&quot;&gt;final&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;code&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;html&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;replaceFirst&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&amp;lt;pre&amp;gt;&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;replaceFirst&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&amp;lt;/pre&amp;gt;&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
		&lt;span class=&quot;nc&quot;&gt;Scheduler&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;scheduleDeferred&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ScheduledCommand&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
			&lt;span class=&quot;nd&quot;&gt;@Override&lt;/span&gt;
			&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;execute&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
				&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;brush&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
					&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;codeAsHtml&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;SyntaxHighlighter&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;highlight&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;code&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;brush&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
					&lt;span class=&quot;n&quot;&gt;panel&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;setHTML&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;codeAsHtml&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
				&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
			&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
		&lt;span class=&quot;o&quot;&gt;});&lt;/span&gt;
	&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

	&lt;span class=&quot;nd&quot;&gt;@Override&lt;/span&gt;
	&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;getText&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;UnsupportedOperationException&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
	&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

	&lt;span class=&quot;nd&quot;&gt;@Override&lt;/span&gt;
	&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;setText&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;UnsupportedOperationException&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
	&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

	&lt;span class=&quot;nd&quot;&gt;@Override&lt;/span&gt;
	&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;getHTML&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;UnsupportedOperationException&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
	&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;&lt;em&gt;Notez l’utilisation du &lt;a href=&quot;http://google-web-toolkit.googlecode.com/svn/javadoc/latest/com/google/gwt/core/client/Scheduler.html&quot;&gt;Scheduler&lt;/a&gt; pour afficher le code immédiatement &lt;strong&gt;après&lt;/strong&gt; la construction du widget. L’ordre de valorisation des attributs n’étant pas garanti, cela permet d’être sûr que la valeur du champ &lt;strong&gt;brush&lt;/strong&gt; aura été préalablement injectée au moment de l’appel à &lt;strong&gt;SyntaxHighlighter&lt;/strong&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;On peut ensuite utiliser ce widget dans un template UiBinder classique :&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-xml&quot; data-lang=&quot;xml&quot;&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;!DOCTYPE ui:UiBinder SYSTEM &quot;http://dl.google.com/gwt/DTD/xhtml.ent&quot;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;ui:UiBinder&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;xmlns:ui=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'urn:ui:com.google.gwt.uibinder'&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;xmlns:g=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'urn:import:com.google.gwt.user.client.ui'&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;xmlns:custom=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'urn:import:info.piwai.blog.ui'&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;

	&lt;span class=&quot;nt&quot;&gt;&amp;lt;ui:with&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;field=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;brushFactory&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;type=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;info.piwai.blog.BrushFactory&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;

	&lt;span class=&quot;nt&quot;&gt;&amp;lt;g:FlowPanel&amp;gt;&lt;/span&gt;
		&lt;span class=&quot;nt&quot;&gt;&amp;lt;custom:Code&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;brush=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;{brushFactory.newJavaBrush}&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&amp;lt;pre&amp;gt;&lt;/span&gt;
			public class Main {
				public static void main(String[] args) throws Exception {
					List&lt;span class=&quot;ni&quot;&gt;&amp;amp;lt;&lt;/span&gt;String&lt;span class=&quot;ni&quot;&gt;&amp;amp;gt;&lt;/span&gt; moto = Arrays.asList(&quot;I&quot;, &quot;Like&quot;, &quot;Turtles&quot;);
					System.out.println(moto);
				}
			}&lt;span class=&quot;nt&quot;&gt;&amp;lt;/pre&amp;gt;&lt;/span&gt;		
		&lt;span class=&quot;nt&quot;&gt;&amp;lt;/custom:Code&amp;gt;&lt;/span&gt;
	&lt;span class=&quot;nt&quot;&gt;&amp;lt;/g:FlowPanel&amp;gt;&lt;/span&gt;

&lt;span class=&quot;nt&quot;&gt;&amp;lt;/ui:UiBinder&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;_Les caractères &lt;strong&gt;&amp;lt;&lt;/strong&gt; et &lt;strong&gt;&amp;gt;&lt;/strong&gt; doivent être échappés pour éviter qu’ils ne soient interprétés par UiBinder et ne conduisent à des erreurs de validation. Ainsi, au lieu de **List&lt;String&gt;**, on écrit **List&amp;lt;String&amp;gt;**_&lt;/String&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Edit :&lt;/strong&gt; Merci &lt;a href=&quot;https://twitter.com/#!/matboniface/status/113509239925915648&quot;&gt;@matboniface&lt;/a&gt;, j’avais au départ parlé d’échapper des entités HTML, ce qui n’a pas beaucoup de sens.&lt;/p&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;Cet article s’est révélé &lt;strong&gt;plus long&lt;/strong&gt; que ce que j’avais en tête initialement ! J’espère qu’il vous aura fait découvrir des aspects &lt;strong&gt;intéressants&lt;/strong&gt; et souvent &lt;strong&gt;méconnus&lt;/strong&gt; de &lt;strong&gt;UiBinder&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;N’hésitez pas à compléter ce billet avec vos &lt;strong&gt;trucs et astuces&lt;/strong&gt; UiBinder en &lt;strong&gt;commentaire&lt;/strong&gt; !&lt;/p&gt;

&lt;p&gt;Vous pouvez aussi vous abonner au &lt;a href=&quot;http://feeds.feedburner.com/Piwai&quot;&gt;Flux RSS&lt;/a&gt;. Je me suis fixé comme objectif de publier un article par semaine, on verra si je tiens le rythme ;-) .&lt;/p&gt;

&lt;h1 id=&quot;comments&quot;&gt;Comments&lt;/h1&gt;

&lt;h2 id=&quot;nicolas-françois&quot;&gt;&lt;a href=&quot;http://injectinto.blogspot.fr/&quot;&gt;Nicolas François&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;Article sympa !
Bon allez, j’ai aussi un truc sympa qui n’est pas dans tes astuces.
Admettons que j’utilise une api gwt externe, et que le composant que je souhaite insérer ne possède pas de constructeur par défaut. Je pourrais m’amuser à recompiler le code en ajoutant un @UiConstructeur mais c’est ch&lt;em&gt;**&lt;/em&gt; à faire et coté maintenance un joli bordel.
La solution est très simple :
Je l’utilise l’air de rien dans le xml, mais dans le java, je le déclare de la façon suivante :&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;&lt;span class=&quot;nd&quot;&gt;@UiField&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;provided&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;MegaComponentOfTheDeath&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mcoth&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MegaComponentOfTheDeath&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;machin&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bidule&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;truc&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Le provided indique que l’instanciation est fournie par le java.&lt;/p&gt;

&lt;p&gt;Autre cas où c’est utile : Injection de ressources via GIN, le composant utilise un resource bundle qui est injecté dans le code java grace à gin.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;&lt;span class=&quot;nd&quot;&gt;@UiField&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;provided&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;Resource&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;res&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;nd&quot;&gt;@Inject&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;setRes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Resource&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;res&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;){&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;res&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;res&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;eric-b-vvinnie&quot;&gt;&lt;a href=&quot;http://twitter.com/vvinnie&quot;&gt;Eric B. (@vvinnie)&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Et pourquoi pas un petit enrobage en CDATA plutôt que de rendre les illisibles. D’ailleurs, question philosophique : et si les generics avaient mauvaise réputation seulement parce que les gens essaient d’en parler en html ? hum ?&lt;/p&gt;

&lt;h2 id=&quot;piwaï&quot;&gt;&lt;a href=&quot;/contact.html&quot;&gt;Piwaï&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;“rendre les illisibles” =&amp;gt; “rendre les &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt; &amp;gt;&lt;/code&gt; illisibles” (les signes ont sautés de ton commentaire, vu que le HTML est activé  )&lt;/p&gt;

&lt;p&gt;Grumph. Je n’y avais pas pensé… ça a l’air de fonctionner, en tout cas ya aucune erreur de validation. A voir si CDATA préserve bien les retours à la ligne (comme ça plus besoin de &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt;pre&amp;gt;&lt;/code&gt;), et comment ça se présente ensuite au runtime en terme de manipulation du DOM (=&amp;gt; que contient la string envoyée à setHTML ou setText ..)&lt;/p&gt;

&lt;p&gt;Je testerai ça à l’occasion, mais si ça marche c’est plutôt génial, ça permet de simplifier à mort le code. Merci !&lt;/p&gt;

&lt;h2 id=&quot;piwaï-1&quot;&gt;&lt;a href=&quot;/contact.html&quot;&gt;Piwaï&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;Je viens de vérifier : CDATA permet effectivement de ne plus échapper les chevrons. Par contre, avec UiBinder, il ne conserve pas les retours chariot. Il convient donc d’utiliser pre et CDATA en complément.&lt;/p&gt;
</content>
 </entry>
 
 
 
 <entry>
   <title>Coloration Syntaxique en GWT</title>
   <link href="http://www.piwai.info/2011/09/05/coloration-syntaxique-en-gwt/"/>
   <updated>2011-09-05T10:59:39+00:00</updated>
   <id>http://www.piwai.info/2011/09/05/coloration-syntaxique-en-gwt</id>
   <content type="html">&lt;p&gt;Vous connaissez peut-être &lt;a href=&quot;http://pyricau.github.com/rockslide&quot;&gt;Rockslide&lt;/a&gt;, qui permet de réaliser une présentation (des slides) en &lt;a href=&quot;http://code.google.com/webtoolkit&quot;&gt;GWT&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Qui dit &lt;strong&gt;slides techniques&lt;/strong&gt; dit exemples de &lt;strong&gt;code&lt;/strong&gt;, et donc &lt;strong&gt;coloration syntaxique&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;J’ai creusé un peu le sujet pour finalement retenir &lt;strong&gt;une solution&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Comment faire de la coloration syntaxique côté client, en GWT ?&lt;/strong&gt;&lt;/p&gt;

&lt;h2 id=&quot;solutions-disponibles&quot;&gt;Solutions disponibles&lt;/h2&gt;

&lt;p&gt;A ma connaissance, il n’existe pas de solution de coloration syntaxique spécifique à GWT, ce qui nous laisse trois options :&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;Implémenter une solution en GWT (c’est mort, je n’ai pas que ça à faire)&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Trouver une solution en Java et adapter la partie graphique (&lt;strong&gt;fausse bonne idée&lt;/strong&gt;)&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Trouver une solution en Javascript et réaliser un binding GWT (ça, c’est dans mes cordes)&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Un rapide tour d’horizon fait ressortir deux frameworks Javascript très utilisés pour la coloration syntaxique :&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;a href=&quot;http://softwaremaniacs.org/soft/highlight/en/&quot;&gt;highlight.js&lt;/a&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;a href=&quot;http://alexgorbatchev.com/SyntaxHighlighter/&quot;&gt;SyntaxHighlighter&lt;/a&gt;&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Les deux semblent maintenus, des releases récentes sont disponibles. Mon choix se porte sur &lt;strong&gt;SyntaxHighlighter&lt;/strong&gt;, qui semble plus beau. C’est purement subjectif, mais je trouve que le code mis en couleur par &lt;strong&gt;highlight.js&lt;/strong&gt; a un petit air &lt;strong&gt;vieillot&lt;/strong&gt;.&lt;/p&gt;

&lt;h2 id=&quot;gwt-syntaxhighlighter&quot;&gt;gwt-syntaxhighlighter&lt;/h2&gt;

&lt;p&gt;Coup de bol : je tombe sur &lt;a href=&quot;http://code.google.com/p/gwt-syntaxhighlighter&quot;&gt;gwt-syntaxhighlighter&lt;/a&gt;, une intégration assez poussée de &lt;strong&gt;SyntaxHighlighter&lt;/strong&gt; dans &lt;strong&gt;GWT&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Trop poussée, hélas :&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;gwt-syntaxhighlighter utilise des &lt;a href=&quot;http://code.google.com/webtoolkit/doc/latest/DevGuideCodingBasicsDeferred.html#generators&quot;&gt;Generators&lt;/a&gt;, ce qui allonge le &lt;strong&gt;temps de compilation&lt;/strong&gt;,&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;gwt-syntaxhighlighter comporte &lt;strong&gt;quelques bugs&lt;/strong&gt; qui ne sont pas corrigés et qui sont difficiles à contourner,&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;la version de SyntaxHighlighter utilisée n’est &lt;strong&gt;pas à jour&lt;/strong&gt; (les versions récentes apportent pourtant des évolutions intéressantes).&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;De plus, il s’avère que l’intégration de SyntaxHighlighter est relativement aisée, beaucoup plus simple que ce que tente de faire &lt;strong&gt;gwt-syntaxhighlighter&lt;/strong&gt;.&lt;/p&gt;

&lt;h2 id=&quot;intégration-gwt-de-syntaxhighlighter&quot;&gt;Intégration GWT de SyntaxHighlighter&lt;/h2&gt;

&lt;h3 id=&quot;charger-les-scripts-et-les-css&quot;&gt;Charger les scripts et les CSS&lt;/h3&gt;

&lt;p&gt;Tout d’abord, il faut &lt;a href=&quot;http://alexgorbatchev.com/SyntaxHighlighter/download/&quot;&gt;télécharger&lt;/a&gt; SyntaxHighlighter. Les dossiers &lt;strong&gt;scripts&lt;/strong&gt; et &lt;strong&gt;styles&lt;/strong&gt; contiennent tout ce dont vous aurez besoin.&lt;/p&gt;

&lt;p&gt;Ces fichiers devront être inclus dans l’application GWT. Il existe &lt;a href=&quot;http://code.google.com/webtoolkit/doc/latest/DevGuideOrganizingProjects.html#DevGuideModules&quot;&gt;différentes méthodes&lt;/a&gt;. J’ai choisi de créer un répertoire &lt;strong&gt;public&lt;/strong&gt; au même niveau que le répertoire &lt;strong&gt;client&lt;/strong&gt;, et d’y placer les répertoires &lt;strong&gt;scripts&lt;/strong&gt; et &lt;strong&gt;styles&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/static/blog_img/public.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Ensuite, il suffit de les ajouter au module (fichier &lt;strong&gt;.gwt.xml&lt;/strong&gt;) :&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-xml&quot; data-lang=&quot;xml&quot;&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;module&amp;gt;&lt;/span&gt;

    &lt;span class=&quot;c&quot;&gt;&amp;lt;!-- La CSS de base pour SyntaxHighlighter --&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;stylesheet&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;src=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;styles/shCore.css&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;

    &lt;span class=&quot;c&quot;&gt;&amp;lt;!-- J'utilise le thème Eclipse (8 thèmes disponibles) --&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;stylesheet&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;src=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;styles/shThemeEclipse.css&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;

    &lt;span class=&quot;c&quot;&gt;&amp;lt;!-- Le javascript de base pour SyntaxHighlighter --&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;script&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;src=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;scripts/shCore.js&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;

    &lt;span class=&quot;c&quot;&gt;&amp;lt;!-- Les extensions pour les différents langages utilisés --&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;script&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;src=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;scripts/shBrushJava.js&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;script&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;src=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;scripts/shBrushXml.js&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;

    &lt;span class=&quot;c&quot;&gt;&amp;lt;!-- [...] --&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/module&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h3 id=&quot;go-go-go&quot;&gt;Go, Go, GO!&lt;/h3&gt;

&lt;p&gt;A l’origine, SyntaxHighlighter fonctionnait en parsant le DOM et en modifiant les nœuds marqués comme conteneurs de code. La dernière release propose une &lt;a href=&quot;http://alexgorbatchev.com/SyntaxHighlighter/whatsnew.html#commonjs&quot;&gt;approche alternative&lt;/a&gt;, qui fonctionne indépendamment du DOM.&lt;/p&gt;

&lt;p&gt;Le fonctionnement est simple : une fonction Javascript prend en entrée du code sous forme de String, et renvoie une String contenant le HTML pour afficher le code formaté.&lt;/p&gt;

&lt;p&gt;Un &lt;em&gt;brush&lt;/em&gt; (pinceau) est nécessaire pour colorer du code. Il existe en fait un brush par langage, et celui-ci définit les mots clés, la syntaxe, etc.&lt;/p&gt;

&lt;p&gt;Il nous faut donc une fabrique de pinceaux :&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;BrushFactory&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;native&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;JavaScriptObject&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;newJavaBrush&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;cm&quot;&gt;/*-{
        return new $wnd.SyntaxHighlighter.brushes.Java();
    }-*/&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;native&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;JavaScriptObject&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;newXmlBrush&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;cm&quot;&gt;/*-{
        return new $wnd.SyntaxHighlighter.brushes.Xml();
    }-*/&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Voici le code &lt;a href=&quot;http://code.google.com/webtoolkit/doc/latest/DevGuideCodingBasicsJSNI.html&quot;&gt;JSNI&lt;/a&gt; utilisant SyntaxHighlighter pour transformer du code en html :&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;SyntaxHighlighter&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;native&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;highlight&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;code&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;JavaScriptObject&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;brush&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;boolean&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;toolbar&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;cm&quot;&gt;/*-{
        var params = {};
        params['toolbar'] = toolbar;
        brush.init(params);
        return brush.getHtml(code);
    }-*/&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;&lt;em&gt;Notez le paramètre toolbar qui permet d’afficher ou non la barre d’outil. De &lt;a href=&quot;http://alexgorbatchev.com/SyntaxHighlighter/manual/configuration/&quot;&gt;nombreux paramètres&lt;/a&gt; sont disponibles ; à vous de les intégrer.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Ya plus qu’à utiliser tout ça, par exemple en récupérant le code contenu dans une &lt;a href=&quot;http://google-web-toolkit.googlecode.com/svn/javadoc/latest/com/google/gwt/user/client/ui/TextArea.html&quot;&gt;TextArea&lt;/a&gt; et en l’affichant via un &lt;a href=&quot;http://google-web-toolkit.googlecode.com/svn/javadoc/latest/com/google/gwt/user/client/ui/HTML.html&quot;&gt;HTML&lt;/a&gt;.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;bindTextAreaCodeToHtml&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;TextArea&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;textArea&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;HTML&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;html&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nc&quot;&gt;JavaScriptObject&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;brush&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;BrushFactory&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;newJavaBrush&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;code&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;textArea&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getValue&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;htmlCode&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;SyntaxHighlighter&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;highlight&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;code&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;brush&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;html&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;setHTML&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;htmlCode&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;Vous avez désormais toutes les clés en main pour faire de la coloration syntaxique côté client en GWT.&lt;/p&gt;

&lt;p&gt;Bien entendu, ce code est à adapter suivant vos besoins. Vous n’êtes pas obligés d’utiliser des &lt;strong&gt;static&lt;/strong&gt; partout ;-) .&lt;/p&gt;

&lt;h1 id=&quot;comments&quot;&gt;Comments&lt;/h1&gt;

&lt;h2 id=&quot;raphaël-brugier-rbrugier&quot;&gt;&lt;a href=&quot;http://twitter.com/rbrugie&quot;&gt;Raphaël Brugier (@rbrugier)&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;Hello,&lt;/p&gt;

&lt;p&gt;Intéressant je n’avais pas suivi le développement de SyntaxHighlighter avec la nouvelle méthode sans le parsing du DOM.&lt;/p&gt;

&lt;p&gt;J’avais utilisé GWT + le plugin sur mon projet de stage l’an dernier &lt;a href=&quot;http://code.google.com/p/gwt-generator/&quot;&gt;presque de la même façon&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;En tout cas continue les posts sur gwt, il y a du public&lt;/p&gt;

&lt;p&gt;Raphaël.&lt;/p&gt;

&lt;h2 id=&quot;piwaï&quot;&gt;&lt;a href=&quot;/contact.html&quot;&gt;Piwaï&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;Cool :) Je vais tâcher de continuer, j’ai quelques idées dans mon sac :)&lt;/p&gt;
</content>
 </entry>
 
 
 
 <entry>
   <title>Les IDE, et la règle des 80 / 120 </title>
   <link href="http://www.piwai.info/2011/08/31/les-ide-et-la-regle-des-80-120/"/>
   <updated>2011-08-31T15:38:09+00:00</updated>
   <id>http://www.piwai.info/2011/08/31/les-ide-et-la-regle-des-80-120</id>
   <content type="html">&lt;p&gt;Cet article n’a strictement rien à voir avec &lt;a href=&quot;http://fr.wikipedia.org/wiki/Loi_de_Pareto&quot;&gt;Pareto&lt;/a&gt;. Un peu plus avec un &lt;a href=&quot;https://twitter.com/MathildeLemee/status/71688421596344320&quot;&gt;tweet&lt;/a&gt; datant de quelques mois.&lt;/p&gt;

&lt;p&gt;La &lt;strong&gt;longueur&lt;/strong&gt; maximale des &lt;strong&gt;lignes de code&lt;/strong&gt; est un débat récurrent dans les équipes de développement.&lt;/p&gt;

&lt;p&gt;Dès lors que l’on met en place un formatage du code automatique et partagé par tous les développeurs (notamment pour faciliter les diff), l’éternelle question revient :&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;80 ou 120 ?
&lt;small&gt;Robert&lt;/small&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Ça fait 5 ans qu’on a tous des 19 pouces, on pourrait peut-être passer à 160 non ?
&lt;small&gt;Gérard&lt;/small&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2 id=&quot;que-nenni-&quot;&gt;Que nenni !&lt;/h2&gt;

&lt;p&gt;Voici la configuration que j’utilise :&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/static/blog_img/line_width.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Vous avez bien lu, je préfère &lt;strong&gt;1000&lt;/strong&gt;. Ou 2000. Ou 10000. Ou… bon, je suppose que vous avez compris.&lt;/p&gt;

&lt;p&gt;Non pas que j’ai la chance de disposer d’un écran de cinéma pour coder, pour moi il s’agit juste de &lt;strong&gt;bonnes pratiques&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Ce n’est pas votre IDE qui doit décider de la longueur de vos lignes de code, &lt;strong&gt;c’est vous&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Une ligne de code qui dépasse la largeur de l’écran, c’est un &lt;a href=&quot;http://en.wikipedia.org/wiki/Code_smell&quot;&gt;code smell&lt;/a&gt;. Laisser l’IDE ajouter des retours à la ligne, c’est cacher le code smell.&lt;/p&gt;

&lt;p&gt;Un peu comme mettre du déo sans se doucher après un jogging.&lt;/p&gt;

&lt;p&gt;Pour la route, quelques cas classiques de longlignite aigüe :&lt;/p&gt;

&lt;h2 id=&quot;le-syndrome-du-développeur-c-aka-le-radin-des-variables&quot;&gt;Le syndrome du développeur C, aka le radin des variables&lt;/h2&gt;

&lt;p&gt;A l’origine, en C, il fallait déclarer toutes les variables locales d’une procédure au début de celle-ci. Ce n’est pas forcément une mauvaise idée.&lt;/p&gt;

&lt;p&gt;Mais en combinant cela avec l’idée qu’une variable locale, c’est forcément de la mémoire utilisée en plus et donc de la “performance” en moins, on prend rapidement la bonne habitude de créer le moins de variables locales possibles.&lt;/p&gt;

&lt;p&gt;Un exemple de la vraie vie :&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;&lt;span class=&quot;nc&quot;&gt;WebApplicationContextUtils&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getWebApplicationContext&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getServletContext&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getAutowireCapableBeanFactory&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;autowireBeanProperties&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;AutowireCapableBeanFactory&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;AUTOWIRE_BY_TYPE&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;&lt;strong&gt;Vous trouvez-ça lisible vous ?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;C’est peut-être super excitant à écrire (ah ça c’est sûr on est fier hein, on a utilisé aucune variable…). Et PAN, &lt;strong&gt;+10000€&lt;/strong&gt; de &lt;strong&gt;dette technique&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;La solution est simple, elle s’appelle la variable locale. Découpez votre code, créez des variables locales &lt;strong&gt;même si elles ne servent qu’une fois&lt;/strong&gt;.  Et découpez votre code en petites méthodes.&lt;/p&gt;

&lt;p&gt;Moins de &lt;strong&gt;5 lignes&lt;/strong&gt;, c’est bien. Au passage, je vous recommande chaudement la lecture de &lt;a href=&quot;http://www.amazon.com/Clean-Code-Handbook-Software-Craftsmanship/dp/0132350882&quot;&gt;Clean Code&lt;/a&gt; :-).&lt;/p&gt;

&lt;p&gt;On comprend déjà mieux :&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;&lt;span class=&quot;nc&quot;&gt;ServletContext&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;servletContext&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getServletContext&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;WebApplicationContext&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;applicationContext&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;WebApplicationContextUtils&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getWebApplicationContext&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;servletContext&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;AutowireCapableBeanFactory&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;beanFactory&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;applicationContext&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getAutowireCapableBeanFactory&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;beanFactory&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;autowireBeanProperties&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;AutowireCapableBeanFactory&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;AUTOWIRE_BY_NAME&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;le-fan-de-programmation-fonctionnelle&quot;&gt;Le fan de programmation fonctionnelle&lt;/h2&gt;

&lt;p&gt;Le mec, un jour, il a découvert Google Guava et ses &lt;a href=&quot;http://guava-libraries.googlecode.com/svn/trunk/javadoc/com/google/common/base/Function.html&quot;&gt;Function&lt;/a&gt; ; il a trouvé ça trop cool et a adopté le “style fonctionnel” dans tous ses développements. Malheureusement, en Java, cela se traduit par des classes anonymes (à moins d’utiliser &lt;a href=&quot;https://github.com/pyricau/FunkyJFunctional&quot;&gt;FJF&lt;/a&gt;… pub ;-)), et cela déborde vite de l’écran !&lt;/p&gt;

&lt;p&gt;Encore un exemple de la vraie vie, un peu maquillé et allégé pour l’occasion :&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MyPanel&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Composite&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;

	&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;MyPanel&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;kd&quot;&gt;final&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Request&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;request&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Request&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;initWidget&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;VerticalPanel&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; 
			&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
				&lt;span class=&quot;n&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;HorizontalPanel&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
					&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
						&lt;span class=&quot;n&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;RadioButton&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;native&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;native&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
							&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
								&lt;span class=&quot;n&quot;&gt;setValue&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;isNativeRequest&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;());&lt;/span&gt;
								&lt;span class=&quot;n&quot;&gt;addClickHandler&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ClickHandler&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;

									&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;onClick&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;ClickEvent&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
										&lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;setNativeRequest&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;getValue&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;());&lt;/span&gt;
									&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
								&lt;span class=&quot;o&quot;&gt;});&lt;/span&gt;
							&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
						&lt;span class=&quot;o&quot;&gt;});&lt;/span&gt;
					&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
				&lt;span class=&quot;o&quot;&gt;});&lt;/span&gt;
				&lt;span class=&quot;n&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Button&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Run&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ClickHandler&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
					&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;onClick&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;ClickEvent&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
						&lt;span class=&quot;nc&quot;&gt;ServicesHolder&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;requestService&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;execute&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;AsyncCallback&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Response&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;

							&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;onFailure&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Throwable&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;caught&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
								&lt;span class=&quot;nc&quot;&gt;Window&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;alert&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;caught&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getMessage&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;());&lt;/span&gt;
							&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

							&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;onSuccess&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Response&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;response&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
								&lt;span class=&quot;k&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
									&lt;span class=&quot;n&quot;&gt;updateUi&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;response&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
								&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Exception&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
									&lt;span class=&quot;n&quot;&gt;onFailure&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
								&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
							&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
						&lt;span class=&quot;o&quot;&gt;});&lt;/span&gt;
					&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
				&lt;span class=&quot;o&quot;&gt;}));&lt;/span&gt;
			&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
		&lt;span class=&quot;o&quot;&gt;});&lt;/span&gt;
	&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Quand je tombe sur une classe qui comporte 1000 lignes comme ça, j’ai beaucoup de mal à suivre le &lt;strong&gt;flux d’exécution&lt;/strong&gt;. Pas vous ?&lt;/p&gt;

&lt;h2 id=&quot;lutilisation-dune-fluid-interface&quot;&gt;L’utilisation d’une Fluid interface&lt;/h2&gt;

&lt;p&gt;Les &lt;a href=&quot;http://en.wikipedia.org/wiki/Fluent_interface&quot;&gt;Fluid interfaces&lt;/a&gt;, par design, sont faites pour permettre les appels chaînés, afin d’augmenter la lisibilité du code et éventuellement créer des &lt;a href=&quot;http://en.wikipedia.org/wiki/Domain-specific_language&quot;&gt;DSL&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Si la chaîne d’appels de méthode est courte et a un sens grammatical, il paraît alors sensé de la laisser sur une ligne, sans que l’IDE ne formate cette ligne.&lt;/p&gt;

&lt;p&gt;Exemple avec un binding &lt;a href=&quot;http://code.google.com/p/google-guice/&quot;&gt;Guice&lt;/a&gt; :&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;&lt;span class=&quot;n&quot;&gt;bind&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Geek&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;annotatedWith&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Piwai&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;toInstance&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;piwai&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Par contre, si la chaîne d’appels est trop longue, à vous de la découper à votre goût sur plusieurs lignes.&lt;/p&gt;

&lt;p&gt;Une astuce simple consiste à ajouter “//” en fin de ligne, pour empêcher l’IDE de recoller ensemble des appels de méthodes que l’on a décidé de séparer.&lt;/p&gt;

&lt;p&gt;Par exemple, pour utiliser un &lt;a href=&quot;http://code.google.com/p/androidannotations/wiki/SharedPreferencesHelpers&quot;&gt;SharedPreferences helper&lt;/a&gt; généré par AndroidAnnotations:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;&lt;span class=&quot;n&quot;&gt;prefs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;edit&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;//&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;clear&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;//&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;put&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;John Smith&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;//&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;age&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;put&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;42&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;//&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;done&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;A vous maintenant : qui a d’autres exemples de longlignite aigüe ?&lt;/p&gt;

&lt;h1 id=&quot;comments&quot;&gt;Comments&lt;/h1&gt;

&lt;h2 id=&quot;baztoune&quot;&gt;&lt;a href=&quot;http://bastien-colmard.com/&quot;&gt;Baztoune&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Ah, l’éternelle question :D ça me rappelle &lt;a href=&quot;http://stackoverflow.com/questions/110928/is-there-a-valid-reason-for-enforcing-a-maximum-width-of-80-characters-in-a-code&quot;&gt;ce topic&lt;/a&gt; sur SO&lt;br /&gt;
Dans l’absolu, je suis d’accord, c’est bien au développeur de découper ses lignes, pour donner du rythme à son code et le rendre lisible, mais en équipe, ne vaut-il mieux pas assurer l’uniformisation de l’apparence du code? Pas spécialement pour le gestionnaire de sources qui se débrouille très bien, mais pour la lisibilité globale du code, et ainsi éviter les disparités de style entre développeurs.&lt;/p&gt;

&lt;h2 id=&quot;gabriel-kastenbaum&quot;&gt;Gabriel Kastenbaum&lt;/h2&gt;
&lt;p&gt;J’ai juste une règle, qui diffère un peu de la règle usuelle du nombre de lignes :&lt;/p&gt;

&lt;p&gt;une méthode doit être lisible d’un coup d’oeil.
On parle toujours du nombre de lignes par méthode. Il faut aussi parler des lignes trop longues en largeur. C’est aussi fautif amha&lt;br /&gt;
Après (cf. exemple de la classe anonyme) java n’aide pas toujours. 
Mais l’idée est là. Pour un écran normal, il faut pouvoir tout lire d’un coup.&lt;/p&gt;

&lt;p&gt;J’ai déjà galéré sur des méthodes dont le bug se voyait quand on scrollait à droite. Or je ne scrolle JAMAIS à droite. je n’y pense jamais.&lt;/p&gt;

&lt;p&gt;C’est pq dans Eclipse je laisse une line width de 120 à peu près.&lt;br /&gt;
L’écran est une feuille.&lt;/p&gt;

&lt;h2 id=&quot;francois-marot&quot;&gt;&lt;a href=&quot;https://twitter.com/FrancoisMarot&quot;&gt;Francois Marot&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Entierement d’accord avec ce post. Pour moi le formatteur est un mal nécessaire (pour uniformiser tout ce qui est tabulation, espacement, supprimer d’éventuels saut de lignes multiple, et surtout faciliter les diff/merges) mais il doit en faire le strict minimum. Le développeur doit rester au manette, et si ponctuellement on veut pouvoir faire un ligne longue (pour mettre un commentaire sur un truc touchy par exemple), on doit pouvoir le faire. Tant que ca reste de facon exceptionnelle et justifiée. Donc des formatteurs de code, oui, mais de facon minimum.&lt;/p&gt;
</content>
 </entry>
 
 
 
 <entry>
   <title>when(piwaï.quit(excilys)).thenReturn(new Blog());</title>
   <link href="http://www.piwai.info/2011/08/31/whenpiwai-quitexcilys-thenreturnnew-blog/"/>
   <updated>2011-08-31T14:28:18+00:00</updated>
   <id>http://www.piwai.info/2011/08/31/whenpiwai-quitexcilys-thenreturnnew-blog</id>
   <content type="html">&lt;p&gt;Après deux ans et demi de prestation de service et de fun au sein d’&lt;a href=&quot;http://www.excilys.com/&quot;&gt;Excilys&lt;/a&gt;, je m’envole pour de nouvelles aventures !&lt;/p&gt;

&lt;p&gt;Tout ce que je peux officiellement vous dire pour le moment, c’est que je vais bosser pour une startup qui fait de l’&lt;strong&gt;Android&lt;/strong&gt;. J’ai hâte d’y être !&lt;/p&gt;

&lt;p&gt;Au sein d’Excilys, j’ai découvert le plaisir d’écrire sur le &lt;a href=&quot;http://blog.excilys.com/author/pyricau/&quot;&gt;Blog&lt;/a&gt; et le &lt;a href=&quot;http://labs.excilys.com/author/pyricauexcilys-com/&quot;&gt;Labs&lt;/a&gt; Excilys, et j’y ai laissé quelques &lt;strong&gt;24 articles&lt;/strong&gt; et &lt;strong&gt;93 commentaires&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Je vais donc continuer sur &lt;a href=&quot;http://blog.piwai.info&quot;&gt;ce blog&lt;/a&gt; (n’oubliez pas le &lt;a href=&quot;http://feeds.feedburner.com/Piwai&quot;&gt;Flux RSS&lt;/a&gt;) ;-)).&lt;/p&gt;

&lt;p&gt;J’héberge le blog sur &lt;a href=&quot;http://wordpress.com&quot;&gt;wordpress.com&lt;/a&gt;, comme ça aucun souci de maintenance, et en prime ya même une &lt;strong&gt;coloration syntaxique&lt;/strong&gt; :&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;&lt;span class=&quot;n&quot;&gt;when&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;piwai&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;quit&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;excilys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;thenReturn&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Blog&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;());&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Ça sera aussi l’occasion de vous parler des projets open source qui me tiennent à cœur : &lt;a href=&quot;http://code.google.com/p/androidannotations/&quot;&gt;AndroidAnnotations&lt;/a&gt;, &lt;a href=&quot;https://github.com/pyricau/rockslide&quot;&gt;Rockslide&lt;/a&gt;, &lt;a href=&quot;https://github.com/pyricau/FunkyJFunctional&quot;&gt;FunkyJFunctional&lt;/a&gt;, &lt;a href=&quot;https://github.com/pyricau/toohardforyou&quot;&gt;2H4U&lt;/a&gt; ;-)&lt;/p&gt;

&lt;p&gt;On commence avec un peu de &lt;strong&gt;clean code&lt;/strong&gt; : &lt;a href=&quot;/2011/08/31/les-ide-et-la-regle-des-80-120/&quot;&gt;Les IDE et la règle des 80 / 120&lt;/a&gt;.&lt;/p&gt;

&lt;h1 id=&quot;comments&quot;&gt;Comments&lt;/h1&gt;

&lt;h2 id=&quot;kévin-gaudin-kevingaudin&quot;&gt;&lt;a href=&quot;http://twitter.com/kevingaudin&quot;&gt;Kévin Gaudin (@kevingaudin)&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;C’est bien de changer ;) Bonne chance pour la suite, alors !&lt;/p&gt;

&lt;h2 id=&quot;cedric-gatay-cedric_gatay&quot;&gt;&lt;a href=&quot;http://twitter.com/Cedric_Gatay&quot;&gt;Cedric Gatay (@Cedric_Gatay)&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Bon courage pour la suite, l’aventure startup est vraiment sympa !&lt;/p&gt;

&lt;h2 id=&quot;françois-ostyn-ostynf&quot;&gt;&lt;a href=&quot;http://twitter.com/ostynf&quot;&gt;François OSTYN (@ostynf)&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Pierre-Yves, bonne chance pour la suite des événements !&lt;/p&gt;

&lt;h2 id=&quot;yannick-grenzinger&quot;&gt;&lt;a href=&quot;http://about.me/yannick.grenzinger&quot;&gt;yannick grenzinger&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Bravo monsieur !&lt;br /&gt;
On en reparle quand on se croise !  :D&lt;/p&gt;

&lt;h2 id=&quot;khoa-nghiem&quot;&gt;Khoa Nghiem&lt;/h2&gt;
&lt;p&gt;Bonne chance pour la suite alors.&lt;br /&gt;
Dommage que je n’ai pas eu plus l’occasion de te côtoyer&lt;/p&gt;

&lt;h2 id=&quot;fred-faure&quot;&gt;Fred Faure&lt;/h2&gt;
&lt;p&gt;Congratulations jeune padawan devenu jedi !&lt;/p&gt;

&lt;h2 id=&quot;thomas-bassetto-tbassetto&quot;&gt;&lt;a href=&quot;http://twitter.com/tbassetto&quot;&gt;Thomas Bassetto (@tbassetto)&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Bonne chance pour la suite :D&lt;/p&gt;
</content>
 </entry>
 
 
 
</feed>