Titanium JIRA Archive
Titanium SDK/CLI (TIMOB)

[TIMOB-3290] Android: TabGroup never translucent even if translucent theme applied to TiTabActivity

GitHub Issuen/a
TypeBug
PriorityMedium
StatusClosed
ResolutionFixed
Resolution Date2011-04-17T02:01:23.000+0000
Affected Version/sn/a
Fix Version/sRelease 1.7.0, Sprint 2011-10
ComponentsAndroid
Labelsandroid, defect, release-1.6.1, release-1.7.0, reported-1.6.0, rplist
ReporterBill Dawson
AssigneeBill Dawson
Created2011-04-15T03:41:27.000+0000
Updated2011-04-17T02:01:23.000+0000

Description

For an activity window to be translucent, Android appears to require that you set the activity's theme to a translucent theme in the AndroidManifest.xml -- http://groups.google.com/group/android-developers/browse_thread/thread/599807e7818f926f/db8fd5c21ae8f0ac?show_docid=db8fd5c21ae8f0ac"> it does not appear to be possible to successfully set a translucent theme -- or a transparent window background -- at runtime.

You could, for example, use a custom AndroidManifest.xml in your Titanium application and set the TiActivity as such:

<activity android:configChanges="keyboardHidden|orientation" android:name="ti.modules.titanium.ui.TiActivity" android:theme="@android:style/Theme.Translucent"/>

TiActivity is the activity we use for all "heavyweight" windows in Titanium. The above change to the TiActivity's manifest entry -- adding android:theme="@android:style/Theme.Translucent" successfully makes your windows translucent by default. (In code, you can then give a backgroundColor to a window if you don't want it to be translucent.)

When you use a TabGroup, however, you need to consider the theme for the TiTabActivity, which is the activity we use for TabGroups. So this should work:

<activity android:configChanges="keyboardHidden|orientation" android:name="ti.modules.titanium.ui.TiTabActivity" android:theme="@android:style/Theme.Translucent"/>

But, in fact, it's not working. The reason is because we explicitly -- in our Java code -- set the Android TabHost's background drawable to a ColorDrawable with color value #ff1a1a1a.

SO ... to re-create the failcase, follow these rather elaborate steps...

  • Create a new Titanium application.

  • Make this its app.js:

Ti.UI.backgroundImage = 'KS_nav_ui.png'; // Set the root background to show an (ugly, stretched) image
var tabGroup = Titanium.UI.createTabGroup();
var win1 = Titanium.UI.createWindow({  
    title:'Tab 1',
    backgroundColor:'transparent'
});
var tab1 = Titanium.UI.createTab({  
    icon:'KS_nav_views.png',
    title:'Tab 1',
    window:win1
});
var win2 = Titanium.UI.createWindow({  
    title:'Tab 2',
    backgroundColor:'transparent'
});
var tab2 = Titanium.UI.createTab({  
    icon:'KS_nav_ui.png',
    title:'Tab 2',
    window:win2
});
tabGroup.addTab(tab1);  
tabGroup.addTab(tab2);  
tabGroup.open();
  • Run the app once so that it generates our default AndroidManifest.xml.

  • Create the folder platform/android under the project's root folder.

  • Copy build/android/AndroidManifest.xml into platform/android. This tells Titanium you want to use a custom AndroidManifest.xml.

  • Edit platform/android/AndroidManifest.xml

  • Search for TiTabActivity. When you find it, add this attribute to its element: android:theme="@android:style/Theme.Translucent" so that the complete element looks like:

<activity android:configChanges="keyboardHidden|orientation" android:name="ti.modules.titanium.ui.TiTabActivity" android:theme="@android:style/Theme.Translucent"/>
  • Save these changes you've made to platform/android/AndroidManifest.xml.

  • Re-launch the application. You will see that although you have specified a translucent theme for our tab Activity, you still won't be able to see through to the default background, which is the image KS_nav_ui.png.

