How to programmatically hide menu on action bars in Android? - java

This is how I declare my menu on my action bars:
public void checkUserType() {
if (mPrefs.getUserType().equalsIgnoreCase("mahasiswa")) {
requestData(String.valueOf(mPrefs.getUserID()));
} else if (mPrefs.getUserType().equalsIgnoreCase("dosen")) {
requestData(String.valueOf(mPrefs.getSelectedUserId()));
getSupportActionBar().hide();
myMenu.findItem(R.id.exit).setVisible(false);
}
And I want to hide/remove the menu from the action bar using an if-else (not hiding whole action bar, just the menu). I have tried using "myMenu.findItem(R.id.exit).setVisible(false);" but it occurs error on a null object reference
This is my code:
public void checkUserType() {
if (mPrefs.getUserType().equalsIgnoreCase("mahasiswa")) {
requestData(String.valueOf(mPrefs.getUserID()));
} else if (mPrefs.getUserType().equalsIgnoreCase("dosen")) {
requestData(String.valueOf(mPrefs.getSelectedUserId()));
getSupportActionBar().hide();
myMenu.findItem(R.id.exit).setVisible(false);
}

This will hide a menu item by id:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater menuInflater = getMenuInflater();
menuInflater.inflate( R.menu.main_menu, menu );
// hide menu item
menu.findItem( R.id.menu_item_1 ).setVisible( false );
return true;
}
You can apply the same to:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if( item.getItemId() == R.id.menu_item_1 ) {
item.setVisible( false );
}
}

here just call invalidateOptionsMenu() and move your logic to onCreateOptionsMenu() and change visiblity there.
for example
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
.
.
btn.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
invalidateOptionsMenu();
}
});
}
and in onCreateOptionsMenu()
#Override
public boolean onCreateOptionsMenu(final Menu menu) {
getMenuInflater().inflate(R.menu.activity_main_menu, menu);
menu.findItem(R.id.menu_item).setVisible(condition);
}

Related

Can't set visibility on a SearchView with savedInstanceState

My activity has a menu which includes a SearchView, and I'm setting the SearchView visibility programmatically. I'm using savedInstanceState to preserve the Visibility value eg between rotations, but this aspect is not working: in the scenario where the SearchView visibility is GONE before rotation, the SearchView icon is showing after rotation.
If I debug and evaluate mSearchView.getVisibility() after picking up its value from savedInstanceState, it appears to be correctly set to 8.
There are lines in my code which setVisibility(View.VISIBLE), but none of them are hit between the value from savedInstanceState being set, and the rotated layout appearing to the user.
Layout:
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<!-- "Mark Favorite", should appear as action button if possible -->
<item android:id="#+id/action_search"
android:title="#string/action_search"
app:actionViewClass="androidx.appcompat.widget.SearchView"
app:showAsAction="ifRoom"/>
Activity (onSaveInstanceState):
public void onSaveInstanceState(Bundle outState){
super.onSaveInstanceState(outState);
switch (mSearchView.getVisibility()){
case View.VISIBLE:
outState.putInt("SearchViewVisibility",View.VISIBLE);
case View.GONE:
outState.putInt("SearchViewVisibility",View.GONE);
};
}
Activity (Menu setup):
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main, menu);
//setup SearchView and callbacks
final MenuItem searchItem = menu.findItem(R.id.action_search);
mSearchView = (SearchView) searchItem.getActionView();
if(mSavedInstanceState != null){
switch (mSavedInstanceState.getInt("SearchViewVisibility")){
case View.VISIBLE:
mSearchView.setVisibility(View.VISIBLE);
case View.INVISIBLE:
mSearchView.setVisibility(View.INVISIBLE);
case View.GONE:
mSearchView.setVisibility(View.GONE);
}
}
mSearchView.setOnQueryTextListener(new SearchView.OnQueryTextListener(){
#Override
public boolean onQueryTextSubmit(String query) {
SetFragmentAndFilter(query);
return true;
}
#Override
public boolean onQueryTextChange(String query) {
// check whether this change is clearing all text from the search
if(query.isEmpty()){
// close the searchView
mSearchView.post(new Runnable(){
#Override
public void run(){
mSearchView.clearFocus();
}
});
mSearchView.setIconified(true);
}
//have the list match the new query text
SetFragmentAndFilter(query);
return true;
}
});
return true;
}
Would really appreciate any thoughts!
You should use setVisible method to set the visibility of a menu item.
Change your code to
// Add this property
MenuItem mSearchMenuItem;
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putBoolean("isVisible", mSearchMenuItem.isVisible());
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main, menu);
//setup SearchView and callbacks
mSearchMenuItem = menu.findItem(R.id.action_search);
if (mSavedInstanceState != null) {
boolean isVisible = mSavedInstanceState.getBoolean("isVisible", true);
mSearchMenuItem.setVisible(isVisible);
}
mSearchView = (SearchView) mSearchMenuItem.getActionView();
mSearchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
return true;
}
#Override
public boolean onQueryTextChange(String query) {
// check whether this change is clearing all text from the search
if (query.isEmpty()) {
// close the searchView
mSearchView.post(new Runnable() {
#Override
public void run() {
mSearchView.clearFocus();
}
});
mSearchView.setIconified(true);
}
return true;
}
});
return true;
}

