Android ActionBar - Item icon change continuously? - java

On my ActionBar there is one item that has an icon about a star(without filled).
When the user clicks on it, the icon changes to another icon(filled star).
But the problem is that if the user cliccks again the icon doesn't change one more time.
So, this is what i want
icon1->click->icon2->click->icon1->click->icon2
My item xml:
<item
android:id="#+id/bookmark"
android:icon="#drawable/bookmark"
android:showAsAction="ifRoom"
android:title="Add to Favorites"/>
My Java for actionBar:
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
menu.clear();
inflater.inflate(R.menu.activity_desc, menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if(item.getItemId() == R.id.bookmark){
// i tried this: something like: if(item.getIcon() == (R.drawable.nobookmark){} it doesn't work
item.setIcon(R.drawable.nobookmark);
return true;
}
return true;
}

In your item.xml make it checkable:
<item
android:id="#+id/bookmark"
android:icon="#drawable/nobookmark"
android:checkable="true"
android:showAsAction="ifRoom"
android:title="Add to Favorites"/>
In the java you must manually toggle the checked state and select the icon:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if(item.getItemId() == R.id.bookmark){
item.setChecked(!item.isChecked());
item.setIcon(item.isChecked() ? R.drawable.bookmark : R.drawable.nobookmark);
return true;
}
return false;
}

Related

Setting menu items based on user input android

I have been reading answers to questions on here for hours and no solutions seem to work for me.
I am creating an android app for DnD Character Creations, and if the user selects a magical class, I would like to add a spell book option to the main menu.
For some reason, no matter what I do, it will either show visible or invisible based on the XML and will not change it through the code.
This is my XML:
<?xml version="1.0" encoding="utf-8"?>
<!--TODO: create related icons-->
<group android:checkableBehavior="single">
<item
android:id="#+id/nav_profile"
android:title="Profile"
android:visible="true"/>
<item
android:id="#+id/nav_battle"
android:title="Battle"
android:visible="true"/>
<item
android:id="#+id/nav_items"
android:title="Items"
android:visible="true"/>
<item
android:id="#+id/nav_spellbook"
android:title="Spell Book"
android:visible="false"/>
</group>
This was attempt 1 in java:
public void classBasedTraits() {
int intHealthInitial = 0;
//end attempt
switch (strCharacterClass) {
case "Sorcerer":
case "Wizard":
intHealthInitial = 6; // Sorcerer and Wizard's initial health is 6
break;
case "Bard":
case "Cleric":
case "Druid":
case "Monk":
case "Rogue":
case "Warlock":
intHealthInitial = 8; // Bard, Cleric, Druid, Monk, Rogue, and Warlock's initial health is 8
break;
case "Fighter":
case "Paladin":
case "Ranger":
intHealthInitial = 10; // Fighter, Paladin, and Ranger's initial health is 10
break;
case "Barbarian":
intHealthInitial = 12; // Barbarian's initial health is 12
break;
}
//Attempt to create spellbook for magical classes'
Set<String> setMagical;
setMagical = new HashSet<String>(Arrays.asList("Bard", "Cleric", "Druid", "Paladin",
"Ranger", "Sorcerer", "Warlock", "Wizard"));
if(setMagical.contains(strCharacterClass)){
magical = true;
invalidateOptionsMenu();
}
intTotalHP = intHealthInitial + intConstitutionMod; // Starting HP is initial health + constitution modifier
intRemainingHP = intTotalHP; // Sets character at full health
}
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.activity_main_drawer, menu);
menu.findItem(R.id.nav_spellbook).setVisible(magical);
return super.onPrepareOptionsMenu(menu);
}
this was attempt 2 in java, in the Profile activity class, because this class is called after the character class has been specified, and this function is when the menu is set up for the first time:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.activity_main_drawer, menu);
Set<String> setMagical;
setMagical = new HashSet<String>(Arrays.asList("Bard", "Cleric", "Druid", "Paladin",
"Ranger", "Sorcerer", "Warlock", "Wizard"));
MenuItem spellbook = menu.findItem(R.id.nav_spellbook);
if(setMagical.contains(characterClass))
{
spellbook.setVisible(true);
}
else
{
spellbook.setVisible(false);
}
return true;
}
Here is the project on github if anyone want's to take a look at the full code
https://github.com/Doszust/RPG-Character-Sheet/tree/master/app/src/main/java/com/ucfknights/dylan_oszust/dungeonsanddragons
You were on the right track with the first attempt. You use invalidateOptionsMenu() to trigger a call to onPrepareOptionsMenu() where you implement your changes to the menu.
You need to return true from onPrepareOptionsMenu() in order for it to be displayed.
Also don't inflate the menu again in onPrepareOptionsMenu(). You are already supplied the menu in the method parameters.
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.activity_main_drawer, menu);
return true;
}
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
menu.findItem(R.id.nav_spellbook).setVisible(magical);
return true;
}
Your menu file should look like this:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<group android:checkableBehavior="single">
<item
android:id="#+id/nav_profile"
android:title="Profile"
android:visible="true"/>
<item
android:id="#+id/nav_battle"
android:title="Battle"
android:visible="true"/>
<item
android:id="#+id/nav_items"
android:title="Items"
android:visible="true"/>
<item
android:id="#+id/nav_spellbook"
android:title="Spell Book"
android:visible="false"/>
</group>
</menu>
So onCreateOptionsMenu() is where you first create the menu. Then onPrepareOptionsMenu() is where you can modifiy it from then on.
For anyone who is also looking to fix this problem with the nav_drawer menu, you have to access it differently than the standard options menu (Thanks to Sound Conception for pointing out the difference). The code should get the menu from the navigation view.
The working code is below, it is the initial menu builder for the app, and it checks to see if the class is a magical class before deciding to show or hide the spellbook option in the nav drawer.
#Override
public boolean onCreateOptionsMenu(Menu menu) {
Set<String> setMagical;
setMagical = new HashSet<String>(Arrays.asList("Bard", "Cleric", "Druid", "Paladin",
"Ranger", "Sorcerer", "Warlock", "Wizard"));
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
Menu nav_Menu = navigationView.getMenu();
MenuItem spellbook = nav_Menu.findItem(R.id.nav_spellbook);
if(setMagical.contains(characterClass))
{
spellbook.setVisible(true);
}
else
{
spellbook.setVisible(false);
}
return true;
}

