Going by the guidelines and conventions in the StopWatch GDK example, I cannot get the MenuOption to open.
My app compiles and able to output the embedded log statement of ""####TEST", but no OptionsMenu appears.
https://developers.google.com/glass/develop/gdk/ui/immersion-menus
This is the method in the Android API for menu's.
openOptionsMenu();
I'm basing the code off of stopwatch's conventions:
/*
*
* Menu Code
*/
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
}
#Override
public boolean onKeyDown(int keycode, KeyEvent event) {
if (keycode == KeyEvent.KEYCODE_DPAD_CENTER) {
openOptionsMenu();
Log.v("####","TEST");
return true;
}
return false;
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu, menu);
return true;
}
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
// Implement if needed
return false;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle item selection. Menu items typically start another
// activity, start a service, or broadcast another intent.
switch (item.getItemId()) {
case R.id.stop:
//startActivity(new Intent(this, StopStopWatchActivity.class));
Log.v("####","HI");
return true;
case R.id.read_aloud:
Log.v("####","READ_ALOUD");
return true;
default:
return super.onOptionsItemSelected(item);
}
}
//open the optionsMenu to make sure
#Override
public void openOptionsMenu() {
super.openOptionsMenu();
}
the XML for menu
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="#+id/read_aloud"
android:title="#string/read_aloud"
android:icon="#drawable/ic_launcher"/>
<item
android:id="#+id/stop"
android:title="#string/stop"
android:icon="#drawable/ic_launcher"/>
</menu>
edit: I discovered what my issue was. I commented out the prepared option which was returning false, which caused my options to not engaged.
Here in reference is a good example to do it properly.
Thanks #w9jds for his help.
I can't find what the issue was in my code, but here is a working example solutions with the correct menu creation and one tap.
https://github.com/w9jds/GlassMenuExample
What the program does is show a glass app that renders a hello world card. On Tap the card creates an options menu that has the 'share' option.
This functionality is a lot similar to how cards work on the timeline.
Menu - Main.Xml
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="#+id/share_menu_item"
android:title="#string/share_label"
android:icon="#drawable/ic_share_50"/>
</menu>
Main Activity
package com.example.glassmenuexample;
import com.google.android.glass.app.Card;
import com.google.android.glass.media.Sounds;
import com.google.android.glass.touchpad.Gesture;
import com.google.android.glass.touchpad.GestureDetector;
import android.media.AudioManager;
import android.os.Bundle;
import android.app.Activity;
import android.content.Context;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
public class MainActivity extends Activity
{
private GestureDetector mGestureDetector;
private AudioManager maManager;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
//initialize the audio manager
maManager = (AudioManager) getSystemService(this.AUDIO_SERVICE);
//create gesture listener
mGestureDetector = createGestureDetector(this);
//create a new card for the view
Card cView = new Card(this);
//set the text of the card to the hello world string
cView.setText(R.string.hello_world);
//set the card as the content view
setContentView(cView.toView());
}
#Override
public boolean onCreateOptionsMenu(Menu menu)
{
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
private GestureDetector createGestureDetector(Context context)
{
GestureDetector gdDetector = new GestureDetector(context);
//Create a base listener for generic gestures
gdDetector.setBaseListener( new GestureDetector.BaseListener()
{
#Override
public boolean onGesture(Gesture gesture)
{
if (gesture == Gesture.TAP)
{
//play the tap sound
maManager.playSoundEffect(Sounds.TAP);
//open the menu
openOptionsMenu();
return true;
}
return false;
}
});
return gdDetector;
}
#Override
public boolean onGenericMotionEvent(MotionEvent event)
{
if (mGestureDetector != null)
return mGestureDetector.onMotionEvent(event);
return false;
}
#Override
public boolean onOptionsItemSelected(MenuItem item)
{
// Handle item selection. Menu items typically start another
// activity, start a service, or broadcast another intent.
switch (item.getItemId())
{
case R.id.share_menu_item:
//do something on menu item click
return true;
default:
return super.onOptionsItemSelected(item);
}
}
}
Related
I have a short list of items in my activity. I want to add a button somewhere in the UI to switch to edit mode for the list of items. I'm new to Android programming and even to using Android devices. I'm accustomed to iOS. In an iOS table, there is usually an "Edit" button in the top right of the navigation bar. What is the standard way in Android to switch to edit mode in a list? (Is there a standard way?)
When in edit mode, I plan to show edit (e.g. pencil) and delete (e.g. 'X') buttons on the right side of each list item's view.
I don't think it is related but just in case...I'm not using RecyclerView or anything fancy. Just LinearLayout. The list is so short I don't think there is a performance reason to use a recycler. Is there any other reason to use a RecyclerView?
Thanks!
You need to action mode. Example:
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.ActionMode;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
public class MainActivity extends Activity {
ActionMode actionMode;
final String LOG_TAG = "myLogs";
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
public void onClick(View v) {
if (actionMode == null)
actionMode = startActionMode(callback);
else
actionMode.finish();
}
private ActionMode.Callback callback = new ActionMode.Callback() {
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
mode.getMenuInflater().inflate(R.menu.context, menu);
return true;
}
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
return false;
}
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
Log.d(LOG_TAG, "item " + item.getTitle());
return false;
}
public void onDestroyActionMode(ActionMode mode) {
Log.d(LOG_TAG, "destroy");
actionMode = null;
}
};
// ...
}
I am following a tutorial 11. Exercise: Using the contextual action mode
But I am having this error :
mActionMode = Display.this.startActionMode(mActionModeCallback);
view.setSelected(true);
Error: The method startActionMode(ActionMode.Callback) in the type Activity is not applicable for the arguments (ActionMode.Callback)
I checked this stackoverflow answer
they said to add
ActionBarActivity activity=(ActionBarActivity)getActivity();
activity.startSupportActionMode(modeCallBack);
I had this error
The method getActivity() is undefined for the type Display
what I am doing wrong ? the below is my code.
package com.example.sqlfirst;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBar.Tab;
import android.support.v7.app.ActionBarActivity;
import android.util.Log;
import android.view.Menu;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.NavUtils;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.view.ActionMode;
import android.view.ActionMode.Callback;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.Toast;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.GridView;
public class Display extends ActionBarActivity {
private final static String TAG = "MainActivity";
protected Object mActionMode;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.grid_main);
//have to use getSupportActionBar from android.support.v7.app
// ActionBar actionBar = getSupportActionBar();
//getActionBar().setDisplayHomeAsUpEnabled(true);
ActionBarActivity activity=(ActionBarActivity)getActivity();
activity.startSupportActionMode(modeCallBack);
View view = findViewById(R.id.gridview);
view.setOnLongClickListener(new View.OnLongClickListener() {
// called when the user long-clicks on someView
public boolean onLongClick(View view) {
if (mActionMode != null) {
return false;
}
// start the CAB using the ActionMode.Callback defined above
mActionMode = Display.this.startActionMode(mActionModeCallback);
view.setSelected(true);
return true;
}
});
GridView gridview = (GridView) findViewById(R.id.gridview);
gridview.setAdapter(new ImageAdapter(this));
gridview.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
// Send intent to SingleViewActivity
Intent i = new Intent(getApplicationContext(), SingleViewActivity.class);
// Pass image index
i.putExtra("id", position);
startActivity(i);
} });
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.activity_main_actions, menu);
return super.onCreateOptionsMenu(menu);
}
public boolean onOptionsItemSelected(MenuItem item)
{
super.onOptionsItemSelected(item);
switch (item.getItemId()){
case R.id.ic_action_person:
Toast.makeText(this, "Create a new account please", Toast.LENGTH_SHORT).show();
Intent intent = new Intent(this, Register.class);
startActivity(intent);
return true;
case R.id.ic_action_search:
Toast.makeText(this, "Search for new images", Toast.LENGTH_SHORT).show();
Intent isearch= new Intent(this,Search.class);
startActivity(isearch);
return true;
case R.id.ic_action_picture:
Toast.makeText(this, "Search for new photos", Toast.LENGTH_SHORT).show();
Intent iphotos= new Intent(this,Display.class);
startActivity(iphotos);
return true;
}
return true;
}
private ActionMode.Callback mActionModeCallback = new ActionMode.Callback() {
// Called when the action mode is created; startActionMode() was called
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
// inflate a menu resource providing context menu items
MenuInflater inflater = mode.getMenuInflater();
// assumes that you have "contexual.xml" menu resources
inflater.inflate(R.menu.activity_main_actions, menu);
return true;
}
// called each time the action mode is shown. Always called after
// onCreateActionMode, but
// may be called multiple times if the mode is invalidated.
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
return false; // Return false if nothing is done
}
// called when the user selects a contextual menu item
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
switch (item.getItemId()) {
case R.id.ic_action_picture:
Toast.makeText(Display.this, "Selected menu",
Toast.LENGTH_LONG).show();
mode.finish(); // Action picked, so close the CAB
return true;
default:
return false;
}
}
// called when the user exits the action mode
public void onDestroyActionMode(ActionMode mode) {
mActionMode = null;
}
};
}
Your Display class is extending ActionBarActivity, that means that it´s an Activity so there´s no need to use getActivity(), you can directly make use of the methods like this:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
/* this method is available within your ActionBarActivity*/
startSupportActionMode(modeCallBack);
setContentView(R.layout.grid_main);
// The rest of your code comes here
}
I have made an app with a lot of buttons and activities. I'm having trouble though understanding how to start a new activity through a button that is in my menu (when the menu button is clicked on phone) (inflatable menu). This is my code for the menu connected to my activity:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="#+id/item1" android:title="#string/menu_home"></item>
</menu>
Here is my activities in Java:
package com.gmail.derekcraigsmith.nanaimobus;
import android.os.Bundle;
import android.app.Activity;
import android.content.ClipData.Item;
import android.content.Intent;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.PopupMenu;
import android.widget.PopupMenu.OnMenuItemClickListener;
public class Route1TimesCcMonfriAActivity extends Activity implements
OnMenuItemClickListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.route1_times_cc_monfri_a);
}
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.route1_times_cc_monfri_a, menu);
return true;
}
#Override
public boolean onMenuItemClick(MenuItem item) {
// TODO Auto-generated method stub
return false;
}
}
int id = item.getItemId();
switch (id) {
case R.id.your_menu_item_id : {
startActivity(new Intent(start_activity, next_activity));
}
where start activity is your main activity and next_activity is the activity you want to start.
Give a look on my blog here for more info.
activity_main.xml in menu folder
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:id="#+id/next"
android:title="Next" />
</menu>
In your activity inflate the menu
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, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item)
{
switch (item.getItemId()) //get the id which is an int
{
case R.id.next: // check if its the menu item next selected
// Single menu item is selected do something
// Ex: launching new activity/screen or show alert message
Toast.makeText(MainActivity.this, "Next Selected", Toast.LENGTH_SHORT).show();
startActivity(new Intent(MainActivity.this,secondAct.class));//start activity
break;
default:
return super.onOptionsItemSelected(item);
}
}
I'm using SlidingMenu implementation in my app, I want the android.R.id.home button to open/close the side menu. Inside the Activity I use Fragment to display information. I want the home button to act as a back button.
The problem is that Activity's onOptionsItemSelected in Activity get invoked before the Fragment's one. Is this ordinary behavior? Or am I doing something wrong?
I'm using ActionBarSherlock in my project as well, but I don't think that matters tho.
Is implementing my own interface the only solution here?
Exactly last night I was struggling with this but eventually managed to solve it, so here is my solution:
These are the relevant parts from MainActivity:
import com.actionbarsherlock.app.ActionBar;
import com.actionbarsherlock.app.SherlockFragmentActivity;
import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuItem;
public class MainActivity extends SherlockFragmentActivity {
.
.
.
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getSupportMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item){
return super.onOptionsItemSelected(item);
}
}
Here is my menu main.xml:
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="#+id/action_settings"
android:orderInCategory="100"
android:showAsAction="never"
android:title="#string/action_settings"/>
</menu>
and here is my Fragment:
import com.actionbarsherlock.app.SherlockFragment;
import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuInflater;
import com.actionbarsherlock.view.MenuItem;
public class TestFrag extends SherlockFragment {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
.
.
setHasOptionsMenu(true);
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
menu.add(Menu.NONE, android.R.id.home, 100, "Home");
}
#Override
public boolean onOptionsItemSelected(MenuItem item){
switch(item.getItemId())
{
case android.R.id.home:
// Do whatever you want when Home is clicked.
Toast.makeText(getSherlockActivity(), "Home is clicked", Toast.LENGTH_SHORT).show();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
}
This is what I am getting:
I hope this helps in any way.
Ended up moving the onOptionsItemSelected from Activity to my base Fragment class instead.
Inside base fragment class, I have these:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch(item.getItemId()){
case android.R.id.home:
// Toggle slide menu
getBaseActivity().getSlidingMenu().toggle(true);
break;
}
return super.onOptionsItemSelected(item);
}
protected boolean useHomeAsBack(MenuItem item){
switch(item.getItemId()){
case android.R.id.home:
Log.v(TAG, "useHomeAsBack - onOptionsItemSelected");
getSherlockActivity().onBackPressed();
return true;
}
return false;
}
Also call setHasOptionsMenu(true); inside onAttach as well.
Inside the actual Fragment that I wanted to use back instead, I have:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if(useHomeAsBack(item)) return true;
return super.onOptionsItemSelected(item);
}
Still, I'd expect Fragment's onOptionsItemSelected to be able to override or take priority over Activity's. Wonder what the reason for that would be.
I'm using the ActionBarCompat sample that comes with the SDK. My activity used to have menu items that would change based on the state of the activity. I would modify the menu like so in onPrepareOptionsMenu():
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
menu.clear();
if (some condition) {
menu.add(...);
}
...
}
In ICS however, I believe we're supposed to modify menu items by calling invalidateOptionsMenu() and then our onCreateOptionsMenu() is called again. Here we can remove menu items (not add them). So then we might end up with something like this:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
if (SDK >= 11) {
// full menu is reloaded from xml every time we
// called invalidateOptionsMenu(), so we have a
// fresh menu here again.
}
}
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
if (SDK >= 11) {
// we can remove items depending on our state,
// but not add any, that's ok.
}
else {
// we only have our original menu instance here,
// so if we previously had called menu.remove(),
// we need to call menu.add() here:
if (foo == true) {
menu.remove(R.id.menu_item_foo);
} else {
menu.add(R.id.menu_item_foo, ...);
}
}
}
This seems a bit awkward,
Thanks
Demo project
https://github.com/AlienAsRoger/CourtDeadlines
This is how i solved it:
In ActionBarHelperBase.java of actionbarcompat project
...
private View addActionItemCompatFromMenuItem(final MenuItem item) {
final int itemId = item.getItemId();
....
The creator of this class copy properties of object, but didn't copy the id of item, so it is impossible to find it later with fiven id.
So i added it in that method:
...
actionButton.setId(itemId);
...
and in the same class i just use:
#Override
public void hideMenuItemById(int id, boolean show){
getActionBarCompat().findViewById(id).setVisibility(show? View.VISIBLE: View.GONE);
}
Hope it helps You.
UPDATES:
in ActionBarActivity from ActionBarCompat sample:
package com.chess.ui.activities;
import actionbarcompat.ActionBarActivity;
import actionbarcompat.ActionBarHelper;
import android.app.ActionBar;
import android.app.SearchManager;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.widget.SearchView;
import com.chess.R;
import com.chess.lcc.android.LccHolder;
public abstract class CoreActivityActionBar2 extends ActionBarActivity {
protected boolean showActionSearch;
protected boolean showActionSettings;
protected boolean showActionNewGame;
protected boolean showActionRefresh;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH && getActionBar() != null) {
getActionBar().setDisplayOptions(ActionBar.DISPLAY_HOME_AS_UP
| ActionBar.DISPLAY_USE_LOGO
| ActionBar.DISPLAY_SHOW_HOME
| ActionBar.DISPLAY_SHOW_TITLE);
}
}
#Override
protected void onStart() {
if (HONEYCOMB_PLUS_API) {
adjustActionBar();
}
super.onStart();
}
#Override
protected void onResume() {
super.onResume();
if (!HONEYCOMB_PLUS_API) {
adjustActionBar();
}
}
private void adjustActionBar() {
getActionBarHelper().showMenuItemById(R.id.menu_settings, showActionSettings);
getActionBarHelper().showMenuItemById(R.id.menu_new_game, showActionNewGame);
getActionBarHelper().showMenuItemById(R.id.menu_refresh, showActionRefresh);
getActionBarHelper().showMenuItemById(R.id.menu_search, showActionSearch);
getActionBarHelper().showMenuItemById(R.id.menu_singOut, LccHolder.getInstance(this).isConnected());
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater menuInflater = getMenuInflater();
menuInflater.inflate(R.menu.sign_out, menu);
getActionBarHelper().showMenuItemById(R.id.menu_singOut, LccHolder.getInstance(this).isConnected(), menu);
getActionBarHelper().showMenuItemById(R.id.menu_search, showActionSearch, menu);
getActionBarHelper().showMenuItemById(R.id.menu_settings, showActionSettings, menu);
getActionBarHelper().showMenuItemById(R.id.menu_new_game, showActionNewGame, menu);
getActionBarHelper().showMenuItemById(R.id.menu_refresh, showActionRefresh, menu);
if (HONEYCOMB_PLUS_API) {
// Get the SearchView and set the searchable configuration
SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
SearchView searchView = (SearchView) menu.findItem(R.id.menu_search).getActionView();
searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
}
return super.onCreateOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
backToHomeActivity();
break;
case R.id.menu_settings:
startActivity(new Intent(this, PreferencesScreenActivity.class));
break;
}
return super.onOptionsItemSelected(item);
}
public ActionBarHelper provideActionBarHelper() {
return getActionBarHelper();
}
}
where showActionSettings is a boolean flag to switch visibility