How to access an options menu item from outside the menu

How can an options menu item be accessed from an object outside of the menu itself? I'm trying to set an alpha value for one of the options menu items, but it's not working for some reason. The commented lines are what I tried.
I've seen the following code used before, but it's not clear on where and how it should be used:
Drawable drawable = item.getIcon();
if (drawable != null) {
drawable.mutate();
drawable.setAlpha(1);
}
Activity class
public class WebviewActivity extends AppCompatActivity {
private static final String TAG = WebviewActivity.class.getSimpleName();
WebView myWebView;
ProgressBar myProgressBar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.fragment_webview);
}
#Override
protected void onStart() {
super.onStart();
setContentView(R.layout.fragment_webview);
String url = getIntent().getStringExtra("url");
myWebView = findViewById(R.id.web_view);
myWebView.setWebViewClient(new WebViewClient());
WebSettings webSettings = myWebView.getSettings();
webSettings.setJavaScriptEnabled(true);
myWebView.loadUrl(url);
myWebView.setWebChromeClient(new WebChromeClient() {
#Override
public void onProgressChanged(WebView view, int newProgress) {
super.onProgressChanged(view, newProgress);
myProgressBar.setProgress(newProgress);
}
});
}
private class WebViewClient extends android.webkit.WebViewClient {
#Override
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request){
String url=request.getUrl().toString();
view.loadUrl(url);
return true;
}
#Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
}
}
public void onBtnBackPressed() {
if (myWebView.canGoBack()){
myWebView.goBack();
} else {
onBackPressed();
}
}
public void onBtnForwardPressed() {
if (myWebView.canGoForward()){
myWebView.goForward();
} else {
// menu.getItem(R.id.action_webbrowser_forward).setEnabled(false);
// menu.getItem(R.id.action_webbrowser_forward).mutate();
// menu.getItem(R.id.action_webbrowser_forward).setAlpha(1);
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.web_browser, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
else if (item.getItemId() == R.id.action_webbrowser_back) {
onBtnBackPressed();
} else if (item.getItemId() == R.id.action_webbrowser_forward) {
onBtnForwardPressed();
}
return super.onOptionsItemSelected(item);
}
}
Define in your activity class this variable:
MenuItem action_webbrowser_forward;
In onCreateOptionsMenu() after the inflation of the menu, write this:
action_webbrowser_forward = menu.findItem(R.id.action_webbrowser_forward);
then you can use it anywhere in your class:
action_webbrowser_forward.setEnabled(false);
but mutate is used for drawables and not menu items, so get the icon of the item by action_webbrowser_forward.getIcon() and apply mutate to it.
Try passing MenuItem reference on your onBtnForwardPressed function parameters :
#Override
public boolean onOptionsItemSelected(MenuItem item) {
else if (item.getItemId() == R.id.action_webbrowser_back) {
onBtnBackPressed();
} else if (item.getItemId() == R.id.action_webbrowser_forward) {
onBtnForwardPressed(item);
}
return super.onOptionsItemSelected(item);
}
And :
public void onBtnForwardPressed(MenuItem menuItem) {
if (myWebView.canGoForward()){
myWebView.goForward();
} else {
menuItem.setEnabled(false);
menuItem.getIcon().setAlpha(50);
}
}
Hope this helps
Okay I spend couple of hour to get this solution.apparently you can get menuitem from your toolbar. So in my case.
var menuItem = toolbar.menu;
Now to get specfic item from menu item
favIcon = menuItem.findItem(R.id.favourite);
Note: favIcon is MenuItem declare global
Now if you can do whatever you want to do for this icon
eg. to make it invisible
favIcon?.isVisible=false

Hide 3-dot menu item when the Navigationbar appears

