<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Sriram Ramani &#187; mozilla</title>
	<atom:link href="http://sriramramani.wordpress.com/tag/mozilla/feed/" rel="self" type="application/rss+xml" />
	<link>http://sriramramani.wordpress.com</link>
	<description></description>
	<lastBuildDate>Sat, 30 Mar 2013 18:00:30 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='sriramramani.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>Sriram Ramani &#187; mozilla</title>
		<link>http://sriramramani.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://sriramramani.wordpress.com/osd.xml" title="Sriram Ramani" />
	<atom:link rel='hub' href='http://sriramramani.wordpress.com/?pushpress=hub'/>
		<item>
		<title>View Reduction</title>
		<link>http://sriramramani.wordpress.com/2013/03/25/view-reduction/</link>
		<comments>http://sriramramani.wordpress.com/2013/03/25/view-reduction/#comments</comments>
		<pubDate>Tue, 26 Mar 2013 05:41:48 +0000</pubDate>
		<dc:creator>Sriram Ramani</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[attributes]]></category>
		<category><![CDATA[compound]]></category>
		<category><![CDATA[compound drawables]]></category>
		<category><![CDATA[custom attributes]]></category>
		<category><![CDATA[custom menu]]></category>
		<category><![CDATA[custom state]]></category>
		<category><![CDATA[custom-ui]]></category>
		<category><![CDATA[drawable state]]></category>
		<category><![CDATA[duplicateParentState]]></category>
		<category><![CDATA[menu]]></category>
		<category><![CDATA[mozilla]]></category>
		<category><![CDATA[optimization]]></category>
		<category><![CDATA[optimize]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[state]]></category>
		<category><![CDATA[textview]]></category>

		<guid isPermaLink="false">http://sriramramani.wordpress.com/?p=290</guid>
		<description><![CDATA[&#8220;So! Many! Views!&#8221; &#8212; that&#8217;s exactly what I felt when we started the process of optimizing Firefox for Android. Compound &#8230;<p><a href="http://sriramramani.wordpress.com/2013/03/25/view-reduction/">Continue reading &#187;</a></p><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=sriramramani.wordpress.com&#038;blog=10234005&#038;post=290&#038;subd=sriramramani&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>&#8220;So! Many! Views!&#8221; &#8212; that&#8217;s exactly what I felt when we started the process of optimizing Firefox for Android. <a href="https://sriramramani.wordpress.com/2013/01/15/compound-drawables/">Compound Drawables</a> was pure magic. It reduced a lot of views in the home page. But we wanted to see where all it could be used. The custom menu was a good choice. To stand out from other menus, but still feel like Android menu, we added the images to the menu. This required re-writing the entire menu management ourselves. Also, some menu items are checkable and some others can have a sub menu. We added an indicator on the right for the same. The final layout had no less than 8 views to manage the image, text and the indicator along with the variable padding in between them.</p>
<div id="attachment_291" class="wp-caption aligncenter" style="width: 610px"><a href="http://sriramramani.wordpress.com/2013/03/25/view-reduction/view-reduction/" rel="attachment wp-att-291"><img src="http://sriramramani.files.wordpress.com/2013/03/view-reduction.jpg?w=791" alt="Left: Original complex layout with 8 views; Right: One single TextView."   class="size-full wp-image-291" /></a><p class="wp-caption-text">Left: Original complex layout with 8 views; Right: One single TextView.</p></div>
<p>How do we reduce the views in this menu? This menu is going to exist for the entire life time of the app (at this point of writing, even though they use a list view, the individual rows aren&#8217;t cleared every time the menu is closed). To start optimizing, let&#8217;s look at how the original menu layout was.</p>
<pre class="brush: xml; title: ; notranslate">
    &lt;LinearLayout&gt;

        &lt;!-- left-most padding --&gt;
        &lt;View android:layout_width=&quot;10dp&quot;/&gt;

        &lt;!-- icon --&gt;
        &lt;ImageView /&gt;

        &lt;!-- menu item name --&gt;
        &lt;TextView /&gt;

        &lt;!-- right Indicator --&gt;
        &lt;FrameLayout&gt;

            &lt;!-- tick --&gt;
            &lt;CheckBox /&gt;

            &lt;!-- more indicator --&gt;
            &lt;ImageView /&gt;

        &lt;/FrameLayout&gt;
        
        &lt;!-- right-most padding --&gt;
        &lt;View android:layout_width=&quot;10dp&quot;/&gt;

    &lt;/LinearLayout&gt;
</pre>
<p>The low hanging fruit here is to combine the <code>ImageView</code> for the icon with the <code>TextView</code>. That reduces one of the two views. The left and right most padding are interesting cases. The <code>TextView</code> by itself cannot have a standard margin. This would push the text more inside, if the icon or the right indicator is present, but will look right without them. But, that&#8217;s not the intended design. The parent <code>LinearLayout</code> can have a padding. However, this layout file actually had a <code>&lt;merge/&gt;</code> tag as the parent, as the layout could be inflated into any <code>ViewGroup</code> on demand. Now, since the left image is now made a compound drawable, the padding can be merged with the TextView. We are left with the right indicator (3 views) and an empty view for padding.</p>
<p>The interesting thing with compound drawables is that they support states. The state of the <code>TextView</code> is duplicated to the compound drawables too. If there is a way to combine the <code>CheckBox</code> and the <code>ImageView</code> as a single drawable, the entire right indicator could be made a compound drawable. How do we do that? The easiest way is to have <a href="http://sriramramani.wordpress.com/2012/11/17/custom-states/">custom states</a>. A typical state list for the right indicator would look like:</p>
<pre class="brush: xml; title: ; notranslate">
    &lt;selector&gt;

        &lt;!-- more indicator --&gt;
        &lt;item app:state_more=&quot;true&quot;
              android:drawable=&quot;@drawable/more_indicator&quot;/&gt;

        &lt;!-- checked state --&gt;
        &lt;item app:state_more=&quot;false&quot;
              android:state_checkable=&quot;true&quot;
              android:state_checked=&quot;true&quot;
              android:drawable=&quot;@drawable/check_mark&quot;/&gt;

       &lt;!-- unchecked state --&gt;
       &lt;item app:state_more=&quot;false&quot;
             android:state_checkable=&quot;true&quot;
             android:state_checked=&quot;false&quot;
             android:drawable=&quot;@drawable/check_box&quot;/&gt;

       &lt;!-- default state --&gt;
       &lt;item android:drawable=&quot;@android:color/transparent&quot;/&gt;

    &lt;/selector&gt;
</pre>
<p>The right side of the <code>TextView</code> is shrunk to a single image with multiple states. This can be the <code>android:drawableRight</code> of the text. So, how many views do we have for the menu item?</p>
<pre class="brush: xml; title: ; notranslate">
    &lt;TextView android:drawableLeft=&quot;@drawable/_assigned_by_code_&quot;
              android:drawableRight=&quot;@drawable/_right_indicator_selector_&quot;
              android:paddingLeft=&quot;10dp&quot;
              android:paddingRight=&quot;10dp&quot;/&gt;
</pre>
<p>And that&#8217;s how we optimize Firefox on Android! One view at a time! <img src='http://s1.wp.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/sriramramani.wordpress.com/290/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/sriramramani.wordpress.com/290/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=sriramramani.wordpress.com&#038;blog=10234005&#038;post=290&#038;subd=sriramramani&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://sriramramani.wordpress.com/2013/03/25/view-reduction/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/98c2d4d449d87a611778e2ff107f3877?s=96&#38;d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">sriramramani</media:title>
		</media:content>

		<media:content url="http://sriramramani.files.wordpress.com/2013/03/view-reduction.jpg" medium="image">
			<media:title type="html">Left: Original complex layout with 8 views; Right: One single TextView.</media:title>
		</media:content>
	</item>
		<item>
		<title>Overdraw</title>
		<link>http://sriramramani.wordpress.com/2013/02/20/overdraw/</link>
		<comments>http://sriramramani.wordpress.com/2013/02/20/overdraw/#comments</comments>
		<pubDate>Thu, 21 Feb 2013 06:36:59 +0000</pubDate>
		<dc:creator>Sriram Ramani</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[background]]></category>
		<category><![CDATA[custom-ui]]></category>
		<category><![CDATA[draw]]></category>
		<category><![CDATA[drawable]]></category>
		<category><![CDATA[gpu]]></category>
		<category><![CDATA[gpu overdraw]]></category>
		<category><![CDATA[hidden]]></category>
		<category><![CDATA[hidden view]]></category>
		<category><![CDATA[imageview]]></category>
		<category><![CDATA[layer]]></category>
		<category><![CDATA[mozilla]]></category>
		<category><![CDATA[optimization]]></category>
		<category><![CDATA[optimize]]></category>
		<category><![CDATA[overdraw]]></category>
		<category><![CDATA[paint]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[reduce]]></category>
		<category><![CDATA[surfaceview]]></category>
		<category><![CDATA[textview]]></category>
		<category><![CDATA[thumbnail]]></category>
		<category><![CDATA[visible]]></category>
		<category><![CDATA[window]]></category>
		<category><![CDATA[window background]]></category>

		<guid isPermaLink="false">http://sriramramani.wordpress.com/?p=275</guid>
		<description><![CDATA[A couple of months back Romain Guy had posted a blog on performance of an Android app. Of the many &#8230;<p><a href="http://sriramramani.wordpress.com/2013/02/20/overdraw/">Continue reading &#187;</a></p><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=sriramramani.wordpress.com&#038;blog=10234005&#038;post=275&#038;subd=sriramramani&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>A couple of months back Romain Guy had posted a <a href="http://www.curious-creature.org/2012/12/01/android-performance-case-study/">blog</a> on performance of an Android app. Of the many things, overdraw seemed to be more easier to see instantly. I enabled the <strong>Show GPU Overdraw</strong> option in Developer Options and launched Fennec. Though some red areas were expected, the result was a shock. Most parts of the app was covered in red. Android gave some consolation in leaving a small portion in light red.</p>
<div id="attachment_276" class="wp-caption aligncenter" style="width: 801px"><a href="http://sriramramani.wordpress.com/2013/02/20/overdraw/overdraw-progress/" rel="attachment wp-att-276"><img src="http://sriramramani.files.wordpress.com/2013/02/overdraw-progress.png?w=791&#038;h=329" alt="(i) Actual UI, (ii) Overdraw to start with, (iii) Actual reduction in overdraw (iv) Ideal condition" width="791" height="329" class="size-large wp-image-276" /></a><p class="wp-caption-text">(i) Actual UI, (ii) Overdraw to start with, (iii) Actual reduction in overdraw, and (iv) Ideal condition</p></div>
<p>After understanding how overdraw is calculated, and how the problems can be mitigated, I started working on it. Basically there doesn&#8217;t seem to be a model that calculates what area of a view has to be repainted on the screen at any given time. In other words, Android doesn&#8217;t ask the view to paint only the region that is actually seen by the user. Instead the entire view is repainted if it is has its visibility as <a href="http://developer.android.com/reference/android/view/View.html#VISIBLE">View.VISIBLE</a>. To think in terms of windowing systems, a background application&#8217;s paint can be avoided when the foreground application occupies the entire screen. However, in case of Android, it paints both the hidden and visible views at every frame. By hidden the views are still <code>View.VISIBLE</code>, but not visible to the user. How do we solve this problem? To solve the problem, we need to see how complex the painting of a thumbnail in the screen was.</p>
<p><a href="http://sriramramani.wordpress.com/2013/02/20/overdraw/stacked-layers/" rel="attachment wp-att-281"><img src="http://sriramramani.files.wordpress.com/2013/02/stacked-layers1.png?w=600&#038;h=450" alt="stacked-layers" width="600" height="450" class="aligncenter size-large wp-image-281" /></a></p>
<p>The actual thumbnail was the sixth layer drawn on the screen! The thumbnail had a text draw over it, and it by itself had a background which is usually hidden from the user. The about:home had a blue background, so did the <code>Window</code>. The tabs UI had a darker background drawn even though it was hidden, ummm, from the user&#8217;s eyes. There was also a <code>SurfaceView</code>, used for showing the HTML page, with a white background.</p>
<p>Android highly recommends using a background color for the Window. But why is it useful? 1. It makes the app feels like it loaded right when the user taps on the icon in the launcher, and 2. it works the same as a HTML background for the page. So, it&#8217;s good to have the window background and take the strain out of individual background in the app. For example, a white background for Facebook app&#8217;s window, instead of individual rows is better. But Firefox for Android has a different problem. We support <a href="https://addons.mozilla.org/en-US/android/themes/">themes</a> starting version 19. If we had to set the image from the theme as the background of the window, then the about:home and url-bar over it wouldn&#8217;t have a background, but instead scroll over it. Also, hiding SurfaceView whenever about:home is shown will become a mess. But, having a background for Window and about:home is a clear overdraw! The way to solve this is to set a Window background at startup, and remove it after the UI is shown to the user. The app will be perceived as having launched faster, but the overdraw is removed for the lifetime of the app.</p>
<pre class="brush: java; title: ; notranslate">
    @Override
    public void onWindowFocusChanged(boolean hasFocus) {
        if (hasFocus)
            getWindow().setBackgroundDrawable(null);
    }
</pre>
<p>That removes one layer out of the equation. Let&#8217;s take the case of tabs UI. When the app launches, it doesn&#8217;t open the tabs right away. The UI for tabs is hidden until the user hits the show-tabs button. This means that there is no point is having the UI with a state <code>View.VISIBLE</code> when the user does not even see it. The UI can be made <code>View.VISIBLE</code> right when the user taps on the tabs-button, and made <code>View.INVISIBLE</code> when it is hidden. As a matter of fact <code>View.GONE</code> could also be used. However, since there is a small animation involved, to know the height of the tabs UI, we had to use <code>View.INVISIBLE</code>. This ensures that the View is not drawn, but <code>onLayout()</code> is called to know the width, the height and the position of the View. A simple change in XML removes the next layer from the stack.</p>
<p><code>SurfaceView</code> has a interesting property. The View wouldn&#8217;t be created and initialized if its not <code>View.VISIBLE</code>. Here comes the actual vs. ideal scenario in the first image. Ideally, if the same technique for Tabs UI is applied for the SurfaceView, the overdraw would be reduced by two times. However, since the code to handle it becomes messier, we avoided doing the same.</p>
<p>The last part in the stack involves the thumbnail. As mentioned earlier, thumbnail has an image of its own and a background. The background (30% white) is used in cases where a thumbnail image is not available. However, we keep drawing the background even when the image occupies the entire width and height of the <code>ImageView</code>. How about clearing the background if there is an image available? That would reduce one more layer!</p>
<pre class="brush: java; title: ; notranslate">
    // somewhere in the code
    if (thumbnail == null) {
        thumbnailView.setImageBitmap(R.drawable.some_default_image);
        thumbnailView.setBackgroundColor(0x22FFFFFF);
    } else {
        thumbnailView.setImageBitmap(thumbnail);
        thumbnailView.setBackgroundColor(0x0);
    }
</pre>
<p>Though this might seem a silly optimization, this would benefit a lot of apps that requires loading images from a server. How do we deal with the <code>TextView</code>? As per the design, we wanted our TextView to be shown over the ImageView. Hence an overdraw couldn&#8217;t be avoided. This is what is seen in third screenshot. However, if we could move the TextView to be shown below the ImageView, the amount of overdraw on the TextView remains the same as the ImageView, as in the last screenshot. If we move the TextView down, wouldn&#8217;t it use a vertical LinearLayout instead of a RelativeLayout? Yes, it would! And wouldn&#8217;t the ImageView be enclosed in a RelativeLayout, that also has another ImageView for the small triangle on right corner? Maybe. And doesn&#8217;t this increase the number of views significantly? Of course yes!</p>
<pre class="brush: xml; title: ; notranslate">
    &lt;!-- TextView over ImageView --&gt;
    &lt;RelativeLayout&gt;
        &lt;ImageView ..thumbnail.. /&gt;
        &lt;ImageView ..triangle.. /&gt;
        &lt;TextView/&gt;
    &lt;/RelativeLayout&gt;

    &lt;!-- TextView below ImageView --&gt;
    &lt;LinearLayout ..vertical.. &gt;
        &lt;RelativeLayout&gt;
            &lt;ImageView ..thumbnail.. /&gt;
            &lt;ImageView ..triangle.. /&gt;
        &lt;/RelativeLayout&gt;
        &lt;TextView /&gt;
    &lt;/LinarLayout&gt;
</pre>
<p>There is a better way to handle this. A custom view can take care of drawing the triangle over the actual image bitmap when needed. This would involve just one View, but two draw operations. This is shown as the green overdraw only for the triangle in the last screenshot. However, if pin&#8217;s bitmap can be blended with the image and painted in one draw, the overdraw can be reduced further. It&#8217;s just the trade-off between two draws vs. blending images that would win there. A very small overdraw is better than a complex bitmap calculation usually.</p>
<p>So, finally, how many layers do we have in last screenshot? 1. about:home background, 2. thumbnail image. Just two layers! Hence the light blue region instead of bright red!</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/sriramramani.wordpress.com/275/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/sriramramani.wordpress.com/275/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=sriramramani.wordpress.com&#038;blog=10234005&#038;post=275&#038;subd=sriramramani&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://sriramramani.wordpress.com/2013/02/20/overdraw/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
	
		<media:thumbnail url="http://sriramramani.files.wordpress.com/2013/02/stacked-layers1.png?w=150" />
		<media:content url="http://sriramramani.files.wordpress.com/2013/02/stacked-layers1.png?w=150" medium="image">
			<media:title type="html">stacked-layers</media:title>
		</media:content>

		<media:content url="http://0.gravatar.com/avatar/98c2d4d449d87a611778e2ff107f3877?s=96&#38;d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">sriramramani</media:title>
		</media:content>

		<media:content url="http://sriramramani.files.wordpress.com/2013/02/overdraw-progress.png?w=791" medium="image">
			<media:title type="html">(i) Actual UI, (ii) Overdraw to start with, (iii) Actual reduction in overdraw (iv) Ideal condition</media:title>
		</media:content>

		<media:content url="http://sriramramani.files.wordpress.com/2013/02/stacked-layers1.png?w=600" medium="image">
			<media:title type="html">stacked-layers</media:title>
		</media:content>
	</item>
		<item>
		<title>Nebula 7</title>
		<link>http://sriramramani.wordpress.com/2013/01/30/nebula-7/</link>
		<comments>http://sriramramani.wordpress.com/2013/01/30/nebula-7/#comments</comments>
		<pubDate>Thu, 31 Jan 2013 06:09:19 +0000</pubDate>
		<dc:creator>Sriram Ramani</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[1.33]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[bug]]></category>
		<category><![CDATA[canvas]]></category>
		<category><![CDATA[custom-ui]]></category>
		<category><![CDATA[holo theme]]></category>
		<category><![CDATA[mozilla]]></category>
		<category><![CDATA[nexus]]></category>
		<category><![CDATA[nexus 7]]></category>
		<category><![CDATA[path]]></category>
		<category><![CDATA[scaling factor]]></category>
		<category><![CDATA[tvdpi]]></category>

		<guid isPermaLink="false">http://sriramramani.wordpress.com/?p=268</guid>
		<description><![CDATA[I&#8217;ve been playing with Nexus 7 for few days now. I know it&#8217;s one of the strange devices with tvdpi &#8230;<p><a href="http://sriramramani.wordpress.com/2013/01/30/nebula-7/">Continue reading &#187;</a></p><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=sriramramani.wordpress.com&#038;blog=10234005&#038;post=268&#038;subd=sriramramani&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>I&#8217;ve been playing with Nexus 7 for few days now. I know it&#8217;s one of the strange devices with <strong>tvdpi</strong> sporting 216ppi. However, I didn&#8217;t feel anything different as such. While trying to solve the fuzzy <a href="http://bugzil.la/794942">refresh icon</a> problem, I found quite a lot of problems.</p>
<p><a href="http://sriramramani.wordpress.com/2013/01/30/nebula-7/nexus-7/" rel="attachment wp-att-269"><img src="http://sriramramani.files.wordpress.com/2013/01/nexus-7.png?w=791" alt="Nexus 7 Fuzziness"   class="aligncenter size-full wp-image-269" /></a></p>
<p>Basically Nexus 7 has a scaling factor of 1.33 (or is it 1.34?). Let&#8217;s take an image of size 50&#215;50 px in mdpi scale. The same image will be of size 75&#215;75 px for hdpi devices. Nexus 7 uses scales down this image to 67x67px. This would seem to look good if the image is flat with no shadows. However, Firefox for Android uses images with shadows to give an embossed feel over the textured background. A 2dp shadow is scaled to 3px on tvdpi, while a 4dp shadow is scaled to 5px. Basically a scale of 1.33 cannot yield a whole number like a scale of 1.5 (for any even number). And hence the rounded off scaled value can either be ceil or floor, causing the above visual artifacts.</p>
<p>So, isn&#8217;t there any solution? Not exactly! Like I mentioned, it&#8217;s hard to believe there is a problem with the scaling unless one watches it closely. If you compare the Nexus 4 and Nexus 7 side by side, the fuzziness is instantly noticeable all over the OS. The way default Android apps mitigate this is with the Holo theme. Since, in Holo theme all the icons are flat, with no shadows and gradients, the fuzziness is not that blatant. Does this enforce every app to follow Holo theme? That&#8217;s a big discussion in itself. However, that seems to mitigate the problem.</p>
<p><a href="http://sriramramani.wordpress.com/2013/01/30/nebula-7/nexus-7-fuzziness/" rel="attachment wp-att-270"><img src="http://sriramramani.files.wordpress.com/2013/01/nexus-7-fuzziness.png?w=400&#038;h=222" alt="Nexus-7-Fuzziness" width="400" height="222" class="aligncenter size-medium wp-image-270" /></a></p>
<p>Is this the only problem? Unfortunately, no! Canvas uses a lot of float calculations. With the device having a scaling factor of 1.33, the chances of getting a whole number on float multiplications is very less. For example, there is a white line to the right of refresh button in the above image. In Firefox for Android, we use a <a href="https://sriramramani.wordpress.com/2012/08/27/constructing-squishy-buttons/">cubic bezier path</a> to create those curves. The width of the curve is 1.125 times the height of the view. Since the curve is in the ActionBar, the height is 48dp on portrait, 40dp on landscape and 56dp on tablets. Hence the width of the curve will be 45dp, 54dp and 63dp respectively. Except for a HDPI tablet, these always yield whole numbers. On a HDPI tablet, the value defaults to its ceil value. However on Nexus 7, the width will be 74 * 1.125 = 83.25. (Note: 74 is the Android&#8217;s approximation of 56 at 1.33 scale). Using this float directly to set control points at 75% and 25% will result in floating values with 4 decimal places. This would make Android to round off the number to it&#8217;s floor value, leading to 1px difference than the intended value.</p>
<p>Hence, a scale like 1.33 is not helpful for the app developers in any ways! If Angry Birds is fuzzy on your Nexus 7, now you why!</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/sriramramani.wordpress.com/268/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/sriramramani.wordpress.com/268/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=sriramramani.wordpress.com&#038;blog=10234005&#038;post=268&#038;subd=sriramramani&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://sriramramani.wordpress.com/2013/01/30/nebula-7/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/98c2d4d449d87a611778e2ff107f3877?s=96&#38;d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">sriramramani</media:title>
		</media:content>

		<media:content url="http://sriramramani.files.wordpress.com/2013/01/nexus-7.png" medium="image">
			<media:title type="html">Nexus 7 Fuzziness</media:title>
		</media:content>

		<media:content url="http://sriramramani.files.wordpress.com/2013/01/nexus-7-fuzziness.png?w=400" medium="image">
			<media:title type="html">Nexus-7-Fuzziness</media:title>
		</media:content>
	</item>
		<item>
		<title>Compound Drawables</title>
		<link>http://sriramramani.wordpress.com/2013/01/15/compound-drawables/</link>
		<comments>http://sriramramani.wordpress.com/2013/01/15/compound-drawables/#comments</comments>
		<pubDate>Tue, 15 Jan 2013 07:03:27 +0000</pubDate>
		<dc:creator>Sriram Ramani</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[compound]]></category>
		<category><![CDATA[compound drawables]]></category>
		<category><![CDATA[custom-ui]]></category>
		<category><![CDATA[drawable]]></category>
		<category><![CDATA[mozilla]]></category>
		<category><![CDATA[myth]]></category>
		<category><![CDATA[optimization]]></category>
		<category><![CDATA[optimize]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[textview]]></category>

		<guid isPermaLink="false">http://sriramramani.wordpress.com/?p=260</guid>
		<description><![CDATA[Many a times we tend to add an image to a text for a Button. The pictorial representation of an &#8230;<p><a href="http://sriramramani.wordpress.com/2013/01/15/compound-drawables/">Continue reading &#187;</a></p><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=sriramramani.wordpress.com&#038;blog=10234005&#038;post=260&#038;subd=sriramramani&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>Many a times we tend to add an image to a text for a <code>Button</code>. The pictorial representation of an action is easier for the user to understand and provides a visual identity for the application. In Android, there is a general perception that this has needs a minimum of three views.</p>
<p><a href="http://sriramramani.wordpress.com/2013/01/15/compound-drawables/compound-drawable/" rel="attachment wp-att-261"><img src="http://sriramramani.files.wordpress.com/2013/01/compound-drawable.png?w=400&#038;h=400" alt="Compound Drawable" width="400" height="400" class="aligncenter size-medium wp-image-261" /></a></p>
<pre class="brush: xml; title: ; notranslate">
    &lt;LinearLayout android:orientation=&quot;horizontal&quot;&gt;
         &lt;ImageView ... the icon ... /&gt;
         &lt;TextView ... the text ... /&gt;
    &lt;/LinearLayout&gt;
</pre>
<p>However, Android provides a  way to add combine these views into a single view &#8212; a <code>TextView</code>. TextViews can optionally support <code>Drawables</code> in a view. They can be specified in XML or using Java methods. From the likes of it, based on the naming convention used, they wanted an approach to show borders like in HTML. However, they can be hacked to show much more than borders.</p>
<pre class="brush: xml; title: ; notranslate">
    &lt;TextView android:text=&quot; ... the text ... &quot;
              android:drawableLeft=&quot;@drawable/_the_icon_&quot;
              android:drawablePadding=&quot;_gap_to_icon&quot;/&gt;
</pre>
<p>The Drawable can be assigned to any direction, and more than one can be specified at a time. The distance between the drawable and the text is specified by the attribute <code>android:drawablePadding</code>. Unfortunately, the padding has to be the same on all sides. Also, this padding is different from the TextView&#8217;s padding. By default the image is shown at its actual size. What if the icon is huge and we don&#8217;t want it to be bigger than the text? Using Drawable&#8217;s <a href="http://developer.android.com/reference/android/graphics/drawable/Drawable.html#setBounds%28android.graphics.Rect%29">setBounds()</a>, we can set the size of the <code>Canvas</code> to use to render the Drawable. A drawable that is assigned as a compound drawable for a TextView should have its bounds set before being specified as one. The standard Android&#8217;s launcher uses this approach to show the icons with the name of the app. The menu items are also rendered in the same way. Though this doesn&#8217;t scale well for all purposes, for simpler cases, this reduces the views effectively.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/sriramramani.wordpress.com/260/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/sriramramani.wordpress.com/260/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=sriramramani.wordpress.com&#038;blog=10234005&#038;post=260&#038;subd=sriramramani&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://sriramramani.wordpress.com/2013/01/15/compound-drawables/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/98c2d4d449d87a611778e2ff107f3877?s=96&#38;d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">sriramramani</media:title>
		</media:content>

		<media:content url="http://sriramramani.files.wordpress.com/2013/01/compound-drawable.png?w=400" medium="image">
			<media:title type="html">Compound Drawable</media:title>
		</media:content>
	</item>
		<item>
		<title>Shaders</title>
		<link>http://sriramramani.wordpress.com/2012/12/21/shaders/</link>
		<comments>http://sriramramani.wordpress.com/2012/12/21/shaders/#comments</comments>
		<pubDate>Fri, 21 Dec 2012 08:52:21 +0000</pubDate>
		<dc:creator>Sriram Ramani</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[alpha compositing]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[bitmap]]></category>
		<category><![CDATA[bitmap shader]]></category>
		<category><![CDATA[bug]]></category>
		<category><![CDATA[canvas]]></category>
		<category><![CDATA[compose shader]]></category>
		<category><![CDATA[custom-ui]]></category>
		<category><![CDATA[drawable]]></category>
		<category><![CDATA[hack]]></category>
		<category><![CDATA[kinetic list view]]></category>
		<category><![CDATA[lightweight themes]]></category>
		<category><![CDATA[linear gradient]]></category>
		<category><![CDATA[mozilla]]></category>
		<category><![CDATA[offscreen bitmap]]></category>
		<category><![CDATA[optimization]]></category>
		<category><![CDATA[optimize]]></category>
		<category><![CDATA[paint]]></category>
		<category><![CDATA[porter-duff]]></category>
		<category><![CDATA[porter-duff mode]]></category>
		<category><![CDATA[porterduff]]></category>
		<category><![CDATA[radial gradient]]></category>
		<category><![CDATA[shader]]></category>
		<category><![CDATA[squishy-button]]></category>
		<category><![CDATA[texture]]></category>
		<category><![CDATA[themes]]></category>

		<guid isPermaLink="false">http://sriramramani.wordpress.com/?p=248</guid>
		<description><![CDATA[Lightweight themes are basically images aligned to the top-right corner of the desktop window. When we applied the same to &#8230;<p><a href="http://sriramramani.wordpress.com/2012/12/21/shaders/">Continue reading &#187;</a></p><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=sriramramani.wordpress.com&#038;blog=10234005&#038;post=248&#038;subd=sriramramani&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>Lightweight themes are basically images aligned to the top-right corner of the desktop window. When we applied the same to the mobile, the top-right corner is actually holding two buttons. Applying the image directly would remove the affordance of the buttons. Hence we wanted to bring the texture of the button with the image applied as a translucent layer on top of them. The way to achieve the translucent effect is described <a href="https://sriramramani.wordpress.com/2012/11/20/reflected-image-view/">here</a>. This is combined with a texture using a <a href="http://developer.android.com/reference/android/graphics/drawable/LayerDrawable.html">LayerDrawable</a>. This approached worked fine until the JellyBean MR1 release (Android 4.2.1 or version 17). The <code>LayerDrawable</code> broke in the latest release removing the affordance from the buttons.</p>
<p><a href="http://sriramramani.wordpress.com/2012/12/21/shaders/android-mutations/" rel="attachment wp-att-249"><img src="http://sriramramani.files.wordpress.com/2012/12/android-mutations.png?w=791" alt="Mutations"   class="aligncenter size-full wp-image-249" /></a></p>
<p>Going through the changesets in the Android codebase, the only new change to the Drawables in three years was related to <code>mutate()</code>. However this couldn&#8217;t all of a sudden affect how a drawable is drawn. What could be the problem? As it turns out, <code>LayerDrawable</code> tries to get a <code>ConstantState</code> of the drawable in its constructor. Our implementation of a <code>LightweightThemeDrawable</code> relied on a <code>BitmapDrawable</code> for the same. And since <code>BitmapDrawable</code> doesn&#8217;t know that it&#8217;s <code>draw()</code> is going to be overriden, it is going to give it&#8217;s own <code>ConstantState</code>, which wouldn&#8217;t add translucency.</p>
<p>Now the visible solution in hand is to implement the <code>ConstantState</code> for the <code>LightweightThemeDrawable</code>. This drawable is going to be used for just one button. The bitmap is not going to be shared between the buttons as it is not a texture. Do we really need to maintain a constant state? What other option could save us here? Let&#8217;s look at how this drawable would be, if defined in XML.</p>
<pre class="brush: xml; title: ; notranslate">
&lt;layer-list&gt;

    &lt;!-- The translucent drawable, with transparency applied by overriding draw() --&gt;
    &lt;item android:drawable=&quot;@drawable/_the_theme_image_&quot;/&gt;

    &lt;!-- The texture beneath --&gt;
    &lt;item android:drawable=&quot;@drawable/_repeating_texture_bitmap_&quot;/&gt;

&lt;/layer-list&gt;
</pre>
<p>Is there a way to combine these layers into one? When given a <code>Canvas</code>, we need to paint the texture once, and then a bitmap. Since we are creating a custom drawable for translucency, we can reuse the same to draw the texture too. The good news is that the translucency can be achieved in a even better way if we use <a href="http://developer.android.com/reference/android/graphics/Shader.html">Shaders</a>. Shaders are more like Photoshop brushes. We could use a pattern and paint over the canvas in Photoshop using a brush. The same holds for Canvas in Android too. </p>
<p>A repeating shader for Bitmap is easy. We need to create a <a href="http://developer.android.com/reference/android/graphics/BitmapShader.html">BitmapShader</a> that holds the repeating bitmap to be drawn. The snippet below checks to see if the textureId specified is a texture in <code>drawable-nodpi/</code> or a BitmapDrawable that already defines how to repeat the texture. In the first case, the texture is repeated in both directions. In the second case, the texture is repeated as specified in the drawable.</p>
<pre class="brush: java; title: ; notranslate">
    public void setTexture(int textureId) {
        Shader.TileMode modeX = Shader.TileMode.REPEAT;
        Shader.TileMode modeY = Shader.TileMode.REPEAT;

        // The texture to be repeated.
        Bitmap texture = BitmapFactory.decodeResource(mResources, textureId);

        if (texture == null) {
            // Texture may be used inside a BitmapDrawable.
            Drawable drawable = mResources.getDrawable(textureId);
            if (drawable != null &amp;&amp; drawable instanceof BitmapDrawable) {
                BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;
                texture = bitmapDrawable.getBitmap();
                modeX = bitmapDrawable.getTileModeX();
                modeY = bitmapDrawable.getTileModeY();
            }
        }

        // Set the shader for the texture paint.
        if (texture != null) {
            mTexturePaint = new Paint();
            mTexturePaint.setAntiAlias(true);
            mTexturePaint.setShader(new BitmapShader(texture, modeX, modeY));
        }
    }
</pre>
<p>As mentioned before, the translucency can be achieved in one go with Shaders. A <a href="http://developer.android.com/reference/android/graphics/ComposeShader.html">ComposeShader</a> takes two shaders and combines them using a <a href="http://developer.android.com/reference/android/graphics/PorterDuff.Mode.html">PorterDuff-Mode</a>. With the bitmap&#8217;s shader as the DST and the <a href="http://developer.android.com/reference/android/graphics/LinearGradient.html">LinearGradient</a> as the SRC, we can use a <code>DST_IN</code> mode to get the translucency effect.</p>
<pre class="brush: java; title: ; notranslate">
    @Override
    protected void onBoundsChange(Rect bounds) {
        super.onBoundsChange(bounds);

        // A bitmap-shader to draw the bitmap.
        // mBitmap is usually passed as an argument for the constructor.
        // Clamp mode will repeat the last row of pixels.
        // Hence its better to have an endAlpha of 0 for the linear-gradient.
        BitmapShader bitmapShader = new BitmapShader(mBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);

        // A linear-gradient to specify the opacity of the bitmap.
        // mStartColor and mEndColor have just the alpha bits set to required value. E.g.: 0xAA000000.
        LinearGradient gradient = new LinearGradient(0, 0, 0, mBitmap.getHeight(), 
                                                     mStartColor, mEndColor, Shader.TileMode.CLAMP);

        // Make a combined shader -- a performance win.
        // The linear-gradient is the 'SRC' and the bitmap-shader is the 'DST'.
        // Drawing the DST in the SRC will provide the opacity.
        mPaint.setShader(new ComposeShader(bitmapShader, gradient, PorterDuff.Mode.DST_IN));
    }
</pre>
<p>We have a shader for the texture and a shader for the bitmap. All we need to do.. is paint them!</p>
<pre class="brush: java; title: ; notranslate">
    @Override
    public void draw(Canvas canvas) {
        // Draw the texture.
        canvas.drawPaint(mTexturePaint);

        // Draw the bitmap.
        canvas.drawPaint(mPaint);
    }
</pre>
<p>And we have the solution! In fact, the base layer needn&#8217;t be a texture. We could just paint a color and paint the bitmap over it. Shaders can be used to do many other effects. What would setting up an alpha based shader, like RadialGradient, from transparency to black, and drawing it on a bitmap look like? A vignette effect! What would adding a red LinearGradient for a shader and using a <code>MULTIPLY</code> look like? A saturated sun-set effect! Have you started dreaming of implementing Instagram filters already? The greatest advantage over <a href="https://sriramramani.wordpress.com/2012/08/27/constructing-squishy-buttons/">my previous post</a> is that this is all drawn by Paint in one go. We don&#8217;t need offscreen bitmap processing to worry about handling opaque areas.</p>
<p><strong>Note:</strong> Painting the Canvas twice could result in overdraw. This complex effect of painting over a texture wouldn&#8217;t be needed in most applications. In that case, a ComposeShader will result in a single time painting. In case you would want to combine the two shaders above, you could do that. It might work.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/sriramramani.wordpress.com/248/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/sriramramani.wordpress.com/248/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=sriramramani.wordpress.com&#038;blog=10234005&#038;post=248&#038;subd=sriramramani&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://sriramramani.wordpress.com/2012/12/21/shaders/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/98c2d4d449d87a611778e2ff107f3877?s=96&#38;d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">sriramramani</media:title>
		</media:content>

		<media:content url="http://sriramramani.files.wordpress.com/2012/12/android-mutations.png" medium="image">
			<media:title type="html">Mutations</media:title>
		</media:content>
	</item>
		<item>
		<title>Runtime Theme Change</title>
		<link>http://sriramramani.wordpress.com/2012/12/06/runtime-theme-change/</link>
		<comments>http://sriramramani.wordpress.com/2012/12/06/runtime-theme-change/#comments</comments>
		<pubDate>Thu, 06 Dec 2012 08:49:03 +0000</pubDate>
		<dc:creator>Sriram Ramani</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[actionbar]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[application]]></category>
		<category><![CDATA[custom attributes]]></category>
		<category><![CDATA[custom-ui]]></category>
		<category><![CDATA[dark themes]]></category>
		<category><![CDATA[duplicateParentState]]></category>
		<category><![CDATA[inflate]]></category>
		<category><![CDATA[light themes]]></category>
		<category><![CDATA[menu]]></category>
		<category><![CDATA[mozilla]]></category>
		<category><![CDATA[myth]]></category>
		<category><![CDATA[optimization]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[pocket]]></category>
		<category><![CDATA[read it later]]></category>
		<category><![CDATA[runtime theme change]]></category>
		<category><![CDATA[theme change]]></category>
		<category><![CDATA[themes]]></category>
		<category><![CDATA[ui xml snapshot]]></category>
		<category><![CDATA[window]]></category>

		<guid isPermaLink="false">http://sriramramani.wordpress.com/?p=238</guid>
		<description><![CDATA[It&#8217;s a known fact in Android that themes cannot be changed during runtime. If the new theme change has to &#8230;<p><a href="http://sriramramani.wordpress.com/2012/12/06/runtime-theme-change/">Continue reading &#187;</a></p><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=sriramramani.wordpress.com&#038;blog=10234005&#038;post=238&#038;subd=sriramramani&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>It&#8217;s a known fact in Android that themes cannot be changed during runtime. If the new theme change has to be reflected in the application, all the views have to be re-inflated, as the theme based values are parsed only once during inflation. However, the beautiful <a href="https://play.google.com/store/apps/details?id=com.ideashower.readitlater.pro">Pocket</a> for Android app switches between black and white themes in a jiffy! How did they achieve something that has been declared by the Android community as impossible? The <code>ActionBar</code> background, the text colors, the image colors, and the <code>Menu</code> background have all changed. Since it&#8217;s not a single line change, let&#8217;s chop it into pieces.</p>
<p><a href="http://sriramramani.wordpress.com/2012/12/06/runtime-theme-change/pocket/" rel="attachment wp-att-239"><img src="http://sriramramani.files.wordpress.com/2012/12/pocket.png?w=400&#038;h=311" alt="Pocket&#039;s Themes" width="400" height="311" class="aligncenter size-medium wp-image-239" /></a></p>
<p>There are clearly two things that make it feel like the theme has changed from Holo Dark to a Light version &#8212; the ActionBar and the Menu. The good thing with menu is that it uses a <code>ListView</code> to show the items. Hence it gets re-created every time it is shown. Now a theme change during runtime will change the menu items for sure. A small theme change code will be like:</p>
<pre class="brush: xml; title: ; notranslate">
&lt;!-- somewhere in themes.xml --&gt;
&lt;resources xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;&gt;

    &lt;!-- light theme --&gt;
    &lt;style name=&quot;AppTheme&quot; parent=&quot;@android:style/Theme.Holo.Light&quot;/&gt;

    &lt;!-- dark theme --&gt;
    &lt;style name=&quot;AppTheme.Dark&quot; parent=&quot;@android:style/Theme.Holo&quot;/&gt;

&lt;/resources&gt;
</pre>
<p>And we could change the theme in Java as:</p>
<pre class="brush: java; title: ; notranslate">
    // somewhere in the activity
    private void changeTheme(boolean isLight) {
        setTheme(isLight ? R.style.AppTheme : R.style.AppTheme_Dark);
    }
</pre>
<p>That solves the menu problem! How about ActionBar? This is where Pocket has a very clever approach. The ActionBar is clearly not a custom UI. Hence, a call like <code>getActionBar().getCustomView()</code> will return <code>null</code>. If we had such a view, we could easily change the background color, couldn&#8217;t we? In this case, ActionBar is fully owned by Android and we don&#8217;t have any control over it&#8217;s appearance, except that is defined in themes.xml. Also, we cannot re-inflate the ActionBar too &#8212; unless we plan to show a custom view.</p>
<p>Let&#8217;s take a step back. Where is the actual app content placed on phone? Based on the UI XML Snapshot (that&#8217;s so cool!), a typical app will have views like:</p>
<pre class="brush: xml; title: ; notranslate">
&lt;!-- A bunch of FrameLayout as ancestors for core android ...and then --&gt;
&lt;!-- Window of the application --&gt;
&lt;FrameLayout&gt;

    &lt;!-- Content of the application --&gt;
    &lt;RelativeLayout&gt;

        &lt;!-- ActionBar owned by Android --&gt;
        &lt;LinearLayout /&gt;

        &lt;!-- Actual content of the application defined in our layout.xml --&gt;
        &lt;LinearLayout or RelativeLayout or FrameLayout /&gt;

    &lt;/RelativeLayout&gt;

&lt;/FrameLayout&gt;
</pre>
<p>And we can get the <code>Window</code> of the application &#8212; which is a FrameLayout &#8212; and can set a background! So, if the views contained by it are translucent, the Window&#8217;s background will be seen. Choosing a mid-grey for the translucent layer and changing the background to be black or white could give magical effects.</p>
<p><a href="http://sriramramani.wordpress.com/2012/12/06/runtime-theme-change/color-matrix/" rel="attachment wp-att-242"><img src="http://sriramramani.files.wordpress.com/2012/12/color-matrix.png?w=791" alt="Color Matrix"   class="aligncenter size-full wp-image-242" /></a></p>
<p>Did we just have two color themes by just changing the Window background? Changing the window background color is pretty simple.</p>
<pre class="brush: java; title: ; notranslate">
    // somewhere in the activity
    private void changeTheme(boolean isLight) {
        getWindow().setBackgroundDrawable(new ColorDrawable(isLight ? Color.WHITE : Color.BLACK));
    }
</pre>
<p>And that&#8217;s the magic behind a two-color ActionBar in Pocket. The icons are all translucent, making them feel like they change based on the Holo theme used. The text part is pretty easy. Inflating the views again is unnecessary. Adding <a href="https://sriramramani.wordpress.com/2012/11/17/custom-states/">a custom state</a> can switch themes in a jiffy. Firefox for Android uses this technique to swiftly change color scheme between normal and private browsing modes. One good trick here is to make the children duplicate their parent state.</p>
<pre class="brush: xml; title: ; notranslate">
&lt;!-- some layout file for the activity --&gt;
&lt;LinearLayout ...attributes...&gt;
    &lt;Button ...attributes...
            android:duplicateParentState=&quot;true&quot;/&gt;

    &lt;TextView ...attributes...
              android:duplicateParentState=&quot;true&quot;/&gt;
&lt;/LinearLayout&gt;
</pre>
<p>In the above layout, changing the custom state, say &#8220;state_light_theme_enabled&#8221;, of <code>LinearLayout</code> will propagate down to its children too. So a single call on the root level element can do wonders. And thereby, we can change themes &#8212; or make it feel like &#8212; within 250ms. This technique is not restricted for monochrome. This works with normal colors too.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/sriramramani.wordpress.com/238/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/sriramramani.wordpress.com/238/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=sriramramani.wordpress.com&#038;blog=10234005&#038;post=238&#038;subd=sriramramani&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://sriramramani.wordpress.com/2012/12/06/runtime-theme-change/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:thumbnail url="http://sriramramani.files.wordpress.com/2012/12/pocket.png?w=150" />
		<media:content url="http://sriramramani.files.wordpress.com/2012/12/pocket.png?w=150" medium="image">
			<media:title type="html">Pocket&#039;s Themes</media:title>
		</media:content>

		<media:content url="http://0.gravatar.com/avatar/98c2d4d449d87a611778e2ff107f3877?s=96&#38;d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">sriramramani</media:title>
		</media:content>

		<media:content url="http://sriramramani.files.wordpress.com/2012/12/pocket.png?w=400" medium="image">
			<media:title type="html">Pocket&#039;s Themes</media:title>
		</media:content>

		<media:content url="http://sriramramani.files.wordpress.com/2012/12/color-matrix.png" medium="image">
			<media:title type="html">Color Matrix</media:title>
		</media:content>
	</item>
		<item>
		<title>Custom Fonts</title>
		<link>http://sriramramani.wordpress.com/2012/11/29/custom-fonts/</link>
		<comments>http://sriramramani.wordpress.com/2012/11/29/custom-fonts/#comments</comments>
		<pubDate>Thu, 29 Nov 2012 11:50:24 +0000</pubDate>
		<dc:creator>Sriram Ramani</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[custom fonts]]></category>
		<category><![CDATA[custom-ui]]></category>
		<category><![CDATA[fileset]]></category>
		<category><![CDATA[font]]></category>
		<category><![CDATA[font family]]></category>
		<category><![CDATA[font familyset]]></category>
		<category><![CDATA[fontFamily]]></category>
		<category><![CDATA[fonts]]></category>
		<category><![CDATA[mozilla]]></category>
		<category><![CDATA[myth]]></category>
		<category><![CDATA[nameset]]></category>
		<category><![CDATA[optimize]]></category>
		<category><![CDATA[parser]]></category>
		<category><![CDATA[textview]]></category>
		<category><![CDATA[typeface]]></category>
		<category><![CDATA[xml]]></category>
		<category><![CDATA[xml parser]]></category>

		<guid isPermaLink="false">http://sriramramani.wordpress.com/?p=228</guid>
		<description><![CDATA[A general myth in Android is that it has only one font, as opposed to iOS&#8217;s 50+ fonts. It&#8217;s not &#8230;<p><a href="http://sriramramani.wordpress.com/2012/11/29/custom-fonts/">Continue reading &#187;</a></p><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=sriramramani.wordpress.com&#038;blog=10234005&#038;post=228&#038;subd=sriramramani&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>A general myth in Android is that it has only one font, as opposed to iOS&#8217;s 50+ fonts. It&#8217;s not easy enough to support custom fonts in Android. Hence developers were forced to fall in love with Roboto. However, few manufacturers like Samsung started shipping phones with their custom fonts. Should an application use its own font on Android, or follow Holo-ish theme and use Roboto always? If so, are applications losing their brand identity? How would internet be if all webpages had to use just one <a href="http://www.splicd.com/D1R-jKKp3NA/210/267">font</a>?</p>
<p>Since that&#8217;s a big discussion by itself, let&#8217;s skip that and investigate if we can support fonts. There are few <a href="http://www.barebonescoder.com/2010/05/android-development-using-custom-fonts/">blogs</a> explaining how one can add new fonts. The general idea here is to add the font to <code>assets</code> in project directory, and apply it to the individual views. Should we have to apply the Typeface individually to each element, after it is inflated? (Does this sound like loading a HTML page with default font, and changing the CSS to a custom font &#8212; which loads later?). A better approach would be to add a custom attribute, say <code>font</code> in XML, and use it to specify the path to the font. But font is a heavy resource and shared among many views (a flyweight pattern!). Hence, its better to cache the fonts and use them. So, a direct path to the font file wouldn&#8217;t work.</p>
<p>Coming from HTML background, the CSS has a <code>font-family</code> attribute that can be used to specify a font family for a group of classes or HTML elements. How could we use a similar concept in Android? In fact, Android supports such a <a href="http://developer.android.com/reference/android/widget/TextView.html#attr_android:fontFamily">property</a> starting with JellyBean. However, this still doesn&#8217;t support user&#8217;s custom fonts. There are various styles of Roboto that can be used &#8212; like sans-serif, sans-serif-light or sans-serif-condensed. Let&#8217;s tie them all together to build a <code>FontManager</code> that can support a CSS like <code>font-family</code>, which effectively caches resources.</p>
<p><a href="http://sriramramani.wordpress.com/2012/11/29/custom-fonts/fonts/" rel="attachment wp-att-229"><img src="http://sriramramani.files.wordpress.com/2012/11/fonts.png?w=225&#038;h=400" alt="" width="225" height="400" class="aligncenter size-medium wp-image-229" /></a></p>
<p>Digging into the Android SDK, I found out how Android specifies the list of fonts it supports. If you look into the file: _sdk-directory_/platforms/android-16/data/fonts/system_fonts.xml, you could see a similar XML like below. A <code>family</code> specifies a particular font-type. This has a list of names that it can respond to, specified in <code>nameset</code> and a list of files that specifies the different styles, specified in <code>fileset</code>. And, <code>familyset</code> is a parent tag, more like the <code>resources</code> tag.</p>
<pre class="brush: xml; title: ; notranslate">
&lt;familyset&gt;
    &lt;family&gt;
        &lt;nameset&gt;
            &lt;name&gt;sans-serif&lt;/name&gt;
            &lt;name&gt;arial&lt;/name&gt;
            &lt;name&gt;helvetica&lt;/name&gt;
            &lt;name&gt;tahoma&lt;/name&gt;
            &lt;name&gt;verdana&lt;/name&gt;
        &lt;/nameset&gt;
        &lt;fileset&gt;
            &lt;file&gt;Roboto-Regular.ttf&lt;/file&gt;
            &lt;file&gt;Roboto-Bold.ttf&lt;/file&gt;
            &lt;file&gt;Roboto-Italic.ttf&lt;/file&gt;
            &lt;file&gt;Roboto-BoldItalic.ttf&lt;/file&gt;
        &lt;/fileset&gt;
    &lt;/family&gt;
&lt;/familyset&gt;
</pre>
<p>For the sake of easy understanding, lets create our parser based on this. Since any file in <code>res/values/</code> expects tags only known to Android, we can add a file with these tags in a file, say <code>fonts.xml</code> in <code>res/xml/</code> folder. I downloaded a couple of fonts from Google web fonts, added it to assets folder, and specified them in a XML like below. Here, Montaga has just one style &#8212; Regular, while OpenSans supports four different styles. Also, OpenSans could respond to &#8220;opensans&#8221;, &#8220;open-sans&#8221;, &#8220;sans&#8221; or &#8220;sans-serif&#8221; as font-family.</p>
<pre class="brush: xml; title: ; notranslate">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;familyset&gt;
    
    &lt;!--  Montaga --&gt;
    &lt;family&gt;
        &lt;nameset&gt;
            &lt;name&gt;montaga&lt;/name&gt;
        &lt;/nameset&gt;
        &lt;fileset&gt;
            &lt;file&gt;fonts/Montaga-Regular.ttf&lt;/file&gt;
        &lt;/fileset&gt;
    &lt;/family&gt;
    
    
    &lt;!--  Open Sans --&gt;
    &lt;family&gt;
        &lt;nameset&gt;
            &lt;name&gt;opensans&lt;/name&gt;
            &lt;name&gt;open-sans&lt;/name&gt;
            &lt;name&gt;sans&lt;/name&gt;
            &lt;name&gt;sans-serif&lt;/name&gt;
        &lt;/nameset&gt;
        &lt;fileset&gt;
            &lt;file&gt;fonts/OpenSans-Regular.ttf&lt;/file&gt;
            &lt;file&gt;fonts/OpenSans-Bold.ttf&lt;/file&gt;
            &lt;file&gt;fonts/OpenSans-Italic.ttf&lt;/file&gt;
            &lt;file&gt;fonts/OpenSans-BoldItalic.ttf&lt;/file&gt;
        &lt;/fileset&gt;
    &lt;/family&gt;

&lt;/familyset&gt;
</pre>
<p>Since we are adding a custom attribute, we need to create custom views. Also, fonts work as a combination of Typeface and the style (bold/italic/bold and italic/normal). We could use <code>android:textStyle</code> in our custom styleable attribute <code>Fonts</code>.</p>
<pre class="brush: xml; title: ; notranslate">
&lt;resources&gt;
    &lt;declare-styleable name=&quot;Fonts&quot;&gt;
        &lt;!-- using android's --&gt;
        &lt;attr name=&quot;android:textStyle&quot; /&gt;

        &lt;!-- our custom attribute --&gt;
        &lt;attr name=&quot;fontFamily&quot; format=&quot;string&quot; /&gt;
    &lt;/declare-styleable&gt;
&lt;/resources&gt;
</pre>
<p>And the custom TextView will be like,</p>
<pre class="brush: java; title: ; notranslate">
    public class FontView extends TextView {
        public FontView(Context context, AttributeSet attrs) {
            super(context, attrs);
		
            // Fonts work as a combination of particular family and the style. 
            TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.Fonts);
            String family = a.getString(R.styleable.Fonts_fontFamily);
            int style = a.getInt(R.styleable.Fonts_android_textStyle, -1);
            a.recycle();

            // Set the typeface based on the family and the style combination.
            setTypeface(FontManager.getInstance().get(family, style));
       }
    }
</pre>
<p>And the parser for the XML,</p>
<pre class="brush: java; title: ; notranslate">
public class FontManager {
	
    //Making FontManager a singleton class
    private static class InstanceHolder {
        private static final FontManager INSTANCE = new FontManager();
    }

    public static FontManager getInstance() {
       return FontManager.InstanceHolder.INSTANCE;
    }
	
    private FontManager() { }
    
    // Different tags used in XML file.
    private static final String TAG_FAMILY = &quot;family&quot;;
    private static final String TAG_NAMESET = &quot;nameset&quot;;
    private static final String TAG_NAME = &quot;name&quot;;
    private static final String TAG_FILESET = &quot;fileset&quot;;
    private static final String TAG_FILE = &quot;file&quot;;
	
    // Different styles supported.
    private static final String STYLE_BOLD = &quot;-Bold.ttf&quot;;
    private static final String STYLE_ITALIC = &quot;-Italic.ttf&quot;;
    private static final String STYLE_BOLDITALIC = &quot;-BoldItalic.ttf&quot;;
	
    private class FontStyle {
        int style;
        Typeface font;
    }
	
    private class Font {
        // different font-family names that this Font will respond to.
        List&lt;String&gt; families;
		
        // different styles for this font.
        List&lt;FontStyle&gt; styles;
    }
	
	private List&lt;Font&gt; mFonts;

	//private boolean isFamilySet = false;
	private boolean isName = false;
	private boolean isFile = false;
	
	// Parse the resId and initialize the parser.
	public void initialize(Context context, int resId) {
		XmlResourceParser parser = null;
		try {
			parser = context.getResources().getXml(resId);
			mFonts = new ArrayList&lt;Font&gt;();

			String tag;
			int eventType = parser.getEventType();
			
			Font font = null;

			do {
				tag = parser.getName();

				switch (eventType) {
					case XmlPullParser.START_TAG:
						if (tag.equals(TAG_FAMILY)) {
							// one of the font-families.
							font = new Font();
						} else if (tag.equals(TAG_NAMESET)) {
							// a list of font-family names supported.
							font.families = new ArrayList&lt;String&gt;();
						} else if (tag.equals(TAG_NAME)) {
							isName = true;
						} else if (tag.equals(TAG_FILESET)) {
							// a list of files specifying the different styles.
							font.styles = new ArrayList&lt;FontStyle&gt;();
						} else if (tag.equals(TAG_FILE)) {
							isFile = true;
						}
						break;

					case XmlPullParser.END_TAG:
						if (tag.equals(TAG_FAMILY)) {
							// add it to the list.
							if (font != null) {
								mFonts.add(font);
								font = null;
							}
						} else if (tag.equals(TAG_NAME)) {
							isName = false;
						} else if (tag.equals(TAG_FILE)) {
							isFile = false;
						}
					break;
					
					case XmlPullParser.TEXT:
						String text = parser.getText();
						if (isName) {
							// value is a name, add it to list of family-names.
							if (font.families != null)
								font.families.add(text);
						} else if (isFile) {
							// value is a file, add it to the proper kind.
							FontStyle fontStyle = new FontStyle();
							fontStyle.font = Typeface.createFromAsset(context.getAssets(), text);
							
							if (text.endsWith(STYLE_BOLD))
								fontStyle.style = Typeface.BOLD;
							else if (text.endsWith(STYLE_ITALIC))
								fontStyle.style = Typeface.ITALIC;
							else if (text.endsWith(STYLE_BOLDITALIC))
								fontStyle.style = Typeface.BOLD_ITALIC;
							else
								fontStyle.style = Typeface.NORMAL;
							
							font.styles.add(fontStyle);
						}
					}

				eventType = parser.next();

			} while (eventType != XmlPullParser.END_DOCUMENT);

		} catch (XmlPullParserException e) {
			throw new InflateException(&quot;Error inflating font XML&quot;, e);
		} catch (IOException e) {
			throw new InflateException(&quot;Error inflating font XML&quot;, e);
		} finally {
			if (parser != null)
				parser.close();
		}
	}
	
	public Typeface get(String family, int style) {
		for (Font font: mFonts) {
			for (String familyName : font.families) {
				if (familyName.equals(family)) {
					// if no style in specified, return normal style.
					if (style == -1)
						style = Typeface.NORMAL;
					
					for (FontStyle fontStyle : font.styles) {
						if (fontStyle.style == style)
							return fontStyle.font;
					}
				}
			}
		}
			
	    return null;
	}
}
</pre>
<p>Now the activity should make sure to load the fonts, so that when the views are inflated, they know to get the font from the FontManager. The following piece of code needs to be added before <code>setContentView()</code> in <code>onCreate()</code>.</p>
<pre class="brush: java; title: ; notranslate">
    // Set up the font parser with the fonts.xml resource.
    FontManager.getInstance().initialize(this, R.xml.fonts);
</pre>
<p>With so much of plumbing what did we achieve? Quite a lot! Lets see what all this can do.</p>
<pre class="brush: xml; title: ; notranslate">
    &lt;!-- In any layout, we could specify the fontFamily to the custom views.
         &quot;sirius&quot; is our custom namespace for our application --&gt;

    &lt;!-- Regular font --&gt;
    &lt;FontView style=&quot;@style/CustomFont&quot;
              android:text=&quot;Montaga&quot;
              sirius:fontFamily=&quot;montaga&quot;/&gt;
    
    &lt;!-- fontFamily as opensans --&gt;
    &lt;FontView style=&quot;@style/CustomFont&quot;
              android:text=&quot;OpenSans - Regular&quot;
              sirius:fontFamily=&quot;opensans&quot;/&gt;

    &lt;!-- textStyle is &quot;italic&quot; and family is &quot;sans&quot; --&gt;
    &lt;FontView style=&quot;@style/CustomFont&quot;
              android:text=&quot;OpenSans - Italic&quot;
              android:textStyle=&quot;italic&quot;
              sirius:fontFamily=&quot;sans&quot;/&gt;

    &lt;!-- The font family can be specified in the styles.xml --&gt;
    &lt;FontView style=&quot;@style/OpenSans.Bold&quot; /&gt;


    &lt;!-- In styles.xml, we can create hierarchies of styles with different fonts.
         Note that the attribute names are unbounded, as they are in our scope. --&gt;
    &lt;style name=&quot;OpenSans&quot;&gt;
        &lt;item name=&quot;fontFamily&quot;&gt;opensans&lt;/item&gt;
    &lt;/style&gt;

    &lt;style name=&quot;OpenSans.Bold&quot;&gt;
        &lt;item name=&quot;android:textStyle&quot;&gt;bold&lt;/item&gt;
    &lt;/style&gt;

    &lt;style name=&quot;OpenSans.Bold.Italic&quot;&gt;
        &lt;item name=&quot;android:textStyle&quot;&gt;bold|italic&lt;/item&gt;
    &lt;/style&gt;

</pre>
<p>So, any view that can support custom fonts, can either specify it in its own attribute list, or as a part of it&#8217;s style. In fact, we could specify this attribute in themes.xml, and let our application use a default font! Did we just make it look like a HTML page? Oh wait! Did we just allow developers to develop applications with&#8230; Comic Sans MS?</p>
<p>Note: The fonts used here are for demonstration purposes only. I don&#8217;t own any right to ship it (as I don&#8217;t understand the big complex font licensing that Google talks about).</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/sriramramani.wordpress.com/228/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/sriramramani.wordpress.com/228/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=sriramramani.wordpress.com&#038;blog=10234005&#038;post=228&#038;subd=sriramramani&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://sriramramani.wordpress.com/2012/11/29/custom-fonts/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/98c2d4d449d87a611778e2ff107f3877?s=96&#38;d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">sriramramani</media:title>
		</media:content>

		<media:content url="http://sriramramani.files.wordpress.com/2012/11/fonts.png?w=225" medium="image" />
	</item>
		<item>
		<title>Reflected Image View</title>
		<link>http://sriramramani.wordpress.com/2012/11/20/reflected-image-view/</link>
		<comments>http://sriramramani.wordpress.com/2012/11/20/reflected-image-view/#comments</comments>
		<pubDate>Tue, 20 Nov 2012 08:08:29 +0000</pubDate>
		<dc:creator>Sriram Ramani</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[alpha compositing]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[canvas]]></category>
		<category><![CDATA[custom-ui]]></category>
		<category><![CDATA[gradient]]></category>
		<category><![CDATA[image-view]]></category>
		<category><![CDATA[imageview]]></category>
		<category><![CDATA[lightweight themes]]></category>
		<category><![CDATA[linear gradient]]></category>
		<category><![CDATA[mozilla]]></category>
		<category><![CDATA[paint]]></category>
		<category><![CDATA[personas]]></category>
		<category><![CDATA[porter-duff mode]]></category>
		<category><![CDATA[porterduff]]></category>
		<category><![CDATA[reflected]]></category>
		<category><![CDATA[reflected image view]]></category>
		<category><![CDATA[shader]]></category>
		<category><![CDATA[themes]]></category>

		<guid isPermaLink="false">http://sriramramani.wordpress.com/?p=218</guid>
		<description><![CDATA[While implementing lightweight themes for mobile, a decision was made to use the same images as the desktop, as there &#8230;<p><a href="http://sriramramani.wordpress.com/2012/11/20/reflected-image-view/">Continue reading &#187;</a></p><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=sriramramani.wordpress.com&#038;blog=10234005&#038;post=218&#038;subd=sriramramani&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>While implementing lightweight themes for mobile, a decision was made to use the same images as the desktop, as there are plenty of personas available at <a href="http://www.getpersonas.com">getpersonas.com</a>. However there was a problem. The images are of size 3000&#215;200 pixels and are optimized for the desktop browser. But the mobile phones are usually in portrait format. Also, the height of the device will definitely be more than 200 pixels (Samsung S IV is 441 ppi!). How do we use the same image in mobile then? We resorted to using the dominant color for the background. But the place where the image and dominant color matches will be an abrupt shift. How do we fix this? We decided to gradually fade the image and merge it with the background color. </p>
<p>Let&#8217;s see how we can gradually fade-in an image. The reflected image in the screenshot has <code>android:rotationX</code> set to 180, and is a separate image.</p>
<p><a href="http://sriramramani.wordpress.com/2012/11/20/reflected-image-view/reflected-image-view/" rel="attachment wp-att-219"><img src="http://sriramramani.files.wordpress.com/2012/11/reflected-image-view.png?w=225&#038;h=400" alt="" title="Reflected Image View" width="225" height="400" class="aligncenter size-medium wp-image-219" /></a></p>
<p>The idea is to use a <a href="http://developer.android.com/reference/android/graphics/Shader.html">Shader</a> with the <a href="http://developer.android.com/reference/android/graphics/Paint.html">Paint</a> used for drawing on the <a href="http://developer.android.com/reference/android/graphics/Canvas.html">Canvas</a>. We want the image to be opaque on the top and transparent at the bottom. A <a href="http://developer.android.com/reference/android/graphics/LinearGradient.html">LinearGradient</a> from black to transparent could achieve this effect.</p>
<pre class="brush: java; title: ; notranslate">
public class ReflectedImageView extends ImageView {
    private Paint mPaint;
    
    public ReflectedImageView(Context context, AttributeSet attrs) {
        super(context, attrs);

        // Setup the paint.
        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mPaint.setColor(0xFFFF0000);
        mPaint.setStrokeWidth(0.0f);
        
        // Destination (DST) is drawn by the parent, and should be retained.
        mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
    }
    
    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);
        
        // It's recommended not to create a Shader in the basic layout calls.
        // Linear gradient from Transparent to Black, from top to bottom.
        // Note: We rotated the image using a transformation.
        // Hence the colors will be opposite.
        LinearGradient gradient = new LinearGradient(0, 0, 0, bottom - top, 
                                                     0x0, 0xFF000000,
                                                     Shader.TileMode.CLAMP);
        
        // Set the gradient as the shader.
        mPaint.setShader(gradient);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        // Save the canvas. All PorterDuff operations should be done in a offscreen bitmap.
        int count = canvas.saveLayer(0, 0, canvas.getWidth(), canvas.getHeight(), null,
                                     Canvas.MATRIX_SAVE_FLAG |
                                     Canvas.CLIP_SAVE_FLAG |
                                     Canvas.HAS_ALPHA_LAYER_SAVE_FLAG |
                                     Canvas.FULL_COLOR_LAYER_SAVE_FLAG |
                                     Canvas.CLIP_TO_LAYER_SAVE_FLAG);


        
        // Do a default draw.
        super.onDraw(canvas);
        
        // Draw the paint (that has a shader set), on top of the image
        // drawn by the parent (ImageView).
        // Note: This works only on ICS. For pre-ICS phones, create a bitmap and
        // draw on it, like mentioned in CanvasDelegate linked below.
        canvas.drawPaint(mPaint);
        
        // Restore the canvas.
        canvas.restoreToCount(count);
    }
}
</pre>
<p>That gives a nice glossy feel for the image. This method was earlier used in drawing the <a href="https://sriramramani.wordpress.com/2012/08/27/constructing-squishy-buttons/">tabs button</a>. To re-use the logic, Fennec uses a <a href="http://hg.mozilla.org/mozilla-central/file/tip/mobile/android/base/LightweightThemeDrawable.java">LightweightThemeDrawable</a>, that uses a <a href="http://hg.mozilla.org/mozilla-central/file/tip/mobile/android/base/CanvasDelegate.java">CanvasDelegate</a>, which takes care of drawing on the canvas. Grab an aurora build today to give this a try!</p>
<p><strong>Update:</strong> A better approach would be to use <a href="https://sriramramani.wordpress.com/2012/12/21/shaders/">Shaders</a>. This reduces the need for a offscreen bitmap.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/sriramramani.wordpress.com/218/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/sriramramani.wordpress.com/218/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=sriramramani.wordpress.com&#038;blog=10234005&#038;post=218&#038;subd=sriramramani&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://sriramramani.wordpress.com/2012/11/20/reflected-image-view/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/98c2d4d449d87a611778e2ff107f3877?s=96&#38;d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">sriramramani</media:title>
		</media:content>

		<media:content url="http://sriramramani.files.wordpress.com/2012/11/reflected-image-view.png?w=225" medium="image">
			<media:title type="html">Reflected Image View</media:title>
		</media:content>
	</item>
		<item>
		<title>Custom States</title>
		<link>http://sriramramani.wordpress.com/2012/11/17/custom-states/</link>
		<comments>http://sriramramani.wordpress.com/2012/11/17/custom-states/#comments</comments>
		<pubDate>Sat, 17 Nov 2012 21:36:33 +0000</pubDate>
		<dc:creator>Sriram Ramani</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[attributes]]></category>
		<category><![CDATA[background]]></category>
		<category><![CDATA[custom attributes]]></category>
		<category><![CDATA[custom state]]></category>
		<category><![CDATA[custom-ui]]></category>
		<category><![CDATA[dark themes]]></category>
		<category><![CDATA[drawable]]></category>
		<category><![CDATA[drawable state]]></category>
		<category><![CDATA[mozilla]]></category>
		<category><![CDATA[namespace]]></category>
		<category><![CDATA[private browsing]]></category>
		<category><![CDATA[private browsing mode]]></category>
		<category><![CDATA[private mode]]></category>
		<category><![CDATA[selector]]></category>
		<category><![CDATA[state]]></category>
		<category><![CDATA[state list drawable]]></category>
		<category><![CDATA[themes]]></category>

		<guid isPermaLink="false">http://sriramramani.wordpress.com/?p=210</guid>
		<description><![CDATA[As a part of the ongoing work on private browsing mode, we had to come up with a way to &#8230;<p><a href="http://sriramramani.wordpress.com/2012/11/17/custom-states/">Continue reading &#187;</a></p><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=sriramramani.wordpress.com&#038;blog=10234005&#038;post=210&#038;subd=sriramramani&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>As a part of the ongoing work on private browsing mode, we had to come up with a way to easily flip the background between light and dark themes. It&#8217;s a known fact that though Android supports themes, they cannot be switched on the fly. If we take a step back and look at Android, views can show different backgrounds for selected, pressed, focused, and enabled states. These can be provided as a <code>StateListDrawable</code> in XML, and Android knows to apply the actual background based on the current state.</p>
<p>But, could we reuse an existing state to convey the private browsing mode? This would not go well with the actual meaning of the predefined Android states. So, could we create a new state for private mode? Oh, yes!</p>
<p>We need a custom attribute that can be used in other XML files that describes the background. This is added in <code>res/values/attrs.xml</code>.</p>
<pre class="brush: xml; title: ; notranslate">
&lt;resources&gt;
    &lt;declare-styleable name=&quot;PrivateBrowsing&quot;&gt;
        &lt;!-- name of the attribute that will be used in XML files --&gt;
        &lt;attr name=&quot;state_private_mode&quot; format=&quot;boolean&quot;/&gt;
    &lt;/declare-styleable&gt;
&lt;/resources&gt;
</pre>
<p>We can now add this attribute to a <code>StateListDrawable</code>, that defines the background of the view. Let&#8217;s have it in some <code>res/drawable/background.xml</code>.</p>
<pre class="brush: xml; title: ; notranslate">
&lt;!-- Note: The &quot;state_private_mode&quot; attribute is defined in our application's scope. Let's call it &quot;sirius&quot;. --&gt;
&lt;selector xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
          xmlns:sirius=&quot;http://schemas.android.com/apk/res/com.sriramramani.just.another.app&quot;&gt;

    &lt;!-- private browsing mode --&gt;
    &lt;item sirius:state_private_mode=&quot;true&quot; android:color=&quot;_some_dark_color_&quot; /&gt;

    &lt;!-- normal mode --&gt;
    &lt;item android:color=&quot;_some_light_color_&quot;/&gt;

&lt;/selector&gt;
</pre>
<p>Now this background be specified in the layout XML just like any other drawable. This doesn&#8217;t end here. We&#8217;ve specified a way to add a custom attribute, and have used it in our background. Though the app will compile fine, Android doesn&#8217;t know when to apply this state. It&#8217;s the responsibility of the custom view to inform Android, that it&#8217;s state has changed and request it to show a new background. Is that hard? Let&#8217;s create a new custom button, PrivateModeButton, that&#8217;s a Button at heart but supports private browsing mode, by providing a method <code>setPrivateMode()</code>.</p>
<pre class="brush: java; title: ; notranslate">
public class PrivateModeButton extends Button {
    // (Combination of) States are usually specified as an array.
    // Our custom attribute will be generated as R.attr.state_private_mode.
    // Note: This is in our app's scope.
    private static final int[] STATE_PRIVATE_MODE = { R.attr.state_private_mode };

    // The view needs a way to know if it's in private mode or not.
    private boolean mIsPrivate = false;

    public PrivateModeButton(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    // Android calls this method to know the current drawable state of the view.
    // It starts with an &quot;extraSpace&quot; of 0 in View.java, and each inherited view adds its new state.
    // We add just one more state, hence, we create a new array of size &quot;extraSpace + 1&quot;.
    @Override
    public int[] onCreateDrawableState(int extraSpace) {
        // Ask the parent to add its default states.
        final int[] drawableState = super.onCreateDrawableState(extraSpace + 1);

        // If we are private, add the state to array of states.
        // If not added, the value will be treated as false.
        // mergeDrawableStates() takes care of resolving the duplicates.
        if (mIsPrivate)
            mergeDrawableStates(drawableState, STATE_PRIVATE_MODE);

        // Return the new drawable state.
        return drawableState;
    }

    // We need a way for the Activity (or some other part of the code)
    // to enable private mode for the view.
    public void setPrivateMode(boolean isPrivate) {
        // If we flip the current state of private mode, record the value
        // and inform Android to refresh the drawable state.
        // This will in turn invalidate() the view.
        if (mIsPrivate != isPrivate) {
            mIsPrivate = isPrivate;
            refreshDrawableState();
        }
   }
}
</pre>
<p>Voila! We can now call <code>myPinkButton.setPrivateMode(true);</code> to show a black button instead. Facebook can have a <code>LikeButton</code> with a custom attribute <code>state_liked</code>, or Twitter can have a <code>FavoriteButton</code> that exposes <code>setFavorite()</code> which can add a small little star at the top right. From Java&#8217;s perspective, it&#8217;s a property of the view. From XML perspective, it&#8217;s just another state!</p>
<p>P.S.: Thanks to Wes (<a href="https://twitter.com/DigDug2K">wesj</a>) for pointing me out to try using custom states. <img src='http://s0.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/sriramramani.wordpress.com/210/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/sriramramani.wordpress.com/210/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=sriramramani.wordpress.com&#038;blog=10234005&#038;post=210&#038;subd=sriramramani&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://sriramramani.wordpress.com/2012/11/17/custom-states/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/98c2d4d449d87a611778e2ff107f3877?s=96&#38;d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">sriramramani</media:title>
		</media:content>
	</item>
		<item>
		<title>Show Your Style</title>
		<link>http://sriramramani.wordpress.com/2012/11/03/show-your-style/</link>
		<comments>http://sriramramani.wordpress.com/2012/11/03/show-your-style/#comments</comments>
		<pubDate>Sun, 04 Nov 2012 03:10:51 +0000</pubDate>
		<dc:creator>Sriram Ramani</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[custom-ui]]></category>
		<category><![CDATA[lightweight themes]]></category>
		<category><![CDATA[mozilla]]></category>
		<category><![CDATA[personalization]]></category>
		<category><![CDATA[personas]]></category>
		<category><![CDATA[skins]]></category>
		<category><![CDATA[themes]]></category>

		<guid isPermaLink="false">http://sriramramani.wordpress.com/?p=200</guid>
		<description><![CDATA[Firefox introduced Lightweight themes a.k.a Personas in version 3.6. This became available in built-in starting 4.0. The good news is &#8230;<p><a href="http://sriramramani.wordpress.com/2012/11/03/show-your-style/">Continue reading &#187;</a></p><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=sriramramani.wordpress.com&#038;blog=10234005&#038;post=200&#038;subd=sriramramani&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>Firefox introduced <strong>Lightweight themes</strong> a.k.a <strong>Personas</strong> in version 3.6. This became available in built-in starting 4.0. The good news is that the Firefox for Android now supports lightweight themes (currently available in <a href="http://nightly.mozilla.org/">nightly</a> builds)! This uses the same themes as desktop Firefox from <a href="https://www.getpersonas.com/en-US/">getpersonas.com</a> and optimizes the images based on the resolution of the device.</p>
<p><a href="http://sriramramani.wordpress.com/2012/11/03/show-your-style/personas/" rel="attachment wp-att-201"><img src="http://sriramramani.files.wordpress.com/2012/11/personas.png?w=791&#038;h=500" alt="Lightweight themes" title="Lightweight themes" width="791" height="500" class="aligncenter size-full wp-image-201" /></a></p>
<p>We wanted to show as much persona as we can, yet retain the affordance provided by the buttons. To achieve it, the gray or black texture of the buttons will have a translucent layer of the image, making the image flow smoothly between interactors. Also, the about:home reflects the background from the image by taking the dominant color from the image. The experience isn&#8217;t complete if the tabs menu and the awesomescreen are left behind. We&#8217;ve got that covered as well!</p>
<p><a href="http://sriramramani.wordpress.com/2012/11/03/show-your-style/personas-phone/" rel="attachment wp-att-202"><img src="http://sriramramani.files.wordpress.com/2012/11/personas-phone.png?w=791&#038;h=373" alt="Lightweight theme on phones" title="Lightweight theme on phones" width="791" height="373" class="size-full wp-image-202" /></a></p>
<p>There are few more bits getting reading to join these bytes &#8212; like the text color in about:home and the url-bar transparency. But still, what are you waiting for? Try out a nightly build and help us improve the Firefox for Android to make it more personal for you!</p>
<p>P.S.: Just in case you wanted to get back to the default theme, hit Menu &gt; Tools &gt; Addons and disable the theme.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/sriramramani.wordpress.com/200/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/sriramramani.wordpress.com/200/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=sriramramani.wordpress.com&#038;blog=10234005&#038;post=200&#038;subd=sriramramani&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://sriramramani.wordpress.com/2012/11/03/show-your-style/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/98c2d4d449d87a611778e2ff107f3877?s=96&#38;d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">sriramramani</media:title>
		</media:content>

		<media:content url="http://sriramramani.files.wordpress.com/2012/11/personas.png" medium="image">
			<media:title type="html">Lightweight themes</media:title>
		</media:content>

		<media:content url="http://sriramramani.files.wordpress.com/2012/11/personas-phone.png" medium="image">
			<media:title type="html">Lightweight theme on phones</media:title>
		</media:content>
	</item>
	</channel>
</rss>