Get an item of an item in espresso - android

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());

Related

Can't add Menu item next to another

I am trying to add Menu item(action_collapse_expand) next to another menu item. Problem is that item is added to expandable list(three dots icon), but not as separate icon. I've just started learning Android and I would like to know what am I doing wrong.
<?xml version="1.0" encoding="utf-8" ?>
<!--For all properties see: http://developer.android.com/guide/topics/resources/menu-resource.html-->
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="#+id/action_collapse_expand"
android:icon="#drawable/drag_drop"
android:title="Collapse"
android:showAsAction="always|withText" />
<item android:id="#+id/add" android:showAsAction="never" android:title="add" android:icon="#drawable/Add">
<menu>
<item android:id="#+id/map" android:showAsAction="always|withText" android:title="map" android:icon="#drawable/Map" />
<item android:id="#+id/mapK" android:showAsAction="always|withText" android:title=mapK" android:icon="#drawable/MapK" />
</menu>
</item>
<item android:id="#+id/exit" android:showAsAction="always" android:title="Exit" android:icon="#drawable/Close" />
</menu>
Try replacing android:showAsAction with app:showAsAction.
Don't forget to add xmlns:app="http://schemas.android.com/apk/res-auto" under your menu tag.

Error when Adding Menu to App - Xamarin c# Visual Studio

I am trying to inflate an XML Menu inside my App, but i get the following error when I try to Deploy the App on an Emulator:
Unhandled Exception:
Java.Lang.RuntimeException: Unexpected end of document occurred
Also my XML is located in Resources/menu/main
Inflate Menu Code:
XML Code:
<?xml version="1.0" encoding="utf-8" ?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:id="#+id/mnuAppLogo"
android:title="logoHere"/>
<item android:id="#+id/mnuAppName"
android:title="App Name"/>
<menu>
<item android:id="#+id/submenuHelp"
android:title="Help" />
<item android:id="#+id/submenuExit"
android:title="Exit" />
</menu>
</menu>
Why is this?
Let me know if you need more code...
Thanks in advance.
UPDATE 1:
I want to make the logoHere and App Name appear in spots 1 and 2 with the other 2 Help and Exit inside the Menu.
To create a "submenu", the elements must be included within an item element:
<?xml version="1.0" encoding="UTF-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="#+id/mnuAppLogo" android:title="logoHere" />
<item android:id="#+id/mnuAppName" android:title="App Name">
<menu>
<item android:id="#+id/submenuHelp" android:title="Help" />
<item android:id="#+id/submenuExit" android:title="Exit" />
</menu>
</item>
</menu>
How do I make it so that the First 2 (logoHere and App Name) are not in the "Hamburger Menu" and just on the Action Bar? The Help and Exit however will be inside the Menu.
You can use showAsAction="never" to always place the menu item in the overflow menu and showAsAction="ifRoom" to display it as an action bar button IF there is room for it.
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="#+id/mnuAppLogo" showAsAction="ifRoom" android:title="logoHere" />
<item android:id="#+id/mnuAppName" showAsAction="ifRoom" android:title="App Name" />
<item android:id="#+id/submenuHelp" showAsAction="never" android:title="Help" />
<item android:id="#+id/submenuExit" showAsAction="never" android:title="Exit" />
</menu>

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.

Add child to a MenuItem within a group in a NavigationView