I want to hide the three-dot menu item when the navigationbar appears.
I found some nice topics how to hide the three-dot menu item:
How to disable/hide three-dot indicator(Option menu indicator) on ICS handsets
How do I hide a menu item in the actionbar?
But I can not find a solution for my problem. I hope for some help. :)
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater menuInflater = getMenuInflater();
menuInflater.inflate(R.menu.main_menu, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
infoDialogFragment.aboutMenuItem(this);
return false;
}
#Override
protected void onPostCreate(#Nullable Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
actionBarDrawerToggle.syncState();
}
private void setNavigationDrawer() {
navigationView.setNavigationItemSelectedListener(menuItem -> {
});
return false;
}
Delete all of this codes from your activity:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater menuInflater = getMenuInflater();
menuInflater.inflate(R.menu.main_menu, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
infoDialogFragment.aboutMenuItem(this);
return false;
}

Android onOptionsItemSelected method of Fragment doesn't get called

there are many questions about the topic but i can't figure out my problem. I have a menu declared in my MainActivity(ActionBarActivity). Now i want to work with MenuItem in onOptionsItemSelected of a Fragment class. Here is my MainActivity methods
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);
return super.onCreateOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// toggle nav drawer on selecting action bar app icon/title
if (mDrawerToggle.onOptionsItemSelected(item)) {
return true;
}
// Handle action bar actions click
switch (item.getItemId()) {
case R.id.add_note:
createNewNote();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
private void createNewNote() {
Intent addIntent = new Intent(MainActivity.this, AddNote.class);
startActivity(addIntent);
}
And Fragment methods
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.add_note:
Toast.makeText(getActivity(), "Entered into fragment", Toast.LENGTH_LONG).show();
createNewNote();
return true;
default:
break;
}
return super.onOptionsItemSelected(item);
}
private void createNewNote() {
Intent addIntent = new Intent(getActivity(), AddNote.class);
startActivity(addIntent);
}
Here in MainActivity onOptionsItemSelected get called even in Fragment but doesn't in Fragment as i don't see Toast in Fragment. I think something is missed in my code. Thanks in advance.
inside onOptionsItemSelected() in activity inside your switch after calling createNewNote() instead of returning true return super.onOptionsItemSelected(item)
you must call setHasOptionsMenu() inside onCreate of fragment for menu related method to work.
Your onCreateOptionsMenu() method does not inflate the menu file:
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
}

How can I change option menu in different fragments?

I have a Fragment with menu:
public class FragmentA extends Fragment {
public FragmentA() {
setHasOptionsMenu(true);
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
setHasOptionsMenu(true);
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.activity_main_actions, menu);
super.onCreateOptionsMenu(menu, inflater);
}
}
I would like to change menu but it doesn't work and keep the old action menu
Fragment B is equals like above with different inflate XML menu.
public class FragmentB extends Fragment {
public FragmentB() {
setHasOptionsMenu(true);
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
setHasOptionsMenu(true);
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.**action_ranking**, menu);
super.onCreateOptionsMenu(menu, inflater);
}
}
EDITED:
Can be useful to use different menu layout for different fragments and 1 menu layout for main activity and differents id
Put setHasOptionsMenu(true) in constructor and inflate fragment specific menu.
public class FragmentA extends Fragment {
public FragmentA() {
setHasOptionsMenu(true);
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
setHasOptionsMenu(true);
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.fragmenta_menu, menu);
super.onCreateOptionsMenu(menu, inflater);
}
}
menu in main activity
public class MainActivity extends Activity {
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.main_menu, menu);
super.onCreateOptionsMenu(menu, inflater);
}
}
Can all be done via Fragment - no need to inflate menu from activity:
public class UpdateFragment extends Fragment {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// ...
setHasOptionsMenu(true);
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.update_menu, menu);
super.onCreateOptionsMenu(menu, inflater);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
switch (id){
case R.id.navUpdateProfile:
showToast("navUpdateProfile");
return true;
default:
return super.onOptionsItemSelected(item);
}
}
}
If you have several fragments that share the same menu with some exceptions.
class BaseFragment:Fragment(){
open var menuId = R.menu.default_menu
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setHasOptionsMenu(true) // will apply to all children
}
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
super.onCreateOptionsMenu(menu, inflater)
inflater.inflate(menuId, menu) // will apply to all children except for overridden
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
// all menu ids can be listed here unless specific to code in child
when (item.itemId) {
R.id.menu_option_1 -> {
// do something
}
R.id.menu_option_2 -> {
//do something
}
return false
}
}
class ChildFragment:BasFragment(){
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
menuId = R.menu.menu_2 // change to a different menu as desired here
}
}

Categories

Resources