I have a MenuItem (set in a fragment, though I tried in activity and got pretty much the same results) which is supposed to spin like a ProgressBar until I receive a broadcast.
I animate the Item by settings an ImageView as actionView and starting an animation on it. the problem is when onCreateOptionsMenu() is called again (for example after invalidateOptionsMenu() or switching to another fragment) the animation is not cleared while all my item are inflated again thus I lose my pointer to the previous actionView and cannot even cancel the animation manually with cancelAction().
here's my code:
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.fragment_playlist_synch, menu);
}
public void onPrepareOptionsMenu(Menu menu){
ImageView syncView = (ImageView) MenuItemCompat.getActionView( menu.findItem(R.id.menu_item_sync));
Animation rotate = AnimationUtils.loadAnimation(getContext(), R.anim.rotate);
rotate.setRepeatCount(Animation.INFINITE);
if(animate)
syncView.startAnimation(rotate);
else
//here the animation would always be null because a new sync menuitem is created in onCreateOptionsMenu without clearing the last one
syncView.clearAnimation();
}
Related
I'm currently having an issue with the menu bar, it will work 75% of the time, but after a while it will start to drop off the Shown items and won't add them or any others back onto the visible items (It will still add to the hidden items)
This is what its meant to look like
(Main Screen)
(ViewPager Fragment
)
And it looks fine most of the time, but after a while the visible items drop off and don't come back (When moving between fragment on the viewPager i clear and inflate the menu, but i've removed this and the issue still occurs)
(Main Screen)
(ViewPager Fragment)
The items inside the Elapsed icon at the end all generate fine and get added as they're meant to, its just the ones that're meant to be visible that aren't showing
This is the ViewPager onCreateOptionsMenu function
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
// Clear Sync and Settings menu
menu.clear()
// Inflate the options menu from ViewModel
inflater.inflate(viewModel?.getMenuLayout() ?: R.menu.job_details_menu, menu)
// Let the VM handle the creation
viewModel?.onCreateOptionsMenu(menu)
super.onCreateOptionsMenu(menu, inflater)
}
I have tried placing the super call at the start and end, it hasn't made a difference.
This is the Main Menu function
#Override
public void onCreateOptionsMenu(#NonNull Menu menu,#NonNull MenuInflater inflater) {
// Add the Schedule Search
final MenuItem item = menu.add(App.getAppContext().getString(R.string.search_hint));
item.setIcon(android.R.drawable.ic_menu_search);
item.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
SearchView sv = new SearchView(getActivity().getSupportActionBar().getThemedContext());
sv.setOnQueryTextListener(this);
sv.setOnQueryTextFocusChangeListener(new View.OnFocusChangeListener() {
#Override
public void onFocusChange(View view, boolean queryTextFocused) {
if (!queryTextFocused) {
item.collapseActionView();
}
}
});
item.setActionView(sv);
super.onCreateOptionsMenu(menu, inflater);
}
Why would this be not refreshing correctly? (Mostly the ViewPager Fragment)
Change:
item.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
To
item.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
I displayed a fragment A that implements a ViewPager with several fragments (nested fragments).
In my nested fragments, I inflate a menu with the following method.
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.my_menu, menu);
super.onCreateOptionsMenu(menu, inflater);
}
This question was already asked here. And i tried all the answers its not working.
My issue is
Everything working fine.but when i open another fragment(it have not any option menu) and get back to previous view pager fragment while clicking menu item onOptionsItemSelected not firing. When i swipe fragment in viewpager and come back to the previous one, when i click menu item its firing.
Its because viewpager maintain 3 fragment alive at a time. so when you come back, it set menu visibility status true to last fragment. thats why your menu item click not firing.
Use the following in the fragment where you keeping a viewpager in your case fragment A.
private boolean isInitial=true;
#Override
public void onResume() {
super.onResume();
if (!isInitial) {
int pos = viewpager.getCurrentItem();
if (pageAdapter.getItem(pos).getUserVisibleHint() && pageAdapter.getItem(pos).isVisible()) {
pageAdapter.getItem(pos).setMenuVisibility(true);
}
} else {
isInitial = false;
}
}
When swiping between tabs on my application, the menu icons have a distinct delay before they appear. If I click tabs, rather than swiping, they update immediately. I have different menu.xml files for each fragment, and inflate them inside each fragment's onCreateOptionsMenu.
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.fodmap_menu, menu);
final MenuItem item = menu.findItem(R.id.action_search);
final SearchView searchView = (SearchView) MenuItemCompat.getActionView(item);
searchView.setOnQueryTextListener(this);
}
Notice the icon changes from the overflow to the magnifying glass instantly when the tabs are clicked, but distinctly delayed when swiping. I would like the icon to be updated as soon as the new tab is centered. On Pocket Cast's Discover menu the tabs with different menu icons seem to load them even before the swipe animation completes.
Instead of using a different menu inside each fragment of the view pager - inflate the menu, call invalidateOptionsMenu() inside the ViewPager's onPageChangeListener, and programmatically display desired menu icon's in onCreateOptionsMenu, all inside the main activity instead of the fragments. The searchView listener is still handled in the fragment.
mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
invalidateOptionsMenu();
}
#Override
public void onPageSelected(int position) {}
#Override
public void onPageScrollStateChanged(int state) {}
});
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.fodmap_menu, menu);
if (mViewPager.getCurrentItem()==0){
menu.findItem(R.id.action_search).setVisible(false);
} else if(mViewPager.getCurrentItem()==1){
menu.findItem(R.id.action_search).setVisible(true);
} else if(mViewPager.getCurrentItem()==2) {
menu.findItem(R.id.action_search).setVisible(false);
}
return super.onCreateOptionsMenu(menu);
}
There is no delay now and the menu icons update before the swipe animation finishes.
Never had this issue with ViewPager. But the new ViewPager2 acts this way. And it is frustrating because there is no way to change the scroll speed since the default is toooo slow.
My menu has a item to Log in, but when you are logged in I want it to say Log out.
How?
If I'm going to change the item after its created, its probably through this method
#Override
public boolean onCreateOptionsMenu( Menu menu ) {
MenuInflater inflater = getMenuInflater();
inflater.inflate( R.menu.menu_main, menu );
return true;
}
Afaik the onCreateOptionsMenu() happens after the onCreate so putting any getItemId() for the menu there will give me a NullPointerException right away.
I want the app to find out if its supposed to use the string R.string.Logout if its logged in.
I dont even know what to search for for this issue. All I found was how to make a string implement names, like this answer https://stackoverflow.com/a/7646689/3064486
You should use onPrepareOptionsMenu(Menu menu) instead to update menu items
#Override
public boolean onPrepareOptionsMenu(Menu menu){
super.onPrepareOptionsMenu(menu);
MenuItem someMenuItem = menu.findItem(R.id.some_menu_item);
someMenuItem.setTitle("Log out");
return super.onPrepareOptionsMenu(menu);
}
To refresh Menu items call invalidateOptionsMenu();from Activity
From Android API guides: "If you want to modify the options menu based on events that occur during the activity lifecycle, you can do so in the onPrepareOptionsMenu() method. This method passes you the Menu object as it currently exists so you can modify it, such as add, remove, or disable items. (Fragments also provide an onPrepareOptionsMenu() callback.)"
After you inflate a menu, you can customize its items. To get each one, you must call findItem() with the item's id. In particular, you can use setTitle() to change the displayed string.
For example:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
if (mIsLoggedIn)
menu.findItem(R.id.action_login).setTitle("Log out");
return true;
}
where action_login is the id you set for this particular menu item in the menu's xml file.
private void updateUI() {
runOnUiThread(new Runnable() {
#Override
public void run() {
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
Menu menu = navigationView.getMenu();
MenuItem nav_signin = menu.findItem(R.id.nav_signin);
nav_signin.setTitle(MyApp.signedIn ? "Sign out" : "Sign in");
}
});
}
My application is basically an online store that has a cart. The button to start the cart is in the ActionBar. When someone presses on a product it starts an animation where the product quicly "slides" through the screen towards the ActionBar cart button. As soon as that finishes the cart "blinks". To blink the cart I use
ValueAnimator cartAnim = ObjectAnimator.ofFloat(mCartItem, "alpha", 1,
0.25f, 0);
Where mCartItem is the ActionBar Item View to be animated.
Now as it turns out getting the View of the actual ActionBar item is kinda hard. I can get the View in onOptionsItemSelected but that's basically it, however this won't work for me since the animation isn't triggered from the ActionBar, it's triggered from a ListView in the main UI. After some googling I did however find a hack around this, that works:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getSupportMenuInflater().inflate(R.menu.cartmenu, menu);
new Handler().post(new Runnable() {
#Override
public void run() {
mCartItem = findViewById(R.id.theitem);
}
});
return(super.onCreateOptionsMenu(menu));
}
Why is this way working? As opposed to:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getSupportMenuInflater().inflate(R.menu.cartmenu, menu);
mCartItem = findViewById(R.id.theitem); // Always ends up null.
return(super.onCreateOptionsMenu(menu));
}
How would you solve the problem I had?
findViewById()
searches for a child view with the given id in "this" view. When you call it in onCreateOptionsMenu() the menu is still not attached to the main view, so you it cannot find your item.
Using Handler().post(new Runnable()...) the findViewById(R.id.theitem) is executed after all your view is created and, of course, even the menu has been attached to your main view, so it can be found.
Better solution:
since you are inflating your cart menu in the menu object, you can use:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getSupportMenuInflater().inflate(R.menu.cartmenu, menu);
mCartItem = menu.findItem(R.id.theitem); //This will find your menu item! :-)
return(super.onCreateOptionsMenu(menu));
}