I've been using ABS 4.0 with two MenuItems in one of my apps, but have discovered a little error: When pressing the second MenuItem, it does exactly the same as the first one...
I've tried just about everything I can think of, but it isn't working. I've altered onOptionItemSelected, as I thought that was the method I need to edit.
EDIT:
I've been looking at #Ollie's suggestions, but neither LogCat nor Debug is showing weird things. Maybe it's in some other part of the code, or a declaration for ABS? Here's the entire code, if you could look through it, that would be great!
The code for the whole Activity, as it's maybe in some other place?
package bas.sie.Antonius;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import com.actionbarsherlock.app.ActionBar;
import com.actionbarsherlock.app.SherlockActivity;
import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuItem;
public class TeacherInfo extends SherlockActivity {
String URLhome;
String Info;
String TeacherAb;
TextView mTxtvInfo;
Button mBtnTeacherStSchedule;
Button mBtnTeacherDaySchedule;
private static String mainUrl = "http://www.carmelcollegegouda.nl/site_ant/";
private static String endUrl = ".htm";
private static String[] myUrls = { "roosters/dagroosters/Doc_V1_",
"roosters/standaardroosters/Doc1_" };
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.contactinfo);
setTitle("Over deze leraar");
ActionBar actionBar = getSupportActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
mTxtvInfo = (TextView) findViewById(R.id.TxtvTeacher);
Intent startingIntent = getIntent();
Info = startingIntent.getStringExtra("contact");
mTxtvInfo.setText(Info);
Intent startingIntent1 = getIntent();
TeacherAb = startingIntent1.getStringExtra("abbrev");
mBtnTeacherDaySchedule = (Button) findViewById(R.id.btnTeacherDaySchedule);
mBtnTeacherStSchedule = (Button) findViewById(R.id.btnTeacherStSchedule);
mBtnTeacherDaySchedule.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
URLhome = makeUrl(0);
Intent i = new Intent(TeacherInfo.this, MyWebView.class);
i.putExtra("home", URLhome);
startActivityForResult(i, 0);
}
});
mBtnTeacherStSchedule.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
URLhome = makeUrl(1);
Intent i = new Intent(TeacherInfo.this, MyWebView.class);
i.putExtra("home", URLhome);
startActivityForResult(i, 0);
}
});
}
private String makeUrl(int index) {
String s = mainUrl + myUrls[index] + TeacherAb + endUrl;
return s;
}// makeurl
#Override
public boolean onCreateOptionsMenu(Menu menu) {
menu.add("Instellingen")
.setIcon(R.drawable.ic_settings)
.setShowAsAction(
MenuItem.SHOW_AS_ACTION_IF_ROOM
| MenuItem.SHOW_AS_ACTION_WITH_TEXT);
menu.add("Over de app")
.setIcon(R.drawable.ic_about)
.setShowAsAction(
MenuItem.SHOW_AS_ACTION_IF_ROOM
| MenuItem.SHOW_AS_ACTION_WITH_TEXT);
return super.onCreateOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
Intent intent = new Intent(this, AntoniusActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
return true;
case R.id.settings:
Intent i = new Intent(this, About.class);
startActivity(i);
return true;
case R.id.about:
Intent about = new Intent(this, About.class);
startActivity(about);
return true;
default:
return super.onOptionsItemSelected(item);
}
}
}
I'm thinking that the problem is in the declaration of the menu items, but I don't see any problem there...
Could you take a look at my menu.xml? Posted here:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:id="#+id/settings"
android:icon="#drawable/ic_settings"
android:title="Instellingen"></item>
<item android:id="#+id/about"
android:icon="#drawable/ic_about"
android:title="Over de app"></item>
</menu>
Create the menu like this:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu, menu);
return super.onCreateOptionsMenu(menu);
}
Then use a switch statement to handle selections:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
// Do stuff
return true;
case R.id.menu_item_2:
// Do stuff
return true;
default:
return super.onOptionsItemSelected(item);
}
}
EDIT: Finally, you should do different things for each item, if you change the Intent target Activity to another, it'll do what you expect:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
// ... Stuff ...
case R.id.settings: // Settings item
Intent i = new Intent(this, About.class); // Start About.java Activity, but item says "settings"
// TODO: Change About to Settings?
i = new Intent(this, Settings.class);
startActivity(i);
return true;
case R.id.about: // About item
Intent about = new Intent(this, About.class); // Start About.java Activty
startActivity(about);
return true;
default:
return super.onOptionsItemSelected(item);
}
}
What I find odd is the way you create your menu.
You have defined menu layout it in a menu.xml, yet you do not reference this layout in a onCreateOptionMenu() method.
It should be something like this:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getSupportMenuInflater().inflate(R.menu.menu, menu);
return super.onCreateOptionsMenu(menu);
}
Pay attention to the getSupportMenuInflater() method which is used instead of getMenuInflater(). Why this must be so is somewhere in docemntation about android support library which in term is used by ActionBarSherlock library.
What you do is create menu in code programmatically by using a method menu.add() with a signature add(CharSequence). Nowhere it is in there that you give ItemId. I guess (and this is only a guess) android in that case assigns the same id to all items, something like zero or some other arbitrary number. You should use a method with a signature add(int, int, int,CharSequence) or add(int, int, int, int) as only those allow you to specify ItemId. So, both of your menu items have the same id. And this is (I guess again) the cause that they behave the same.
One more thing. Be careful that you use the correct substitute classes and methods from support library and ActionBarSherlock library.
Please let us know if this solved the problem as I am only running this in my head.
Related
Hello guys am trying to make user login and if he is not an admin I want some bottom navigation bar
hidden I want to hide item before activity showUp for user
I am sending a certain value from activation of the user login and I want to verify before the screen appears to the user if the value is equal to the user answers hide the icon
I tried to get to the icon id but I did not know the correct way to do that please help and thank you
#Override
protected void onStart() {
super.onStart();
BottomNavigationViewEx bottomNavigationViewEx = new BottomNavigationViewEx().findViewById(R.id.addproudactbtnbar).setVisibility(false);
}
my XML
<com.ittianyu.bottomnavigationviewex.BottomNavigationViewEx
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/bottm_navigation_menu"
android:background="#color/colorPrimary"
app:menu="#menu/bottm_navigation_menu"
>
</com.ittianyu.bottomnavigationviewex.BottomNavigationViewEx>
public void setupbottmnavigationview(){
BottomNavigationViewEx bottomnavigationviewex = findViewById(R.id.bottm_navigation_menu);
BottomNvigationViewHelper.botomnavigationview(bottomnavigationviewex);
BottomNvigationViewHelper.enebleactivty(Home.this , bottomnavigationviewex);
Menu menu = bottomnavigationviewex.getMenu();
MenuItem menuItem = menu.getItem(ATIVYTY_NUM);
menuItem.setChecked(true);
}
my navigation helper
public class BottomNvigationViewHelper {
public static void botomnavigationview (BottomNavigationViewEx bottomNavigationViewEx){
bottomNavigationViewEx.enableAnimation(false);
bottomNavigationViewEx.enableItemShiftingMode(false);
bottomNavigationViewEx.enableShiftingMode(false);
bottomNavigationViewEx.setTextVisibility(false);
}
public static void enebleactivty(final Context context , BottomNavigationViewEx viewEx){
viewEx.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
switch (item.getItemId()){
case R.id.homebtnbar:
Intent intent1 = new Intent(context, HomeScreenActivity.class);
context.startActivity(intent1);
break;
case R.id.profilebtnbar:
Intent intent2 = new Intent(context, ProfileScreenActivity.class);
context.startActivity(intent2);
break;
case R.id.searchusersbtnbar:
Intent intent3 = new Intent(context, SearchScreenActivity.class);
context.startActivity(intent3);
break;
case R.id.deleverybtnbar:
Intent intent4 = new Intent(context, DeleviryScreenActivity.class);
context.startActivity(intent4);
break;
case R.id.addproudactbtnbar:
Intent intent5 = new Intent(context, Addproudacts.class);
context.startActivity(intent5);
break;
}
return false;
}
});
}
}
You can inflate the menu programmatically based on the type of the user with
navigationView.getMenu().clear(); //clear old inflated items.
navigationView.inflateMenu(R.menu.new_navigation_drawer_items);
From this answer
I am trying to perform action when click on item in menu and I used switch case to loop over item id
I tried to remove break and tried to play with the code does not work and every time I click on any item in the menu it performs last method in the menu i.e. log out
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_all_users:
// complete later
case R.id.menu_account_setting:
Intent settingIntent = new Intent(MainActivity.this, SettingActivity.class);
startActivity(settingIntent);
finish();
case R.id.menu_log_out:
auth.signOut();
Intent loginIntent = new Intent(MainActivity.this , LoginActivity.class);
loginIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(loginIntent);
finish();
default:
break;
}
return super.onOptionsItemSelected(item);
}
Why you've removed break statement, try in this way :
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle item selection
switch (item.getItemId()) {
case R.id.menu_all_users:
return true;
case R.id.menu_account_setting:
Intent settingIntent = new Intent(MainActivity.this, SettingActivity.class);
startActivity(settingIntent);
finish();
return true;
case R.id.menu_log_out:
auth.signOut();
Intent loginIntent = new Intent(MainActivity.this , LoginActivity.class);
loginIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(loginIntent);
finish();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
Also cross check all id's are present in xml or not and you're properly inflating menu in onCreateOptionsMenu method.
I believe you are missing break statements in all cases except default.
Thank you guys I solved it using if statment instead of switch and it worked
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if(item.getItemId() == R.id.menu_all_users){
sendToAllUsers();
}else if(item.getItemId() == R.id.menu_account_setting){
GoToSetting();
}else if(item.getItemId() == R.id.menu_log_out){
Logout();
}
return super.onOptionsItemSelected(item);
This question already has answers here:
Android: Best way to share code between activities? [closed]
(2 answers)
Closed 4 years ago.
I have multiple activities sharing the same options menu so in my every activity, I am doing
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle item selection
switch (item.getItemId()) {
case R.id.settings:
Intent opensettings = new Intent(this, SettingsActivity.class);
startActivity(opensettings);
return true;
case R.id.help:
...others
default:
return super.onOptionsItemSelected(item);
}
}
Is there a way to share the above code amongst different activities?
I have tried adding a class
class MenuHelper{
Context ctx;
public MenuHelper(Context context){
ctx=context
}
public boolean openMenuItems(Menu item){
switch(item.getItemId()) //here .getItemId() doesnt work{
case R.id.settings: //R.id.settings not found
}
}
}
But am stuck in my helper class. How do I proceed so that in my different activities I only have to
MenuHelper menuitems = new MenuHelper(this);
menuitems.openMenuItems(menu)
You can have a BaseActivity where you can put the common implementation across your activities and then have other activities extend the BaseActivity
public class BaseActivity extends AppCompatActivity {
// Any other common methods
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle item selection
switch (item.getItemId()) {
case R.id.settings:
Intent opensettings = new Intent(this, SettingsActivity.class);
startActivity(opensettings);
return true;
case R.id.help:
...others
default:
return super.onOptionsItemSelected(item);
}
}
}
You can now create your activities extending BaseActivity:
public class MainActivity extends BaseActivity {
}
Why not just create a super class for your common Activities? If you create a super class, like so:
public class MySharedMenuActivity extends Activity {
#Override
public boolean onOptionsItemSelected(MenuItem item) { ... }
}
Then, if you extend that class for the activities you want, you will be able to access the shared menu.
Inheritance
As the other responses suggest, you could use inheritance to provide this sort of functionality. That does break the "favor composition over inheritance rule", but may be the practical solution for simple applications.
Composition
I think you are on the right path with creating a "menu helper" of sorts. I'd prefer a name such as OptionsMenuHandler and would probably write it like this:
public class OptionsMenuHandler {
private final Activity activity;
public OptionsMenuHandler(Activity activity) {
this.activity = activity;
}
public boolean onCreateOptionsMenu(Menu menu) {
// do menu inflation here.
}
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.settings:
Intent openSettings = new Intent(activity, SettingsActivity.class);
activity.startActivity(openSettings);
return true;
case R.id.help:
// others
default:
return false;
}
}
public boolean onPrepareOptionsMenu(Menu menu) {
// do menu preparation here.
}
}
and use it like this:
public class TestActivity extends AppCompatActivity {
private final OptionsMenuHandler optionsMenuHandler = new OptionsMenuHandler(this);
#Override
public boolean onCreateOptionsMenu(Menu menu) {
return optionsMenuHandler.onCreateOptionsMenu(menu) ||
super.onCreateOptionsMenu(menu);
}
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
return optionsMenuHandler.onPrepareOptionsMenu(menu) ||
super.onPrepareOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
return optionsMenuHandler.onOptionsItemSelected(item) ||
super.onOptionsItemSelected(item);
}
}
This does require extra boiler plate in each Activity. It also creates abstraction. The abstraction is justified because it keeps the code DRY. I also like the fact that business logic isn't tucked away and invisible inside a parent class somewhere... the composition makes the location of the business logic a lot more obvious.
Base Activity that Supports Composition
Another option would be to support composition in a base Activity as follows...
Create a well defined abstraction:
public interface OptionsMenuHandler {
boolean onCreateOptionsMenu(Menu menu);
boolean onOptionsItemSelected(MenuItem item);
boolean onPrepareOptionsMenu(Menu menu);
}
Create an implementation for the abstraction:
public class DefaultOptionsMenuHandler implements OptionsMenuHandler {
private final Activity activity;
public DefaultOptionsMenuHandler(Activity activity) {
this.activity = activity;
}
public boolean onCreateOptionsMenu(Menu menu) {
// do menu inflation here.
}
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.settings:
Intent openSettings = new Intent(activity, SettingsActivity.class);
activity.startActivity(openSettings);
return true;
case R.id.help:
// others
default:
return false;
}
}
public boolean onPrepareOptionsMenu(Menu menu) {
// do menu preparation here.
}
}
Support composition in the base class (ie base class has a setter):
public class BaseActivity extends AppCompatActivity {
#Nullable
private OptionsMenuHandler optionsMenuHandler;
protected void setOptionsMenuHandler(OptionsMenuHandler optionsMenuHandler) {
this.optionsMenuHandler = optionsMenuHandler;
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
return optionsMenuHandler != null
? optionsMenuHandler.onCreateOptionsMenu(menu)
: super.onCreateOptionsMenu(menu);
}
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
return optionsMenuHandler != null
? optionsMenuHandler.onPrepareOptionsMenu(menu)
: super.onPrepareOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
return optionsMenuHandler != null
? optionsMenuHandler.onOptionsItemSelected(item)
: super.onOptionsItemSelected(item);
}
}
Set the implementation in the Activity that needs the functionality.
public class TestActivity extends BaseActivity {
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setOptionsMenuHandler(new DefaultOptionsMenuHandler(this));
}
}
The net benefit here is that you write the main boilerplate once and support it through all of your activities. You can also continue to keep your business logic defined in the top level activity - where it goes with the other various logic for that particular activity.
Most non-trivial apps would benefit from something along these lines. I typically do something even more robust that supports zero or more OptionsMenuHandlers being set in any given activity where each handler supports a specific type of functionality. The code for this is fairly long and many considerations are needed, so I won't produce it here.
How do you open a new activity when you click on an item in the menu list?
For example I have a menu item named "Teams" so after I click on that, the "TeamsActivity" should open. I've searched on the internet but that didn't help me.
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.home:
???????????????????
case R.id.Teams:
???????????????????
default:
return super.onOptionsItemSelected(item);
}
}
Basically you create an Intent and start it.
You can have a look in the tutorial of the developer-site of android.
In your case it's something like:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
Intent intent = null;
switch (item.getItemId()) {
case R.id.home:
intent = new Intent(this, HomeActivity.class);
break;
case R.id.Teams:
intent = new Intent(this, TeamsActivity.class);
break;
default:
return super.onOptionsItemSelected(item);
}
startActivity(intent);
return true;
}
I have a class that extends SherlockFragmentActivity that is supposed to provide actionBar to other classes. Somehow when I override some methods, they aren't working the way they should. This is the original overriden method
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
final Intent intent = new Intent(getApplicationContext(),
MainScreen.class);
intent.putExtra("Back", true);
startActivity(intent);
break;
default:
break;
}
return super.onOptionsItemSelected(item);
}
And here I override it in my Activity.
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
final Intent intent = new Intent(Terms.this, CarDetailed.class);
Log.d("ActionBar in Terms", "Home button pressed");
intent.putExtra("Back", true);
startActivity(intent);
break;
default:
break;
}
return super.onOptionsItemSelected(item);
}
The log says it is invoking home button, but somehow I am always redirected to MainScreen.class. What am I doing wrong?
SOLVED
I returned super method, that was my error.