Recall, onCreateOptionsMenu method (more times) - android

I have this problem: in my class.java I have a private method (I call this in onRemoteCallListenerComplete) that elaborate a data that I want to appear in Menu. This method is not very fast and the application call the onCreateOptionsMenu method before onRemoteCallListenerComplete is finished.
I have read the use void invalidateOptionsMenu() method - to invalidate and re-call onCreateOptionsMenu - and I append this before onRemoteCallListenerComplete ended. However, onOptionsItemSelected method is not re-called.
NB: I'm sorry for my (terrible) English
The following i put my code
onCreateOptionsMenu method
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.dati_carriera, menu);
SharedPreferences prefs = getPreferences(MODE_PRIVATE);
MenuItem item = menu.findItem(R.id.expandableListView1_checkable);
if(sizeValueCollection>0){
item.setVisible(false);
}else{
boolean value = prefs.getBoolean(PREFERENCE_EXPANDIBLE_LIST_VIEW, true);
if(value)
item.setChecked(true);
else
item.setChecked(false);
}
return super.onCreateOptionsMenu(menu);
}
onOptionsItemSelected method
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
SharedPreferences prefs = getPreferences(MODE_PRIVATE);
Toast.makeText(this, "onOptionItemSelceted", Toast.LENGTH_LONG).show();
final ExpandableListView tv;
int id=item.getItemId();
switch(id){
case R.id.expandableListView1_checkable:
tv = (ExpandableListView) findViewById(R.id.expandableListView1);
if(item.isChecked()){
item.setChecked(false);
tv.setVisibility(ExpandableListView.GONE);
Editor prefsEditor = prefs.edit();
prefsEditor.putBoolean(PREFERENCE_EXPANDIBLE_LIST_VIEW, false);
prefsEditor.commit();
}else{
item.setChecked(true);
tv.setVisibility(ExpandableListView.VISIBLE);
Editor prefsEditor = prefs.edit();
prefsEditor.putBoolean(PREFERENCE_EXPANDIBLE_LIST_VIEW, true);
prefsEditor.commit();
}
return true;
default:
return super.onOptionsItemSelected(item);
}
}
onRemoteCallListenerComplete
#Override
public void onRemoteCallListenerComplete(String dati) {
// TODO Auto-generated method stub
[...]
sizeValueCollection=valueCollection.size();
invalidateOptionsMenu();
}
sizeValueCollection is a private int variable initialized to -1

try supportInvalidateOptionsMenu() if you use activity from support package

You can keep a reference to Menu object and update it after you receive all required data.
public class MyActivity extends Activity {
private Menu menu;
private MyMenuData myMenuData;
#Override
public boolean onCreateOptionsMenu(final Menu menu) {
// Prepare menu
this.menu = menu;
if(myMenuData != null){
// Data is loaded, menu can be updated now
updateMenu(myMenuData);
}
return super.onCreateOptionsMenu(menu);
}
public void onRemoteCallListenerComplete(MyMenuData data){
this.myMenuData = data;
updateMenu(data);
}
private void updateMenu(MyMenuData menuData){
// Update your menu here
}
}

Related

Make menu item on android work like a button

I'm here to see if they guide me in this problem
I have a menu, with an item, and what I want is that item to work as a button, if you click on it change the icon and a toast that says Notification active, and if you click again, change the icon and say using toast, Disabled notifications.
All this I have achieved, the detail is that when activating the button and leaving the activity and when entering again, the button is again deactivated, when it should be activated
I hope you understand, here I give you the code, which makes the function perfect, but I think I must do something with shared preferences to save if it is clicked or not, but I do not know where to start, I hope you understand and guide me, I leave the code that I have implemented
----- xml menu ------------
<?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:icon="#drawable/ic_notifications_off_black_24dp"
android:title="#string/notificaciones"
android:id="#+id/notificaciones"
android:checkable="true"
app:showAsAction="always"
/>
</menu>
--------- Java---------------
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menucampeonatos, menu);
MenuItem item = menu.findItem(R.id.notificaciones);
item.setChecked(false);
return super.onCreateOptionsMenu(menu);
}
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
MenuItem checkable = menu.findItem(R.id.notificaciones);
checkable.setChecked(false);
return super.onPrepareOptionsMenu(menu);
}
#RequiresApi(api = Build.VERSION_CODES.KITKAT)
#Override
public boolean onOptionsItemSelected(#NonNull MenuItem item) {
switch (item.getItemId()){
case R.id.notificaciones:
if (item.isChecked()){
myRef.update("notificacion", false);
item.setChecked(false);
item.setIcon(R.drawable.ic_notifications_off_black_24dp);
Toast.makeText(this, "Notificaciones Desactivadas para este campeonato", Toast.LENGTH_LONG).show();
}else{
myRef.update("notificacion", true);
item.setChecked(true);
item.setIcon(R.drawable.ic_notifications_active_black_24dp);
Toast.makeText(this, "Notificaciones Activadas para este campeonato", Toast.LENGTH_LONG).show();
}
return true;
}
return super.onOptionsItemSelected(item);
}
First you need to implement Shared Preferences, as you mentioned
private String sharedPrefFile = "your Shared Preferences Name";
private String NOTIFICATION_KEY = "notification_key";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mPreferences = getSharedPreferences(sharedPrefFile, MODE_PRIVATE);
...
}
Then, in your onOptionsItemSelected, you need to save user action to preference
public boolean onOptionsItemSelected(#NonNull MenuItem item) {
switch (item.getItemId()){
case R.id.notificaciones:
if (item.isChecked()){
// Add this line
SharedPreferences.Editor preferencesEditor = mPreferences.edit();
preferencesEditor.putBoolean(NOTIFICATION_KEY, true);
preferencesEditor.apply();
myRef.update("notificacion", false);
item.setChecked(false);
item.setIcon(R.drawable.ic_notifications_off_black_24dp);
Toast.makeText(this, "Notificaciones Desactivadas para este campeonato", Toast.LENGTH_LONG).show();
}else{
// Add this line
SharedPreferences.Editor preferencesEditor = mPreferences.edit();
preferencesEditor.putBoolean(NOTIFICATION_KEY, false);
preferencesEditor.apply();
myRef.update("notificacion", true);
item.setChecked(true);
item.setIcon(R.drawable.ic_notifications_active_black_24dp);
Toast.makeText(this, "Notificaciones Activadas para este campeonato", Toast.LENGTH_LONG).show();
}
return true;
}
return super.onOptionsItemSelected(item);
}
Lastly, load the preference everytime activity is destroyed in onPrepareOptionsMenu
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
MenuItem checkable = menu.findItem(R.id.notificaciones);
String isNotificationClicked = mPreferences.getBoolean(NOTIFICATION_KEY, false);
checkable.setChecked(isNotificationClicked);
return super.onPrepareOptionsMenu(menu);
}

