How to invoke Fragment's onOptionItemSelected before Activity's? - android

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.

Related

Android Tutorial - Adding Action Bar, duplicate class?

I'm trying to create the Action Bar by following the Android Studio tutorial. I am familiar with VBA, C++, and Python, but this is the first time I've ventured into an App, which uses java, xml, etc. in one. I say that because I think I've misplaced (or misnamed) something in my code, as when I try to run this, I get the error error: duplicate class: com.example.batman.myfirstapp.MyActivity.
I don't understand how it's a duplicate, I only have one "MyActivity.java", so am thinking that I can't do more than one public class MyActivity extends ... per .java file?
Here's what I have (please let me know if I need to include other code):
MyActivity.java
package com.example.batman.myfirstapp;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.EditText;
import android.support.v7.app.*;
public class MyActivity extends ActionBarActivity{
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu items for use in the action bar
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main_activity_actions, menu);
return super.onCreateOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle presses on the action bar items
switch (item.getItemId()) {
case R.id.action_search:
// openSearch();
return true;
case R.id.action_settings:
// openSettings();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
}
public class MyActivity extends AppCompatActivity {
public final static String EXTRA_MESSAGE = ".com.batman.myfirstapp.MESSAGE";
/**
* Called when the user clicks the Send button
*/
public void sendMessage(View view) {
Intent intent = new Intent(this, DisplayMessageActivity.class);
EditText editText = (EditText) findViewById(R.id.edit_message);
String message = editText.getText().toString();
intent.putExtra(EXTRA_MESSAGE, message);
startActivity(intent);
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_display_message);
// getSupportActionBar().setDisplayHomeAsUpEnabled(true);
// If your minSdkVersion is 11 or higher, instead use:
getActionBar().setDisplayHomeAsUpEnabled(true);
}
}
main_activity_actions.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:myfirstapp="http://schemas.android.com/apk/res-auto">
<!-- Search, should appear as action button -->
<item android:id="#+id/action_search"
android:icon="#drawable/ic_action_search"
android:title="#string/action_search"
myfirstapp:showAsAction="ifRoom" />
<!-- Settings, should always be in the overflow -->
<item android:id="#+id/action_settings"
android:title="#string/action_settings"
myfirstapp:showAsAction="never" />
</menu>
Again, I'm not sure what other files (strings.xml, DisplayMessageActivity.java, etc.) would be helpful to debug the above, so let me know what else I can include.
Thank you for any advice/help!
You're intuition is correct! You can only have one MyActivity class in your file, here's what it might look like:
public class MyActivity extends ActionBarActivity {
public final static String EXTRA_MESSAGE = ".com.batman.myfirstapp.MESSAGE";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_display_message);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main_activity_actions, menu);
return super.onCreateOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_search:
return true;
case R.id.action_settings:
return true;
default:
return super.onOptionsItemSelected(item);
}
}
private void sendMessage(View view) {
Intent intent = new Intent(this, DisplayMessageActivity.class);
EditText editText = (EditText) findViewById(R.id.edit_message);
String message = editText.getText().toString();
intent.putExtra(EXTRA_MESSAGE, message);
startActivity(intent);
}
}
Your assumption is correct. In your .java file you have two classes named MyActivity. You can only have one.

Error:(9, 30) error: package android.support.v4.app does not exist

I'm using Studio 0.8.9
I have an android-sdks\extras\android\support\v4\android-support-v4.jar
but I still run into the import issue.
I'm using NavUtils.navigateupfromsametask method.
what I'm trying to achieve is simply to use the back button to get to my previous activity.
is it the right way of doing?
when I'm using my email app (for ex yahoo) I'm using the back button to get back to my inbox when I'm viewing an email.
how do they do it? using activities and the back button?
I'm using the standard code:
package com.example.bernard.test;
import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import java.util.NavigableMap;
import android.support.v4.app.NavUtils;
public class Statistic extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_statistic);
getActionBar().setDisplayHomeAsUpEnabled(true);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.statistic, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
switch (id)
{
case android.R.id.home:
NavUtils.navigateUpFromSameTask(this);
onBackPressed();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
#Override
public void onBackPressed(){
super.onBackPressed();
}
}

Creating Options Menus for Google Glass

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);
}
}
}

How do I create a clickable item in menu to open a new activity?

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);
}
}

onOptionsSelected not working at all

I did this menu and when I click a menu item nothing happens, it doesnt't even shows the default toast! Maan I dont know what is going on!
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="#+id/menuLapiz" android:alphabeticShortcut="l"
android:icon="#drawable/pencil" />
<item android:id="#+id/menuCirculo" android:alphabeticShortcut="c"
android:icon="#drawable/circulo" />
<item android:id="#+id/menuTriangulo" android:alphabeticShortcut="t"
android:icon="#drawable/triangulo" />
<item android:id="#+id/menuCuadrado" android:alphabeticShortcut="s"
android:icon="#drawable/cuadrado" /> </menu>
DrawActivity.java
... Here I got the menu onOptionsSelected which appereantly is not working
import android.app.Activity
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Toast; `
public class DrawActivity extends Activity {
DrawView drawView;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Set full screen view
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
// No Title
requestWindowFeature(Window.FEATURE_NO_TITLE);
drawView = new DrawView(this);
setContentView(drawView);
drawView.requestFocus();
}
#Override
public boolean onCreateOptionsMenu(Menu menu){
super.onCreateOptionsMenu(menu);
MenuInflater awesome = getMenuInflater();
awesome.inflate(R.menu.main_menu, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item){
switch(item.getItemId()){
case R.id.menuLapiz:
Toast.makeText(this, "This is a toast", Toast.LENGTH_LONG);
return true;
default:
Toast.makeText(this, "This is a toast", Toast.LENGTH_LONG);
return true;
}
}}
I have no idea why the onOptionsItemSelected(MenuItem item) method is not working I already tried without the S of Options because I read that suggestion in other post but it did not work.
I'm new to android programming so I really have no clue of what is going on .. any help will be appreciated, thanks a lot!! pd: let me know if you want to see the DrawView.java class
Add a return true; to the end of each case
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.mAdd:
startActivity(new Intent("com.example.ADD"));
return true;
case R.id.mAbout:
startActivity(new Intent("com.example.ABOUT"));
return true;
}
return false;
}
EDIT: toast code
Toast t = Toast.makeText(getApplicationContext(),
"This is a toast",
Toast.LENGTH_SHORT);
t.show();

Categories

Resources