23

Does anybody know how to easily implement an action bar with two stretched buttons?

Here is an example of the Google calendar app:

enter image description here

Thank you!

Louis
  • 2,140
  • 4
  • 19
  • 18
  • This isn't the actionbar... it looks more like a dropdown widget of some sort. – Alex Lockwood Jun 29 '12 at 16:12
  • possible duplicate of [Cancel Done buttons in Calendar App - Is it part of Action Bar?](http://stackoverflow.com/questions/15103895/cancel-done-buttons-in-calendar-app-is-it-part-of-action-bar) – Simon Jackson May 20 '15 at 10:22

5 Answers5

39

If you rather have this in the ActionBar for whatever reason, one way to achieve this is by using a custom view on the Action bar. Within you Custom View's layout then worry about setting up the buttons width.

Telling the activity to use a custom view for the action bar:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);   
    final ActionBar ab = getActionBar();
    ab.setDisplayShowHomeEnabled(false);
    ab.setDisplayShowTitleEnabled(false);     
    final LayoutInflater inflater = (LayoutInflater)getSystemService("layout_inflater");
    View view = inflater.inflate(R.layout.action_bar_edit_mode,null); 
    ab.setCustomView(view);
    ab.setDisplayShowCustomEnabled(true);
}

layout/action_bar_edit_mode.xml can then look something like:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:gravity="fill_horizontal"
    android:orientation="horizontal" >
    <LinearLayout 
        android:layout_alignParentLeft="true"
        android:layout_width="fill_parent"
        android:layout_height="match_parent"
        android:orientation="horizontal">

        <Button
        android:id="@+id/action_bar_button_cancel"
        android:layout_width="fill_parent"
        android:layout_height="match_parent"           
        android:layout_weight="1"
        android:text="Cancel" />

        <Button
        android:id="@+id/action_bar_button_ok"
        android:layout_width="fill_parent"
        android:layout_height="match_parent"           
        android:layout_weight="1"
        android:text="Ok" />
    </LinearLayout>    
</RelativeLayout>

Hope it helps someone!

Note: I realize the ugly nesting layouts here and normally I wouldn't recommend this but for some reason the actionbar's own layout refuses to let the LinearLayout take up the entire width on its own. Normally you should avoid nesting layouts unnecessarily like this! Perhaps if someone sees this they can point us to a better solution?

What it looks like: result

EDIT: There is an excellent post by Roman Nurik where he explains a way to do this very nicely.

EDIT 2: If anyone is curious, the correct way to lay out the buttons so that they expand the width of the actionbar without the need to nest your layouts like I did above, is to set the custom view with the proper layout parameters that allows its component to match the parent group.

Essentially:

actionBar.setCustomView(view,new ActionBar.LayoutParams(
        ViewGroup.LayoutParams.MATCH_PARENT,
        ViewGroup.LayoutParams.MATCH_PARENT));
Carlos N
  • 1,616
  • 14
  • 15
  • Using a custom view in this fashion (with a stretched relative layout) has the nasty side effect of hiding the overflow menu that normally shows for some devices. – Nariman Feb 28 '13 at 23:46
  • Not really a nasty side effect, that's actually the desired effect in this case. If you want the overflow to still show you might want to follow what the contacts app does (or the "DoneButtonActivity on Roma Nurik's project) and align the buttons to the left as to allow the overflow to still show. Optionally you can set your activity with split action bar so the overflow shows at the bottom. – Carlos N Mar 04 '13 at 15:49
5

I know 2 ways to do this, but one doesn't stay on top.

Here is the 1st:

You need to override the method onCreateOptionsMenu, but this is add on the ActionBar, you need API 11 to do this and when you rotate the screen this buttons appear on ActionBar, this depends of the screen size.

 @Override
 public void onCreateOptionsMenu(Menu menu, MenuInflater inflater)
 {
     MenuItem add = menu.add(Menu.NONE, ADD_TIME, 0, R.string.add_time);
     add.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);

     MenuItem qkAdd = menu.add(Menu.NONE, QUICK_ADD_TIME, 1, R.string.quick_add_time);
     qkAdd.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
 }

and this is the result:

enter image description here

if you're using a Fragment you need to set setHasOptionsMenu to true, otherwise the menu wont show.

Here is the 2nd:

cancel_done.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/color_bar"
android:orientation="horizontal" >

<LinearLayout
    android:layout_width="0dp"
    android:layout_height="match_parent"
    android:layout_weight="1"
    android:dividerPadding="12dp"
    android:orientation="vertical"
    android:showDividers="end" >

    <Button
        android:id="@+id/button1"
        style="@drawable/btn_cab_done_holo_light"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_gravity="center"
        android:background="@drawable/btn_cab_done_holo_light"
        android:text="CANCEL"
        android:textSize="14sp" />

</LinearLayout>

<LinearLayout
    android:layout_width="0dp"
    android:layout_height="match_parent"
    android:layout_weight="1"
    android:dividerPadding="12dp"
    android:orientation="vertical"
    android:showDividers="beginning" >

    <Button
        android:id="@+id/button2"
        style="@drawable/btn_cab_done_holo_light"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_gravity="center"
        android:background="@drawable/btn_cab_done_holo_light"
        android:text="DONE"
        android:textSize="14sp" />

</LinearLayout>
</LinearLayout>

the resource style btn_cab_done_holo_light.xml you can find on ..\sdk\platforms\android-%%\data\res\drawable and then on your layout you just add:

        <include
            android:layout_width="match_parent"
            android:layout_height="48dp"
            android:layout_gravity="fill"
            layout="@layout/cancel_done" />

and this is the result:

enter image description here

I don't now if is the best way, but it's working.

3

Make a horizontal LinearLayout with two buttons. Then set each of their widths to match_parent and android:layout_weight="0.5" (Each button will then take up 50% of the space).

EDIT:

To apply as the ActionBar background:

(ActionBarSherlock) getSupportActionBar().setCustomView(R.layout.my_view);
(ActionBar) getActionBar().setCustomView(R.layout.my_view);
Mahdi Alkhatib
  • 1,954
  • 1
  • 29
  • 43
Cruceo
  • 6,763
  • 2
  • 31
  • 52
0

You can use the actionMode of the ActionBar to implement the Done and Cancel actions.

See http://developer.android.com/guide/topics/ui/menus.html#CAB

userM1433372
  • 5,345
  • 35
  • 38
0

Is called done bar in android. have a look at this it will be helpfull https://github.com/googlesamples/android-DoneBar

Imran Khan
  • 158
  • 1
  • 3
  • 13