Question

I am trying to create a custom title bar strictly for Android 2.1 that somewhat emulates the ActionBar found in Android 3.0 and up.

So far I've had fairly decent luck, but I cannot find an easy way to make the drop-down lists that can appear below the icon / buttons in the ActionBar.

I would like these drop-down lists to be able to cross the boundary between the title layout and the content layout without being clipped / cut off. I would also like the drop-down lists to be positioned relatively below the icons / buttons in the ActionBar. I've seen advice to use FrameLayouts and RelativeLayouts already but these did not seem to solve my particular problem (unless I'm looking at it wrong). I keep thinking it must be possible since I believe the newer versions of Android have support for exactly this type of behavior.

Here is a screenshot of what I am trying to accomplish with some notes. http://img217.imageshack.us/img217/3279/67343249.png

Please help. Thanks!!!

Was it helpful?

Solution 3

After a few days of research I found the best way to implement this is to use a custom dialog box with a custom theme that contains a listView. When the user clicks on the button the dialog should be displayed directly below the button. This provides a good user experience and also means you don't have to completely change your basic layout structure to accomodate this functionality. (This is basically the same approach that ActionBar Sherlocke uses for their backwards compatibility menus)

Here is a code snippet of what I'm describing (this is written in C# using Mono for Android but it should be easy to translate to Java):

Dialog dlgHome = new Dialog(this, Resource.Style.ActionBarMenu);
dlgHome.SetCanceledOnTouchOutside(true);
dlgHome.SetContentView(Resource.Layout.ActionBarMenu);
ListView lsvHome = (ListView)dlgHome.FindViewById(Resource.Id.lsvHome);
lsvHome.Adapter = new ArrayAdapter<string>(this, Resource.Layout.ActionBarMenuItem, new string[] { "Add Activity", "Edit Log", "Program Details" });

Rect r = new Rect();
btnHome.GetLocalVisibleRect(r);
int x = r.Left + (int)TypedValue.ApplyDimension(ComplexUnitType.Dip, 5, Resources.DisplayMetrics);
int y = r.Bottom;

WindowManagerLayoutParams param = dlgHome.Window.Attributes;
param.Gravity = (int)(GravityFlags.Top | GravityFlags.Left);
param.X = x;
param.Y = y;
dlgHome.Window.Attributes = param;

Also, here is the style xml (goes in style.xml)

<style name="ActionBarMenu" parent="android:Theme.Dialog">
<item name="android:windowBackground">@color/actionbar_menu_bg</item>
<item name="android:windowNoTitle">true</item>
<item name="android:backgroundDimEnabled">false</item>
</style>

OTHER TIPS

I think best way to do that is to create a linear layout and add your drop-down list item into that linear layout. Then add linear layout on button click and display it just below to the button by using relative layout layoutparams.

You need to hold your content with a FrameLayout. A FrameLayout can hold more than one child, and it will allow them to overlap on each other.

A possible layout xml could look like:

<FrameLayout>
    <LinearLayout android:margin_top="30dip">...</LinearLayout>
    <CustomActionBar />
</FrameLayout>

The 30dip is just the height of your ActionBar, you might want to define it in values. And the LienarLayout you can replace with anything which is just for holding the other content in your application.

PS. I am not sure if FrameLayout renders first child first or last. In case you found the linearlayout stuff overlaps the customactionbar, swap their position.

=== Edit ===

To make the code much cleaner, one can do in this way:

<CustomActionBar>
    <LinearLayout/>
</CustomActionBar>

Which replaced the custom action bar to be the "root" element of any xml layout that utilized the action bar. When doing the custom action bar, you need to extend it from FrameLayout, and assign the child's margin accordingly. Which the idea is much the same as the one I presented above.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top