Comments

  1. Bill Dawson 2011-04-15

    (from [843c806d1c07731e5bd6643b37ce5015e0134695]) If TabGroup passed a backgroundColor, use it instead of the default #ff1a1a1a we've been setting. This allows people to set 'transparent', for example, and then use Theme.Translucent on TiTabActivity to let their tabs be transparent. Also remove duplicate entries from generated AndroidManifest.xml in case user puts one of our default activities into of tiapp.xml (such as if they wanted to apply a custom theme to it.) [#3290] https://github.com/appcelerator/titanium_mobile/commit/843c806d1c07731e5bd6643b37ce5015e0134695"> https://github.com/appcelerator/titanium_mobile/commit/843c806d1c07...

  2. Bill Dawson 2011-04-15

    (from [0a693f4dae443f4381269afebbcdffd24e5e8100]) If TabGroup passed a backgroundColor, use it instead of the default #ff1a1a1a we've been setting. This allows people to set 'transparent', for example, and then use Theme.Translucent on TiTabActivity to let their tabs be transparent. Also remove duplicate entries from generated AndroidManifest.xml in case user puts one of our default activities into of tiapp.xml (such as if they wanted to apply a custom theme to it.) [#3290] https://github.com/appcelerator/titanium_mobile/commit/0a693f4dae443f4381269afebbcdffd24e5e8100"> https://github.com/appcelerator/titanium_mobile/commit/0a693f4dae44...

  3. Bill Dawson 2011-04-15

    So with this fix in place, here are the instructions for getting (and testing) transparent tab windows:

    • You can get rid of the custom AndroidManifest.xml from my instructions above (if you're using the same project to test the fix). I made a change that makes it easier to just update a single Activity rather than pull over the whole AndroidManifest.xml. The next step takes advantage of that change.

    • Open your tiapp.xml and put an entry for the TiTabActivity in the <android><manifest><application> section. On that entry, you're going to assign the Theme.Translucent theme to that activity. Such as this:

       <android xmlns:android="http://schemas.android.com/apk/res/android">
           <manifest>
               <application>
                   <activity android:name="ti.modules.titanium.ui.TiTabActivity"
                       android:configChanges="keyboardHidden|orientation"
                       android:theme="@android:style/Theme.Translucent"
                   />
               </application>
           </manifest>
       </android>
       
    • In your app.js, create a TabGroup and set its backgroundColor:'transparent' -- that's not required in iOS, but it is for Android, because otherwise the default background color that we set for tab groups will be applied. Also set the constituent windows' backgroundColor: 'transparent'. Here is a good example app.js that does both:
       Ti.UI.backgroundImage = 'KS_nav_ui.png';
       var tabGroup = Titanium.UI.createTabGroup({backgroundColor: 'transparent'});
       var win1 = Titanium.UI.createWindow({  
           title:'Tab 1',
           backgroundColor:'transparent',
           fullscreen:false
       });
       var tab1 = Titanium.UI.createTab({  
           icon:'KS_nav_views.png',
           title:'Tab 1',
           window:win1
       });
       var win2 = Titanium.UI.createWindow({  
           title:'Tab 2',
           backgroundColor:'transparent',
           fullscreen:false
       });
       var tab2 = Titanium.UI.createTab({  
           icon:'KS_nav_ui.png',
           title:'Tab 2',
           window:win2
       });
       tabGroup.addTab(tab1);  
       tabGroup.addTab(tab2);  
       tabGroup.open();
       
    • Note that that sample app.js also sets an ugly, stretched bitmap on the root background, so that you can see if transparency is actually working.

    • Run the app -- you should be able to see the ugly bitmap, which means the tabgroup and the tab windows are transparent.

  4. Natalie Huynh 2011-04-15

    Tested with Titanium SDK version: 1.7.0 (03/08/11 13:41 1dbf930) on
    Samsung Galaxy 2.2
    Nexus One 2.2.2
    Emulator 2.1

  5. Dennis Schneider 2011-04-15

    Hi Bill,

    I tried the code above and it works, but on my HTC Desire HD it's always in fullscreen mode. The bar at the top is missing. Sometimes the empty bar pops up and disappears again a few seconds later.

    Kind regards,
    Dennis

  6. Bill Dawson 2011-04-15

    Yup, Android has an annoyance whereby if you open a translucent window from a fullscreen window, then the translucent window will also be fullscreen, even if you don't want it to be. :\ It's really annoying. There appears to be no way around it.

    So what's happening is that since the "launch" theme is fullscreen (the fullscreen splash screen), the translucent "window" (the TabGroup) which gets launched from it is also fullscreen. It doesn't happen for non-translucent windows. Very weird.

    There are a couple of things you can try. The first one works for sure, the second one I haven't tried.

    1. Change the launch theme to not be fullscreen. If you look in the generated AndroidManifest.xml, you'll see that the first activity definition -- the one that carries your application's name -- has android:theme="@style/Theme.Titanium. Now if you look at build/android/res/values/theme.xml, you'll see that Theme.Titanium inherits from the Android built-in theme named Theme.NoTitleBar.Fullscreen. You can make a custom version of this theme.xml:

      • In your project root, create platform/android/res/values, then copy this theme.xml file into that folder and edit it.
      • Change the Theme.NoTitleBar.Fullscreen to Theme.NoTitleBar and save the file.
      • Now "touch" your tiapp.xml file (i.e, do something to update its file date/time). I'm not sure this step is necessary, but it's a good idea in this case.
      • Re-launch your app. You'll see that your splash screen is no longer fullscreen (which might be annoying), but also your translucent TabGroup will not be fullscreen anymore.
    2. Keep the launch screen as a fullscreen, but put a non-fullscreen-window between the launch window (splash) and the tabgroup. I have not tried this. For example, in app.js you'd createWindow({fullscreen:false, url:'launch.js'}) (etc.), then launch.js you'd have the code to open the TabGroup immediately. (For createTabGroup, you would want to also set exitOnClose:true so that the app closes when you back out of the TabGroup -- otherwise you would end up setting at that launch.js window which is useless.)

    Hope that helps,

    Bill

  7. Dennis Schneider 2011-04-15

    Hi Bill,

    the first approach works great so far! But as soon as I put the device to the landscape mode the splash screen covers the root background. I was able to use a workaround by setting the background image again on orientationchange, but sometimes this doesn't work as desired.

    Would it be possible that I add you to my contacts in Skype? I have some more bugs to share ;) Maybe you can send your Skype name by email to dennis@wunderkinder.com. That would be really great!!

    Thank you very much

    Kind regards,
    Dennis

  8. Bill Dawson 2011-04-15

    (from [0cfa014353f9af858ff975a9ae1eb6823ced0966]) If TabGroup passed a backgroundColor, use it instead of the default #ff1a1a1a we've been setting. This allows people to set 'transparent', for example, and then use Theme.Translucent on TiTabActivity to let their tabs be transparent. Also remove duplicate entries from generated AndroidManifest.xml in case user puts one of our default activities into of tiapp.xml (such as if they wanted to apply a custom theme to it.) [#3290] https://github.com/appcelerator/titanium_mobile/commit/0cfa014353f9af858ff975a9ae1eb6823ced0966"> https://github.com/appcelerator/titanium_mobile/commit/0cfa014353f9...

JSON Source