Getting error: Unable to Instantiate Activity

I have been following this tutorial: http://developer.android.com/guide/topics/ui/menus.html#CAB. However, when I run the application, I get an error:
java.lang.RuntimeException:
Unable to instantiate activity
ComponentInfo{com.example.ayushi.chaseyourdream/com.example.ayushi.chaseyourdream.MainActivity}:
java.lang.InstantiationException: can't instantiate class
com.example.ayushi.chaseyourdream.MainActivity
Here's my MainActivity. My application was working completely fine before I added code between label 1 and `label 2'.
public abstract class MainActivity extends ActionBarActivity implements AbsListView.MultiChoiceModeListener{
DbHelper db;
ListView myList;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
db = new DbHelper(this);
myList = (ListView) findViewById(R.id.newList);
loadData();
// LABEL 1
myList.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
myList.setMultiChoiceModeListener(new AbsListView.MultiChoiceModeListener() {
#Override
public void onItemCheckedStateChanged(ActionMode mode, int position,
long id, boolean checked) {
// Here you can do something when items are selected/de-selected,
// such as update the title in the CAB
}
#Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
// Respond to clicks on the actions in the CAB
switch (item.getItemId()) {
case R.id.menu_delete:
// deleteSelectedItems();
mode.finish(); // Action picked, so close the CAB
return true;
default:
return false;
}
}
#Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
// Inflate the menu for the CAB
MenuInflater inflater = mode.getMenuInflater();
inflater.inflate(R.menu.context_main, menu);
return true;
}
public void onDestroyActionMode(ActionMode mode) {
// Here you can make any necessary updates to the activity when
// the CAB is removed. By default, selected items are deselected/unchecked.
}
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
// Here you can perform updates to the CAB due to
// an invalidate() request
return false;
}
});
// LABEL 2
}
public void onResume()
{
super.onResume();
loadData();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
public void loadData()
{
Cursor cursor = null;
try {
cursor = db.fetchData();
}
catch(NullPointerException e)
{
e.printStackTrace();
}
ListAdapter myAdapter = new SimpleCursorAdapter(this, R.layout.tasks,
cursor,
new String[]{db._ID, db.COLUMN_1, db.COLUMN_2},
new int[]{R.id.idnum, R.id.c1, R.id.c2}, 0);
myList.setAdapter(myAdapter);
}
public void addNew(View v)
{
Intent intent = new Intent(this,AddActivity.class);
startActivity(intent);
}
}
EDIT 1: this line
public class MainActivity extends ActionBarActivity implements AbsListView.MultiChoiceModeListener{
showed me an error in Android Studio, and when I clicked Alt + Enter, it showed me two options: Make the class abstract, or implement its methods.
The first option gave me the initial problem, so now I went for option 2. Here are the additional methods implemented :
#Override
public void onItemCheckedStateChanged(ActionMode mode, int position, long id, boolean checked) {
}
#Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
return false;
}
#Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
return false;
}
#Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
return false;
}
#Override
public void onDestroyActionMode(ActionMode mode) {
}
Now, my doubt is: these are exactly the same methods in between LABEL 1 and LABEL 2, and erasing any one set will lead to errors. What should I do?
You are getting this error: Unable to instantiate activity because you made your activity abstract. Remove that and implement the methods of AbsListView.MultiChoiceModeListenerinterface.
When you're implementing an Interface so you have to implement all the methods you have listed. If you don't know what to do with method you don't use just leave them as they are.
Now, my doubt is: these are exactly the same methods in between LABEL 1 and LABEL 2, and erasing any one set will lead to errors. What should I do?
You shouldn't have two of the same. Try using #Override annotation on the methods you implemented.

