How to detect menu item overflow? - android

Is it possible to programmatically detect when a menu is overflowed?
My intention is to have a menu item always be visible (SHOW_AS_ACTION_ALWAYS), except for in the case where it would cause other items to overflow, in which case, don't show the menu item at all. That is:
if (overflowed) actionBarMenu.removeItem(id);

You are not saying where this menu is appearing, so I'll just give an example of what you can do with a Toolbar. What you need to do is to get the reference to the ActionMenuView from the Toolbar and then call isOverflowMenuShowing on it, something like this:
private boolean isOverflowShowing(Toolbar toolbar) {
if(toolbar == null) {
return false;
}
for(int i = 0; i < toolbarView.getChildCount(); i++) {
View v = toolbarView.getChildAt(i);
if(v instanceof ActionMenuView) {
return ((ActionMenuView)v).isOverflowMenuShowing();
}
}
return false;
}
This is crude and dirty - and I haven't tested it - but it should get you started.

Related

collapse all recycler view sections except one.. set image resource

I am trying to collapse all sections in recyclerview except one ( currently selected)..
I can collapse all items successfully.. but I want to reverse the arrow direction in headerholder.. I Using the library as https://github.com/luizgrp/SectionedRecyclerViewAdapter..
while reversing the arrow it is giving null pointer exception for headerholders out of window ( not visible in present screen)..
{
for (int i = 0; i < deviceInfoList.size(); i++) {
ExpandableDeviceSection section = (ExpandableDeviceSection) sectionAdapter.getSection(deviceInfoList.get(i).getdName());
if (section.expanded && !section.dName.equals(dName)) {
section.expanded = false;
HeaderViewHolder headerViewHolder1=(HeaderViewHolder)recyclerView.findViewHolderForAdapterPosition(sectionAdapter.getHeaderPositionInAdapter(section.dName));
//getting null for sectionHeader which is not available.
if(headerViewHolder1!=null)
headerViewHolder1.imgArrow.setImageResource(section.expanded ? R.drawable.ic_expand_less : R.drawable.ic_expand_more);
}
}
// sectionAdapter.notifyDataSetChanged();
}
here is my all collapse code in onclick listener.. I hope this clarifies.. let me know if anything else required..
Problem solved.. forgot to set image view (imagearrow) in onbindheaderview holder..
No need to set it in for loop now .

Android Toolbar overflow menu view id

