16

I've got a split ActionBar, and I'm trying to add functionality almost identical to google play's 'Now playing'..

I can get menu items to appear at the bottom of the screen, using the onCreateOptionsMenu, but I can't seem to get a custom view to appear at the bottom of the screen when using actionBar.setCustomView. The custom view just sits underneath the top ActionBar.

Does anyone know how to force the customview to the bottom, or to add custom views to the onCreateOptionsMenu?

Here are the snippets of my code:

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    ActionBar actionBar = getActionBar();
    actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
    actionBar.setDisplayShowTitleEnabled(true);
    actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);

    //Custom view to add
    actionBar.setCustomView(R.layout.albumitem);
            //This view shows up just under the top actionbar at the moment,
              despite menu items being at the bottom

The menu options code: (These are showing down the bottom where I'd like my custom view to be)

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    new MenuInflater(this).inflate(R.menu.option_menu, menu);

    return (super.onCreateOptionsMenu(menu));
}

I believe that the now playing menu at the bottom of the google play music app is a custom view inside a split action bar:

Google Play Music

Tim Malseed
  • 6,003
  • 6
  • 48
  • 66
  • you can refer to my answer over here [fixed bottomBar and TopBar][1] [1]: http://stackoverflow.com/a/14597289/1627904 – Kosh Jan 30 '13 at 05:30

2 Answers2

17

So I managed to find a dirty solution to this.. Well, dirty in my amateurish opinion..

In the oncreateOptionsMenu, I've inflated a menu called option_menu like so:

@Override
public boolean onCreateOptionsMenu(Menu menu) {
        new MenuInflater(this).inflate(R.menu.option_menu, menu);

And in the xml for that option_menu item, I've implemented an actionViewClass, and in this case I've used relative layout (I'm guessing I could've just used View..?):

<item
    android:id="@+id/layout_item"
    android:actionViewClass="android.widget.RelativeLayout"
    android:showAsAction="always|withText"
    android:title="Text 1"/>

</menu>

So then I inflated an xml layout, and added it to the layout_item defined in my menu:

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        new MenuInflater(this).inflate(R.menu.option_menu, menu);
        relativeLayout = (RelativeLayout) menu.findItem(R.id.layout_item)
                .getActionView();

        View inflatedView = getLayoutInflater().inflate(R.layout.now_playing,
                null);

        relativeLayout.addView(inflatedView);

        return (super.onCreateOptionsMenu(menu));
    }

Please feel free to edit/enhance this answer as you see fit.

Tim Malseed
  • 6,003
  • 6
  • 48
  • 66
  • It seems to work but I am not able to display icons on the top action bar and my custom view on the bottom bar. Did you also achieve this? – Fernando Gallego Jan 11 '13 at 13:12
  • 2
    No. I've recently realised using a fragment down the bottom is probably better. – Tim Malseed Jan 11 '13 at 13:40
  • 1
    A little late on this one, but the music app doesn't use an Action Bar at all. Both the top and bottom are custom Views. – adneal Mar 19 '13 at 15:30
  • aneal, I think the tabs are part of the actionbar, the bottom view is the main activity layout, and the inner content is a fragment. I didn't realise this until after I posted this question, but given that there is a way to inflate custom views to the actionbar, I left the question and answer as they are. It's a solution, but not the best one, particularly because any calls which refresh the options menu cause the inflated view to redraw, which can have a flickering effect. – Tim Malseed Mar 19 '13 at 22:15
  • timusu did you got any solution i have to implement same please help me if you have any solution – rajahsekar Feb 27 '14 at 18:02
  • rajahsekar just use a custom view in your activity layout for the bottom part, and sit your fragment container on top of it. – Tim Malseed Feb 28 '14 at 05:36
1

I've done a solution based on yours, including custom layout on top + custom layout on bottom + title/subtitle + home icon. Here is the code:

public class SplitABActivity extends Activity{
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    ActionBar ab = getActionBar();
    ab.setTitle("Action Bar Title");
    ab.setSubtitle("Action Bar Subtitle");
    ab.setDisplayShowHomeEnabled(true);

    LayoutInflater inflater = (LayoutInflater) getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
    RelativeLayout layout = (RelativeLayout) inflater.inflate(R.layout.ab_custom_layout, null);
    ab.setCustomView(layout);
    ab.setSplitBackgroundDrawable(new ColorDrawable(Color.BLUE));
    ab.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM  | ActionBar.DISPLAY_SHOW_HOME | ActionBar.DISPLAY_SHOW_TITLE);
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.menu_including_layout, menu);
    RelativeLayout layout = (RelativeLayout) menu.findItem(R.id.layout_item).getActionView();
    View v = getLayoutInflater().inflate(R.layout.ab_bottom_layout, null);
    layout.addView(v); 

    return super.onCreateOptionsMenu(menu);
}
}

ab_custom_layout.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:gravity="right"
    >
   <TextView android:id="@+id/element1" 
       android:layout_width="wrap_content" android:layout_height="wrap_content"
       android:textColor="#fff"
       android:background="#ff0000"
       android:text="Element 1"/>

   <TextView
       android:id="@+id/element2" 
        android:layout_width="wrap_content" android:layout_height="wrap_content"
        android:textColor="#000"
        android:background="#f0f0f0"
        android:layout_toRightOf="@+id/element1"
       android:text="Element 2"/>

</RelativeLayout>

menu_including_layout.xml

<menu xmlns:android="http://schemas.android.com/apk/res/android" >

<item android:id="@+id/action1"
    android:title="Action 1"
      android:icon="@android:drawable/ic_dialog_alert"
      android:showAsAction="ifRoom" />

<item android:id="@+id/action2"
    android:title="Action 2"
      android:icon="@android:drawable/ic_dialog_info"
      android:showAsAction="ifRoom" />

<item
android:id="@+id/layout_item"
android:actionViewClass="android.widget.RelativeLayout"
android:showAsAction="always|withText"
android:title="Layout Item"/>
 </menu>

ab_bottom_layout.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
 >

<TextView 
    android:id="@+id/bottom_layout_txt_status"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Click this button"/>

<ImageButton android:id="@+id/bottom_layout_btn_chat"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:src="@android:drawable/ic_menu_camera"
    android:layout_toRightOf="@+id/bottom_layout_txt_status"
    android:contentDescription="@string/app_name"/>
</RelativeLayout>

Code works perfect for me. I can see the split ActionBar when my tablet is on portrait. On landscape it is wide enough to store all the items on the top.

Hope it helps

voghDev
  • 5,641
  • 2
  • 37
  • 41