I already checked some questions but none has a really answer of what I'm looking for.
Basically I'm trying to add an item child to an item parent, or simulate a tree of options in the lateral panel, something like the Google Play app does:
I tried this as a test in my XML file:
<group android:checkableBehavior="single">
<item
android:orderInCategory="0"
android:id="#+id/nav_back"
android:icon="#drawable/ic_arrow_back_black_24dp"
android:title="Regresar a la pagina principal"
/>
</group>
<group android:checkableBehavior="single"
android:id="#+id/groupTypes">
<item
android:orderInCategory="1"
android:id="#+id/nav_negocios"
android:icon="#drawable/ic_local_convenience_store_black_48dp"
android:title="#string/negocios" />
<item
android:orderInCategory="1"
android:id="#+id/nav_hoteles"
android:icon="#drawable/ic_local_hotel_black_48dp"
android:title="#string/hoteles" />
<item
android:orderInCategory="1"
android:id="#+id/nav_bares"
android:icon="#drawable/ic_local_bar_black_48dp"
android:title="#string/bares">
<menu>
<item
android:orderInCategory="1"
android:id="#+id/nav_barType1"
android:icon="#drawable/ic_local_bar_black_48dp"
android:title="#string/restaurant" />
</menu>
</item>
<item
android:orderInCategory="1"
android:id="#+id/nav_restaurant"
android:icon="#drawable/ic_restaurant_black_48dp"
android:title="#string/restaurant" />
<item
android:orderInCategory="1"
android:id="#+id/nav_destacado"
android:icon="#drawable/ic_stars_black_48dp"
android:title="#string/destacado" />
</group>
<group android:title="#string/grupo2">
<menu>
<item
android:id="#+id/nav_taxi"
android:orderInCategory="2"
android:icon="#drawable/ic_local_taxi_black_48dp"
android:title="#string/mobility" />
</menu>
</group>
And this is what I got:
The "Bares" item has changed to a category and the item inside is just adding as the original sequence in the group.
Also I tried using the android:menuCategory="container" and android:menuCategory="secondary"options but the result is the same.
<item
android:orderInCategory="1"
android:id="#+id/nav_bares"
android:menuCategory="container"
android:icon="#drawable/ic_local_bar_black_48dp"
android:title="#string/bares">
<menu>
<item
android:orderInCategory="1"
android:id="#+id/nav_barType1"
android:menuCategory="secondary"
android:icon="#drawable/ic_local_bar_black_48dp"
android:title="#string/restaurant" />
</menu>
</item>
Any suggestions?
I couldn't find such an API in source codes. I decompiled Play Store apk file (version 7.7.17.O) with androidtool.
main.xml
<com.google.android.finsky.layout.play.FinskyDrawerLayout>
<com.google.android.finsky.layout.InsetsFrameLayout>
</com.google.android.finsky.layout.InsetsFrameLayout>
<include layout="#layout/play_drawer_container" />
</com.google.android.finsky.layout.play.FinskyDrawerLayout>
play_drawer_container.xml
<LinearLayout>
<ListView android:id="#id/play_drawer_list" style="#style/PlayDrawerList" />
<TextView android:id="#id/play_drawer_docked_action" android:visibility="gone" style="#style/PlayDrawerDockedAction" />
</LinearLayout>
As you can see, menu items are not set via app:menu. It's just a ListView.
You can also see the difference of view bounds when "Show layout bounds" is turned on:
If they have used the default menu items, you should have seen the boundaries matching.
So, answering to your question: it can be implemented with custom approach, menus have no such functionality.
Update
There are a number of ways to implement that kind of functionality:
Using RecyclerView
Using ListView
Using ScrollView
If there are few items in the list, which won't need recycling functionality, than you can stick with ScrollView. Otherwise, prefer either RecyclerView or ListView, where each of item has its own row item xml.
You need to surround your item with the menu, and then add the submenu below it. It might look like this:
<group android:checkableBehavior="single">
<item
android:orderInCategory="0"
android:id="#+id/nav_back"
android:icon="#drawable/ic_arrow_back_black_24dp"
android:title="Regresar a la pagina principal"
/>
</group>
<group android:checkableBehavior="single"
android:id="#+id/groupTypes">
<menu>
<item
android:orderInCategory="1"
android:id="#+id/nav_negocios"
android:icon="#drawable/ic_local_convenience_store_black_48dp"
android:title="#string/negocios" />
<item
android:orderInCategory="1"
android:id="#+id/nav_hoteles"
android:icon="#drawable/ic_local_hotel_black_48dp"
android:title="#string/hoteles" />
<item
android:orderInCategory="1"
android:id="#+id/nav_bares"
android:icon="#drawable/ic_local_bar_black_48dp"
android:title="#string/bares">
<menu>
<item
android:orderInCategory="1"
android:id="#+id/nav_barType1"
android:icon="#drawable/ic_local_bar_black_48dp"
android:title="#string/restaurant" />
</menu>
</item>
<item
android:orderInCategory="1"
android:id="#+id/nav_restaurant"
android:icon="#drawable/ic_restaurant_black_48dp"
android:title="#string/restaurant" />
<item
android:orderInCategory="1"
android:id="#+id/nav_destacado"
android:icon="#drawable/ic_stars_black_48dp"
android:title="#string/destacado" />
</menu>
</group>
<group android:title="#string/grupo2">
<menu>
<item
android:id="#+id/nav_taxi"
android:orderInCategory="2"
android:icon="#drawable/ic_local_taxi_black_48dp"
android:title="#string/mobility" />
</menu>
</group>
You can try with drop down menu or expandable list or simple lists which can be seen on click of menu options accordingly in navigation drawer instead of group.
For your first approach, you can make a little edit. That SubItem is also an item an instead of putting everything in group you should put in an item. Try this example below:
<item
android:id="#+id/nav_category_electronics"
android:icon="#drawable/ic_email_black_24dp"
android:title="Electronics">
<menu>
<item
android:id="#+id/nav_subcategory_laptops"
android:icon="#drawable/laptop"
android:title="Laptops" />
<item
android:id="#+id/nav_subcategory_tablet"
android:icon="#drawable/tablet3"
android:title="Tablets" />
<item
android:id="#+id/nav_category_phones"
android:icon="#drawable/smartphone"
android:title="Mobile Phones" />
<item
android:id="#+id/nav_subcategory_gadgets"
android:icon="#drawable/ic_developer_mode_black_18dp"
android:title="Gadgets" />
</menu>
</item>