What I am trying to do is showing a PopupWindow pointing to the overflow icon (the three dots) on the Toolbar. So I need to get a reference to the View object with the id of the icon. But what is the id?
The PopupWindow is used to tell the users that there are new entries added to the overflow menu. And suggest users to check it out.
You should create the button id
<?xml version="1.0" encoding="utf-8"?>
<resources>
<item type="id" name="overflowActionButton"/>
</resources>
then create the button style
<style name="Widget.ActionButton.Overflow" parent="Widget.AppCompat.ActionButton.Overflow">
<item name="android:id">#id/overflowActionButton</item>
</style>
and add this style in the theme
<style name="Theme.App" parent="Theme.MaterialComponents.Light.NoActionBar">
<item name="actionOverflowButtonStyle">#style/Widget.ActionButton.Overflow</item>
</style>
finally you should find the button view by id
activity.findViewById(R.id.overflowActionButton)
and do what you want
The overflow menu item doesn't have a resource id. I found the overflow view by traversing the toolbar. The debugger showed an id of -1 and the Hierarchy Viewer showed no resource-id.
Here is how I found the overflow view without a resource id:
/**
* Get the OverflowMenuButton.
*
* #param activity
* the Activity
* #return the OverflowMenuButton or {#code null} if it doesn't exist.
*/
public static ImageView getOverflowMenuButton(Activity activity) {
return findOverflowMenuButton(activity, findActionBar(activity));
}
static ImageView findOverflowMenuButton(Activity activity, ViewGroup viewGroup) {
if (viewGroup == null) {
return null;
}
ImageView overflow = null;
for (int i = 0, count = viewGroup.getChildCount(); i < count; i++) {
View v = viewGroup.getChildAt(i);
if (v instanceof ImageView && (v.getClass().getSimpleName().equals("OverflowMenuButton") ||
v instanceof ActionMenuView.ActionMenuChildView)) {
overflow = (ImageView) v;
} else if (v instanceof ViewGroup) {
overflow = findOverflowMenuButton(activity, (ViewGroup) v);
}
if (overflow != null) {
break;
}
}
return overflow;
}
static ViewGroup findActionBar(Activity activity) {
try {
int id = activity.getResources().getIdentifier("action_bar", "id", "android");
ViewGroup actionBar = null;
if (id != 0) {
actionBar = (ViewGroup) activity.findViewById(id);
}
if (actionBar == null) {
return findToolbar((ViewGroup) activity.findViewById(android.R.id.content).getRootView());
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
static ViewGroup findToolbar(ViewGroup viewGroup) {
ViewGroup toolbar = null;
for (int i = 0, len = viewGroup.getChildCount(); i < len; i++) {
View view = viewGroup.getChildAt(i);
if (view.getClass() == android.support.v7.widget.Toolbar.class ||
view.getClass().getName().equals("android.widget.Toolbar")) {
toolbar = (ViewGroup) view;
} else if (view instanceof ViewGroup) {
toolbar = findToolbar((ViewGroup) view);
}
if (toolbar != null) {
break;
}
}
return toolbar;
}
Calling getOverflowMenuButton(activity) will return null in onCreate because the overflow menu isn't laid out yet. To get the overflow menu in onCreate I did the following:
findViewById(android.R.id.content).post(new Runnable() {
#Override public void run() {
ImageView overflow = getOverflowMenuButton(MainActivity.this);
}
});
I found a library called TapTarget and a function TapTarget.forToolbarOverflow(). It presents a solution: https://github.com/KeepSafe/TapTargetView/blob/master/taptargetview/src/main/java/com/getkeepsafe/taptargetview/TapTarget.java#L96
The way how it finds the overflow view is not neat but should be stable.
you want to create custom DropDown menu? consider this "native" way
or use android:showAsAction="never" in your menu.xml. doc of showAsAction attribute HERE. when one of MenuItems have set never value then you will get overflow three-dot icon automatically and these MenuItems will be hidding there
also you may try to use Hierarchy Viewer to investigate this id if really needed
Instead of using expensive and complicated layout traversal to find the overflow menu, I have achieved showing the PopupWindow under the overflow menu by using the Toolbar view as anchor and setting gravity to Gravity.END:
/**
* Sets the anchor view and shows the popup. In case of narrow display the menu items may be hidden in an overflow
* menu, in that case anchorView may be null and the popup will be anchored to the end of the toolbar.
*/
public void show(#Nullable View anchorView, #NonNull View toolbarView) {
if (anchorView == null) {
setDropDownGravity(Gravity.END);
setAnchorView(toolbarView);
} else {
setAnchorView(anchorView);
}
show();
}

Android Studio GridLayout toggle all button

I'm using a Gridlayout with the MyView.java class. I got the code from GridLayout.
I implemented another button under the GridLayout. I want to toggle all (GrigLayout-)Buttons with this button. Does anyone have an Idea how I could do this?
Thank you!!!
You have to revise through all child views, and check if they are toggle buttons. Here is an example, when you want to toggle, call toggleButtons(grid);
private void toggleButtons(ViewGroup v) {
View a;
for(int i = 0; i < v.getChildCount(); i++)
{
a = v.getChildAt(i);
if(a instanceof ViewGroup) {
toggleButtons((ViewGroup) a);
}
else if(a instanceof Button){
// Toggle here
}
}
}

Disable actionbar Up button

I am trying to disable the Up button in the Support Actionbar on certain user actions. According to http://developer.android.com/reference/android/app/ActionBar.html#setHomeButtonEnabled(boolean), setHomeButtonEnabled should do what I want. However, the button remains clickable. (I can disable the other icons in the actionbar without problem).
I am trying to disable it from a fragment.
My code to disable is:
#Override
public void onPrepareOptionsMenu (Menu menu) {
if (isUpdating) {
getBaseActivity().getSupportActionBar().setHomeAsUpIndicator(getResources().getDrawable(R.drawable.ic_backgrey));
getBaseActivity().getSupportActionBar().setHomeButtonEnabled(false);
for (int i = 0; i < menu.size(); i++) {
menu.getItem(i).setEnabled(false);
menu.getItem(i).getIcon().setAlpha(64);
}
} else {
getBaseActivity().getSupportActionBar().setHomeButtonEnabled(true);
getBaseActivity().getSupportActionBar().setHomeAsUpIndicator(getResources().getDrawable(R.drawable.ic_back));
for (int i = 0; i < menu.size(); i++) {
menu.getItem(i).setEnabled(true);
menu.getItem(i).getIcon().setAlpha(255);
}
}
}
and my code in activity onCreate is:
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setHomeAsUpIndicator(getResources().getDrawable(R.drawable.ic_back));
and my Fragment onCreate contains
setHasOptionsMenu(true)
In your fragment add
getBaseActivity().getSupportActionBar().setDisplayHomeAsUpEnabled(false);
and in your Activity add
getSupportActionBar().setDisplayHomeAsUpEnabled(false);
In oncreate() setDisplayHomeAsUpEnabled should be set to false as well.
getSupportActionBar().setDisplayHomeAsUpEnabled(false);
http://developer.android.com/reference/android/app/ActionBar.html#setDisplayHomeAsUpEnabled(boolean)

Android Support Library 21 toolbar losing theme

My question is in continuation to this question Toolbar NavigationIcon loose theme. This is a known bug in support library 21.
In my case i have two activities with two different theme toolbars. When I navigate back from Activity2 to Activity1, Activity1 toolbar buttons (back and overflow) take Activity2's theme.
I am trying to do a workaround for this problem and this what I have tried so far.
onResume() of my Activity1
#Override
protected void onResume() {
super.onResume();
supportInvalidateOptionsMenu();
if(mToolbar != null) {
// set navigation icon
mToolbar.setNavigationIcon(R.drawable.abc_ic_ab_back_mtrl_am_alpha);
}
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setHomeButtonEnabled(true);
}
onPrepareOptionsMenu of Activity1
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
// set overflow icon
for(int i = 0; i < mToolbar.getChildCount(); i++) {
if(mToolbar.getChildAt(i) instanceof ActionMenuView) {
ActionMenuView v = (ActionMenuView)mToolbar.getChildAt(i);
for(int j = 0; j < v.getChildCount(); j++) {
if(v.getChildAt(j) instanceof TintImageView) {
TintImageView v1 = (TintImageView)v.getChildAt(j);
v1.setImageResource(R.drawable.abc_ic_menu_moreoverflow_mtrl_alpha);
}
}
}
}
return super.onPrepareOptionsMenu(menu);
}
with this workaround my back button is working fine but overflow icon comes in Activity2's theme untill I press it once. Once pressed it changes its theme. Also I am using Searchview in Activity1 and when its activated then only overflow icon appears.
Let me know if more information is required.

Categories

Resources