Android ActionBar - Push custom view to bottom of

2019-03-08 05:01发布

问题:

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:

回答1:

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.



回答2:

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