Martin Stone Martin Stone - 3 months ago 11
Android Question

Why doesn't my custom action bar view "match parent" when using appcompat and Toolbar?

I'm setting a custom view in an action bar. It fills the width of the action bar when using the SDK action bar, but not when using the appcompat version. Why doesn't my linear layout fill the width when using appcompat and Toolbar? And what can I do about it?

Here's what it looks like pre-appcompat:

enter image description here

And here's what it looks like with appcompat. (The red colour shows the extent of my custom view.):

enter image description here

Edit: Here's how it looks using @Seidan's explicit layout params tip. (Showing black text where it should be white):

enter image description here

Here's my custom layout:

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

<FrameLayout
android:id="@+id/actionbar_discard"
style="?attr/actionButtonStyle"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
>

<TextView
style="?android:actionBarTabTextStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:drawableLeft="@drawable/ic_close_white_24dp"
android:drawablePadding="8dp"
android:gravity="center_vertical"
android:paddingRight="20dp"
android:text="@string/actionbar_cancel" />
</FrameLayout>

<FrameLayout
android:id="@+id/actionbar_done"
style="?attr/actionButtonStyle"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1" >

<TextView
style="?android:actionBarTabTextStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:drawableLeft="@drawable/ic_check_white_24dp"
android:drawablePadding="8dp"
android:gravity="center_vertical"
android:paddingRight="20dp"
android:text="@string/actionbar_done" />
</FrameLayout>
</LinearLayout>


And here's how I'm setting up the action bar:

ActionBar ab = getSupportActionBar();
ab.setDisplayHomeAsUpEnabled(false);
ab.setDisplayOptions(
ActionBar.DISPLAY_SHOW_CUSTOM,
ActionBar.DISPLAY_SHOW_CUSTOM | ActionBar.DISPLAY_SHOW_HOME | ActionBar.DISPLAY_SHOW_TITLE);
ab.setCustomView(R.layout.actionbar_discard_done);


Both appcompat-v7:22.0.0 and the new appcompat-v7:22.1.0 exhibit this problem.

Answer

Thanks @Seidan for your comment. It led me to a solution. The styling problem was due to the inflater using the wrong theme when I gave it my Activity's this.

To summarize, instead of this line from my code in the question...

ab.setCustomView(R.layout.actionbar_discard_done);

...I have...

View v = LayoutInflater
        .from(ab.getThemedContext())
        .inflate(R.layout.actionbar_discard_done, null);
ActionBar.LayoutParams params = new ActionBar.LayoutParams(
        ActionBar.LayoutParams.MATCH_PARENT, 
        ActionBar.LayoutParams.MATCH_PARENT);
ab.setCustomView(v, params);

Which gives me...

correct action bar

It's a mystery why we have to specify match_parent in the layout and the code, but I can live with it.