How to show always 5 items in Action mode menu like WhatsApp in Android toolbar

<?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/menu_reply"
android:icon="#drawable/ic_reply_white_24dp"
android:title="Reply"
app:showAsAction="always" />
<item
android:id="#+id/menu_favourite"
android:icon="#drawable/ic_grade_white_24dp"
android:title="Favourite"
app:showAsAction="always" />
<item
android:id="#+id/menu_info"
android:icon="#drawable/ic_info_outline_white_24dp"
android:title="Info"
android:visible="false"
app:showAsAction="always" />
<item
android:id="#+id/menu_delete"
android:icon="#drawable/ic_delete_white_24dp"
android:title="Delete"
app:showAsAction="always" />
<item
android:id="#+id/menu_copy"
android:icon="#drawable/ic_content_copy_white_24dp"
android:title="Copy"
app:showAsAction="always" />
<item
android:id="#+id/menu_right_arrow"
android:icon="#drawable/ic_arrow_right_bold_white_24dp"
android:title="Forward"
app:showAsAction="always" />
<item
android:id="#+id/menu_message"
android:icon="#drawable/ic_arrow_right_bold_white_24dp"
android:title="Message xyz"
app:showAsAction="always" />
<item
android:id="#+id/menu_call"
android:icon="#drawable/ic_arrow_right_bold_white_24dp"
android:title="Call xyz"
app:showAsAction="always" />
</menu>
I'm using Action mode menu while long click on list item. It is always showing max 2 items, even it has space to show more items in Action mode menu. I'm assigning android:showAsAction = "always" for all the items. I'm expecting to design screen like WhatsApp long press showing 5 items with icons.
Use android:showAsAction="always" property along with app:showAsAction="always".
<item
android:id="#+id/menu_reply"
android:icon="#drawable/ic_reply_white_24dp"
android:title="Reply"
app:showAsAction="always"
android:showAsAction="always" />
Use import android.support.v7.view.ActionMode and
yourActionMode = startSupportActionMode(mActionModeCallback)
it solves this problem.

Categories

Resources