onprepareoptionsmenu was called by default

I got a need to change the menu items dynamically during a click event of menu items.
So I implemented onOptionsItemSelected in an activity.
public class ResultActivity extends Activity {
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_main_actions, menu);
return true;
}
}
and i'm calling invalidateOptionsMenu in the onOptionsItemSelected method which inturn should call the onPrepareOptionsMenu
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
switch (id){
case R.id.action_group: {
invalidateOptionsMenu();
break;
}
}
}
Also, I am trying to remove one item from menu in onPrepareOptionsMenu method.
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
Log.d(TAG,"In onPrepareOptionsMenu");
menu.removeItem(R.id.action_group);
Log.d(TAG,"Group icon is removed");
return super.onPrepareOptionsMenu(menu);
}
The problem is, item is deleted during the launch of activity rather than wait until corresponding menu item is clicked.
Can someone tell what the problem is.. TIA
The problem is that onPrepareOptionsMenu(Menu) gets called anyway, anytime your menu needs to be shown or reloaded. That includes calls coming from invalidateOptionsMenu(), but also from the Activity being created.
You could, for example, check for a boolean state before actually removing the item.
public boolean mRemoveItem;
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
switch (id){
case R.id.action_group: {
mRemoveItem = true;
invalidateOptionsMenu();
break;
}
}
}
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
if (mRemoveItem) {
menu.removeItem(R.id.action_group);
}
return super.onPrepareOptionsMenu(menu);
}
According to your needs, you will need to set mRemoveItem back to false at some point in your code.

How to get menu item id on action bar when other menu item clicked

So I have menu items on action bar. on onOptionsItemSelected, I want to change the menu items images.
Here's my code
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle presses on the action bar items
switch (item.getItemId()) {
case R.id.todaySched:{
viewTodaySched();
item.setIcon(R.drawable.calendarselected);
infoLog=(MenuItem)findViewById(R.id.infoLog);
infoLog.setIcon(R.drawable.book);
return true;}
case R.id.infoLog:{
viewInfoLog();
item.setIcon(R.drawable.bookselected);
todaySched=(MenuItem)findViewById(R.id.todaySched);
todaySched.setIcon(R.drawable.calenderselected);
return true;}
default:
return super.onOptionsItemSelected(item);
}
}
But the icon won't change when I clicked it, and I got run time error.
e.g: When I click todaySched icon, It seems like I can't get the infoLog item id.
My LogCat: LogCat
As per you logcat, you getting class cast exception and you have used sharlockactionbar.
so try and check if you have imported the correct MenuItem and Menu which should like this:
import com.actionbarsherlock.view.MenuItem;
and
import com.actionbarsherlock.view.Menu;
instead of
import android.view.MenuItem;
and
import android.view.Menu;
Edit:
Here is how you can change both icons on just a single click:
private Menu menu;
private MenuItem item1, item2;
Boolean original = true;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getSupportMenuInflater().inflate(R.menu.menu, menu);
this.menu = menu;
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.todaySched) {
update();
} else if (id == R.id.infoLog) {
update();
}
return true;
}
private void update() {
item1 = menu.findItem(R.id.todaySched);
item2 = menu.findItem(R.id.infoLog);
if (original) {
item1.setIcon(getResources().getDrawable(
android.R.drawable.ic_menu_search));
item2.setIcon(getResources().getDrawable(
android.R.drawable.ic_menu_report_image));
original = false;
} else if (!original) {
item1.setIcon(getResources().getDrawable(
android.R.drawable.ic_menu_my_calendar));
item2.setIcon(getResources().getDrawable(
android.R.drawable.ic_menu_info_details));
original = true;
}
}
checked and is working. Now use it as per your requirement..
Cheers....
Every time you want to make changes to your items in the Action bar you have to call the function
invalidateOptionsMenu(). Then you override the method public boolean onPrepareOptionsMenu(Menu menu), there you get your menu items and you can set icons, create new actions or remove them. Hope it helps.

finish activity from an other one

I have an activity for my menu events:
public class GlobalMenu extends Activity{
private MenuItem item;
public boolean event(MenuItem item){
this.item = item;
// Handle item selection
switch (this.item.getItemId()) {
case R.id.menu_stop:
finish();
return true;
}
return true;
}
}
And I use it like this
GlobalMenu gm = new GlobalMenu();
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
return gm.event(item);
}
But the finish didn't work, I think I need to link it with an application but I don't know how to do
Thanks
First of All, You can't make a Object or Instance of Android Activity.
like this
GlobalMenu gm = new GlobalMenu();
You have to pass a Context of GlobalMenu Activity to other Activity or Class and then call finish on this.
Like,
((GlobalMenu)mContext).finish();
Here mContext is a reference of GlobalMenu Activity.

Categories

Resources