Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to set expanded ActionView's width in SupportActionBar to fill the available space

I try to set up a MenuItem with an actionView as described here.

In my case the ActionView Widget is a SeekBar.

The problem is, that when the ActionView is shown on icon click, its width is way smaller than expected as you can see in the following screenshots:

enter image description here

enter image description here

The docs say:

If the widget is on the app bar, the app should display the widget as an icon. If the widget is in the overflow menu, the app should display the widget as a menu item. When the user interacts with the action view, it expands to fill the app bar.

In my case, nothing gets "expanded". Instead of taking up the whole width of the ActionBar, its tiny.

To fix it I tried using another View like an EditText, but got similar Results. (The EditText is small on start, but expands on writing in it). It seems to work with a android.support.v7.widget.SearchView as used in the docs.

I also tried it with Theme.AppCompat.Light.DarkActionBar or Theme.AppCompat.Light.NoActionBar providing a Toolbar in the layout without any noticeable difference.

Here is the code I used:

MainActivity

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        /* set this on other layout with toolbar in it
        Toolbar toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        */
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        super.onCreateOptionsMenu(menu);
        getMenuInflater().inflate(R.menu.camera_menu, menu);
        return true;
    }
}

app_menu.xml

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <item
        android:id="@+id/action_item"
        android:title="Action"
        android:icon="@drawable/ic_icon_in_black_24dp"
        app:showAsAction="ifRoom|collapseActionView"
        app:actionViewClass="android.widget.SeekBar"
        />
</menu>

I also tried app:actionViewLayout=@layout/seekbar_layout instead of actionViewClass where seekbarLayout was something like this

<?xml version="1.0" encoding="utf-8"?>

<SeekBar
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/action_seekbar"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
/>

Where I also tried different versions of ViewGroups around it like Linear, Relative or FrameLayouts, or tried to set a fixed width of my SeekBar without any success.

What Am I missing or doing wrong here?

like image 206
Rafael T Avatar asked Feb 12 '18 10:02

Rafael T


2 Answers

enter image description here

Adding Seekbar as the menu item, will take up the size of default menu item. If you need Seekbar to extend across the appbar, then you can create your own Toolbar and add SeekBar like this.

<youtLayoutRoot>
<android.support.v7.widget.Toolbar
    android:id="@+id/toolbar"
    android:layout_width="match_parent"
    android:layout_height="?attr/actionBarSize"
    app:popupTheme="@style/AppTheme.PopupOverlay"
    app:titleTextColor="@color/white" >
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1">
        <SeekBar
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:max="100"
            android:progress="10"/>
    </LinearLayout>
</android.support.v7.widget.Toolbar>
<!-- your content layout here -->
</youtLayoutRoot>

Make the theme of your activity as Theme.AppCompat.Light.NoActionBar and run the application. You should be able to see the seekbar spanning across the toolbar.

In your activity just inflate the menu and it will take ut its size. It works for me and hope that seekbar with menu item will also work for you.

enter image description here

toolbar.inflateMenu(R.menu.menu_delete)
    toolbar.setNavigationIcon(R.drawable.vector_back)
    toolbar.setNavigationOnClickListener {
        onBackPressed()
    }
    toolbar.setOnMenuItemClickListener { menuItem ->
        when (menuItem.itemId) {
            R.id.delete -> {
                deleteCall()
                true
            }
            else -> {
                false
            }
        }
    }
like image 144
niketshah09 Avatar answered Oct 20 '22 00:10

niketshah09


The "magic" takes place in Toolbar.expandItemActionView. This method overrides the layout parameters of the expanded ActionView and sets the width to wrap_content. Now to one possible solution:

Toolbar.expandItemActionView checks if the ActionView implements CollapsibleActionView interface and calls CollapsibleActionView.onActionViewExpanded method if this is the case. This is your chance to fix the layout paramters and set the width to match_parent. Derive a custom class from the SeekBar and let it implement CollapsibleActionView:

public class CollapsibleSeekBar extends AppCompatSeekBar implements CollapsibleActionView {
    public CollapsibleSeekBar(Context context) {
        super(context);
    }

    public CollapsibleSeekBar(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public CollapsibleSeekBar(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    public void onActionViewExpanded() {
        ViewGroup.LayoutParams params = getLayoutParams();
        params.width = ViewGroup.LayoutParams.MATCH_PARENT;
        setLayoutParams(params);
        requestLayout();
    }

    @Override
    public void onActionViewCollapsed() {

    }
}

Use it in your menu item via app:actionViewClass.

Also make sure to use the appropriate CollapsibleActionView.

If you are using android.support.v4.widget.Toolbar you also need android.support.v7.view.CollapsibleActionView.

If you have an android.widget.Toolbar use android.view.CollapsibleActionView

like image 37
artkoenig Avatar answered Oct 20 '22 00:10

artkoenig