How to create an action item with sub-items programmatically? - android

Background
Just want to see how to make action items in code without XML
The problem
I've come to some case that I fail to see how I can create in code.
The case below is showing a normal action-item that has an icon, and when pressed, it shows a sub-menu of items to choose from. I want to create the same, but programmatically:
<menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto">
<item android:icon="#android:drawable/ic_menu_info_details" android:title="More info" app:showAsAction="always">
<menu>
<group android:checkableBehavior="none" android:menuCategory="container">
<item android:id="#+id/..." android:title="item 1"/>
<item android:id="#+id/..." android:title="item 2"/>
<item android:id="#+id/..." android:title="item 3"/>
</group>
</menu>
</item>
</menu>
When using this, the result is:
And after clicking:
What I've tried
I tried 2 solutions:
Create a subMenu (using addSubMenu), and then setting an action-item properties to it.
Create a normal Action item (using add) and then adding sub-items to it.
The result for both of them failed in comparison to what
The question
How can I make the exact same thing programmatically, without using XML resource for it.

Related

Android Drawer Submenu with Edit Action and Title [Google Keep Example]

I want to have a group in my navigation drawer which has a title and next to the title there should be an edit button like in the new Google Keep App (see example below). Currently I can't find a sleek and working solution.
My menu layout at the moment:
<?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:title="Accounts"
app:actionLayout="#layout/edit_action"
app:showAsAction="always"
android:enabled="false">
<menu>
<group android:checkableBehavior="single">
<item android:title="Item 1" android:icon="#drawable/ic_outline_calendar_today"/>
<item android:title="Item 2" android:icon="#drawable/ic_outline_calendar_today"/>
</group>
<item android:title="Add new Item" android:icon="#drawable/ic_outline_add"/>
</menu>
</item>
<group>
<item android:title="Settings" android:icon="#drawable/ic_outline_settings"/>
<item android:title="Trash" android:icon="#drawable/ic_outline_delete"/>
<item android:title="Help \u0026 Feedback" android:icon="#drawable/ic_outline_feedback"/>
</group>
</menu>
Currently only the title is displayed in the submenu but the edit button is missing. But if you just create an item without a menu child, the edit button will be displayed but the item is now an item and not a title as before.
I would like to have the same result as in the picture. The padding as well as the text size and color should be the default values from Android.
My edit_action.xml file looks like this:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
style="?android:attr/actionButtonStyle"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:clickable="true">
<TextView
android:text="Edit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#color/colorPrimary"
android:id="#+id/edit"/>
</RelativeLayout>
My menu looks like this at the moment:

How to keep options menu open in titlebar?

I need to create menu in titlebar, where user can chose many variants at one time. It will be a filter options of content in activity.
So, it should looks like this:
I can use standard menu items like this:
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="#+id/one"
android:checkable="true"
android:checked="true"
android:title="#string/one"
app:showAsAction="never" />
<item
android:id="#+id/two"
android:checkable="true"
android:checked="true"
android:title="#string/two"
app:showAsAction="never" />
</menu>
And it will work perfectly, but after click on any item, menu will close.
I find old question about it: Android - keep options menu open .
May be already there are some variants to resolve it, without create menu by my own?
Or I can use spinner:
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="#+id/one"
android:icon="#drawable/ic_arrow_dropdown"
app:actionViewClass="android.widget.Spinner"
app:showAsAction="always"
android:title="some title" />
</menu>
But Spinner doesn't support multiselect.
What is the right way to do it?

Adding Horizontal Divider to Menu Items (or Groups) in pure XML

I have created the following top-level main Menu in the Android app:
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
tools:context=".MainActivity">
<group android:id="#+id/group_speed" android:checkableBehavior="single" >
<item android:id="#+id/slow" android:title="#string/speed_slow"/>
<item android:id="#+id/normal" android:title="#string/speed_normal"/>
<item android:id="#+id/fast" android:title="#string/speed_fast" />
</group>
<group android:id="#+id/group_info" android:checkableBehavior="none">
<item android:id="#+id/help" android:title="Help"/>
<item android:id="#+id/about" android:title="About"/>
</group>
</menu>
I would like to know if there is a simple way to add a Horizontal divider between two menu groups (and/or two menu items within the group) in a declarative way using just XML statement (optionally, adding shape resources, attributes, etc., but not using java code for this decorative task).

Get an item of an item in espresso

I am a beginner in Espresso. I have this menu.xml file:
<?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/configuration"
android:icon="#drawable/ic_settings"
android:title="Configuration"
app:showAsAction="ifRoom">
<menu>
<item
android:id="#+id/add_sound"
android:title="Add a sound"
app:showAsAction="ifRoom" />
<item
android:id="#+id/takeof_sound"
android:enabled="false"
android:title="Take of the sound"
app:showAsAction="ifRoom" />
<item
android:id="#+id/add_image"
android:title="Add an image"
app:showAsAction="ifRoom" />
<item
android:id="#+id/takeof_image"
android:enabled="false"
android:title="Take of the image"
app:showAsAction="ifRoom" />
</menu>
</item>
<item
android:id="#+id/add"
android:icon="#drawable/ic_add"
android:title="Add"
app:showAsAction="ifRoom" />
</menu>
I would like to perform a click on the item with id configuration and then a click on the sub-item with id add_sound. So, I have typed this code:
public void menuConfigurationTest()
{
onView(withId(R.id.configuration)).perform(click());
onView(withId(R.id.add_sound)).perform(click());
}
However I get this error:
android.support.test.espresso.NoMatchingViewException: No views in hierarchy found matching: with id: com.example.adrien.smartalarm:id/add_sound
If the target view is not part of the view hierarchy, you may need to use Espresso.onData to load it from one of the following AdapterViews:android.support.v7.widget.MenuPopupWindow$MenuDropDownListView{5a0c4d8 VFED.VC.. .F...... 0,0-686,672}
What is wrong with what I have done?
The problem is the submenu gets shown in a PopupWindow, which is not part of activity's view hierarchy. Therefore you have to add:
.inRoot(RootMatchers.isPlatformPopup())
The next thing is the items are displayed in a special ListView named MenuDropDownListView. So onView() will not work here, you have to use onData().
Therefore the complete expression is:
onData(CoreMatchers.anything())
.inRoot(RootMatchers.isPlatformPopup()) // isPlatformPopup() == is in PopupWindow
.inAdapterView(CoreMatchers.<View>instanceOf(MenuPopupWindow.MenuDropDownListView.class))
.atPosition(0) // for the first submenu item, here: add_sound
.perform(click());

How to use orderInCategory

<?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/item1"
android:title="#string/item_name_1"
app:showAsAction="ifRoom"
android:orderInCategory="3" />
<item
android:id="#+id/item2"
android:title="Create"
app:showAsAction="ifRoom"
android:icon="#drawable/create"
/>
<item
android:id="#+id/item3"
android:title="Delete"
app:showAsAction="always"
android:icon="#drawable/delete"
/>
</menu>
I am trying to use orderIncategory attribute of item tag in menu but it is not wrking as no changes are getting reflected. Am I doing anything wrong
The order in which the menu items will appear within the menu. The menu items are arranged from left to right in ascending order of integer value of orderInCategory (i.e. 1,2,3... -> left to right).
The items with the lowest orderInCategory values are displayed as actions, and the remaining items are displayed in the overflow menu.

Categories

Resources