android - Menu item stays white even disabled

Graying out the Save item in toolbar only happens in design mode but never on runtime.
I'm using this code:
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
if(count > 0) {
menuItemSave.setEnabled(true);
} else {
menuItemSave.setEnabled(false);
}
return true;
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.options_menu, menu);
menuItemSave = menu.findItem(R.id.save);
return true;
}
It's enabling/disabling but it just really not turning into gray when disabled.
You can use custom color to change color when button is enabled or disabled. [ Change color according to your requirement ]
colors/custom_button_color.xml:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="#FF0000" android:state_enabled="false" />
<item android:color="#CCCCCC"/>
</selector>
In menu.xml file set to your required button item like
android:textColor="#color/custom_button_color"
According to Android docs onPrepareOptionsMenu is called just before menu is opened.But if menu is always open, it will not be called.
So,
On Android 3.0 and higher, you must call invalidateOptionsMenu() when you want to update the menu that is always open. The system will then call onPrepareOptionsMenu() so you can update the menu items.

Error starting method from action bar button

I am trying to create a button on the action bar that will activate a method that is in the same activity.
Below is my menu xml:
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:context=".AddContactActivityOCR">
<item
android:id="#+id/action_settings"
android:orderInCategory="100"
android:title="#string/action_settings"
app:showAsAction="never" />
<item
android:id="#+id/undo"
android:orderInCategory="100"
android:title="UNDO"
app:showAsAction="always"/>
</menu>
Below are my relevant codes in the activity:
#Override
public boolean onCreateOptionsMenu (Menu menu) {
getMenuInflater().inflate(R.menu.menu_add_contact_undo, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.undo:
onRewrite();
return true;
case android.R.id.home:
finish();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
public void onRewrite(View v){
listName.setText(recognizedText);
listOwner.setText(recognizedText);
companyName.setText(recognizedText);
companyAddress.setText(recognizedText);
companyNumber.setText(recognizedText);
mCurrentLang = mFromLang;
validator(recognizedText);
}
I am trying to start "onRewrite()" when I click the "UNDO" button on my action bar.
However it shows the error below:
I tried using "android:onClick="onRewrite" on a normal button and it is able to start this method. Why is it not starting "onRewrite" in this case?
why its show error?
you have create method with parameter View like onRewrite(View v) and you are trying to call it without parameter that's why its show you that message.
remove parameter from method. like below
public void onRewrite(){ .... // your code}
I tried using "android:onClick="onRewrite" on a normal button and it
is able to start this method.
why its working?
want to use method to work in both case. create two method with same name & use same code inside that.
public void onRewrite(){ .... // your code}
public void onRewrite(View v){ .... // your code}
another solution is create button click in activity and remove android:onClick="onRewrite from layout.xml, call onRewrite() from click event as well as from onOptionsItemSelected
Change your Activity code
Error Because you calling method On onRewrite() without Parameter
#Override
public boolean onCreateOptionsMenu (Menu menu) {
getMenuInflater().inflate(R.menu.menu_add_contact_undo, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.undo:
onRewrite();
return true;
case android.R.id.home:
finish();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
public void onRewrite(){
listName.setText(recognizedText);
listOwner.setText(recognizedText);
companyName.setText(recognizedText);
companyAddress.setText(recognizedText);
companyNumber.setText(recognizedText);
mCurrentLang = mFromLang;
validator(recognizedText);
}
Hope this will helps you

Share item in actionbar using contextual actionbar

For the first time i use the contextual actionbar. When i click in the item of my ListView i want have the possibility to share that item in some way (whatsapp/mail/gmail/drive etc etc..). I'm trying in with this method but no works:
the menu layout:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="#+id/shareButton"
android:actionProviderClass="android.widget.ShareActionProvider"
android:title="#string/share"
android:showAsAction="always"/>
</menu>
The contextual actionbar class:
public class CABMode implements ActionMode.Callback {
private ShareActionProvider mshare;
#Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
mode.getMenuInflater().inflate(R.menu.cab, menu);
return true;
}
#Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
// don't need to do anything
return false;
}
#Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
mshare = (ShareActionProvider) item.getActionProvider();
mshare.setShareIntent(Share());
return true;
}
#Override
public void onDestroyActionMode(ActionMode mode) {
Mode = null;
}
public Intent Share() {
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("text/plain");
intent.putExtra(Intent.EXTRA_TEXT, "Share");
return intent;
}
}
Well, the contextual actionbar it opens well when i do an long click, but the share button in the actionbar doesn't work. When i say "not works" i mean that seems not clickable. Nothing works when i click over the item. Nothing appears. What i want it's open the multiple share ways. Thanks
When i say "not works" i mean that seems not clickable
ActivityChooserView, the action view ShareActionProvider returns, disables the "share" button when there are no items to display, which in your case if because you're setting up ShareActionProvider incorrectly. All of the "on click" events are handled internally, you won't receive any callbacks to ActionMode.Callback.onActionItemClicked.
Rather than settings it up in ActionMode.Callback.onActionItemClicked, move that code into ActionMode.Callback.onCreateActionMode and call Menu.findItem to initialize it.
#Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
mode.getMenuInflater().inflate(R.menu.cab, menu);
final MenuItem item = menu.findItem(R.id.your_share_action_provider_id);
mshare = (ShareActionProvider) item.getActionProvider();
mshare.setShareIntent(Share());
return true;
}

Change Android Action Bar Menu Item's Icon on Click

I'm using sherlock action bar.
I have 2 items on the action bar. When the item is chosen (active), I want to change the icon's image.
This is my code on Java
#Override
public boolean onPrepareOptionsMenu (Menu menu){
MenuInflater inflater = getSupportMenuInflater();
inflater.inflate(R.menu.menutes, menu);
todaySched=menu.findItem(R.id.todaySched);
if(todaySched.isEnabled()){
todaySched.setIcon(R.drawable.calendarselected);
}
return true;
}
but when I do this the icon become double, and the icon won't change neither.
Can someone help?
Use the on onOptionsItemSelected method
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.todaySched:
// put your code here to change the icon
return true;
default:
return super.onOptionsItemSelected(item);
}
}
you may need to include the correct namespace for the ActionBar Sherlock library to ensure it Overrides the correct menu item. So the start of the method will look like this:
#Override
public boolean onOptionsItemSelected(com.actionbarsherlock.view.MenuItem item)

Categories