I'm developing a weather app, but I have a problem when displaying an optionsMenu with some smartphones. I want to display a menu with 3 options, but on the HTC one X, only 2 options are displayed.
The problem is that the black bar at the bottom of the screen hides the third option of my menu.
Here is a screenshot of the problem : (we should see "Recharger", "Voir cette image" and the last option : "Autres cartes")
The code :
public boolean onCreateOptionsMenu(Menu menu) {
menu.add(0,100,0,m_res.getStringArray(R.array.menu_reload)[Commons.currentLanguage]).setIcon(R.drawable.reload);
menu.add(0,101,0,m_res.getStringArray(R.array.menu_view_single)[Commons.currentLanguage]).setIcon(R.drawable.see);
if(m_model.getUrl2().size() !=0)
menu.add(0,102,0,m_res.getStringArray(R.array.menu_more)[Commons.currentLanguage]).setIcon(R.drawable.more);
SubMenu moreMaps = menu.addSubMenu(0,103,0,m_res.getStringArray(R.array.menu_others_maps)[Commons.currentLanguage]).setIcon(R.drawable.france);
if(m_time == 1)
{
for(int iBoucle = 0 ; iBoucle < m_model.getNames1().size() ; iBoucle++)
moreMaps.add(1,iBoucle,1,m_model.getNames1().get(iBoucle));
}
else
{
for(int iBoucle = 0 ; iBoucle < m_model.getNames2().size() ; iBoucle++)
moreMaps.add(1,iBoucle,1,m_model.getNames2().get(iBoucle));
}
onContextItemSelected(moreMaps.getItem());
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case 100:
if(Commons.getNetworkState() || Commons.getWifiState())
{
eraseData();
loadingData();
}
else
Commons.getConnectivityErrorMessage(m_Context);
return true;
case 101:
Intent sia = new Intent(m_Context, SingleImageActivity.class);
sia.putExtra("url", correctURL(m_urlImages.get(m_step)));
sia.putExtra("choiceNumber", -1);
if(m_textIsHour)
{
if(m_time == 1)
sia.putExtra("title", m_model.getNames1().get(m_mode)+" - "+m_model.getHours1().get(m_step)+"h");
else
sia.putExtra("title", m_model.getNames2().get(m_mode)+" - "+m_model.getHours2().get(m_step)+"h");
}
startActivity(sia);
break;
case 102:
if(Commons.getNetworkState() || Commons.getWifiState())
{
Intent modelSubList = new Intent(m_Context, ModelViewActivity.class);
modelSubList.putExtra("model",m_modelNumber);
modelSubList.putExtra("mode",m_mode);
if(m_time == 1)
modelSubList.putExtra("time",2);
else
modelSubList.putExtra("time",1);
startActivity(modelSubList);
finish();
}
else
{
Commons.getConnectivityErrorMessage(m_Context);
}
break;
case 103:
break;
default:
if(Commons.getNetworkState() || Commons.getWifiState())
{
Intent otherMapsIntent = new Intent(m_Context, ModelViewActivity.class);
otherMapsIntent.putExtra("model",m_modelNumber);
otherMapsIntent.putExtra("mode",item.getItemId());
otherMapsIntent.putExtra("time",m_time);
startActivity(otherMapsIntent);
finish();
return true;
}
else
{
Commons.getConnectivityErrorMessage(m_Context);
return false;
}
}
return false;
}
This code is showing three menu options on the US and European One X phones I have here:
https://github.com/lnanek/Misc/tree/master/OneXFullscreenMenuTest
Can you try it on your device? If it doesn't work, then we know it is the software on your device. If it does work, then it could be something in your code.
Can you post more about your situation? I'm particularly interested in the code for how you turn on fullscreen and your AndroidManifest.xml (for things like the uses-sdk line and theme settings).
I don't see anything wrong offhand in the code you posted, but could you comment out this line just for a quick check?
if(m_model.getUrl2().size() !=0)
If that check isn't passing, then there should be only two menu items, not three. So commenting it out would be a quick check (or watching in a debugger to see if all three adds are called, of course).
Please note that onCreateOptionsMenu is only called the very first time the Activity instance shows the options menu, as opposed to onPrepareOptionsMenu which is called every time. So if adding that third menu option is not done the very first time, then it never will be.
Related
I'm having problems with SettingsActivity which was generated by Android Studio. Specifically pressing the Up button creates a new instance of settings activity instead of going back to the parent activity. This happens only on large tablets where settings are split - i.e. headers to the left of the list of settings.
The following code was generated by Android Studio:
public boolean onMenuItemSelected(int featureId, MenuItem item) {
int id = item.getItemId();
if (id == android.R.id.home) {
if (!super.onMenuItemSelected(featureId, item)) {
NavUtils.navigateUpFromSameTask(this);
}
return true;
}
return super.onMenuItemSelected(featureId, item);
}
On large tablets onMenuItemSelected() always returns true so navigateUpFromSameTask() is never called. However, even forcing the call to navigateUpFromSameTask() produces the same results.
Example:
...
if (!super.onMenuItemSelected(featureId, item) ||
isXLargeTablet(this)) {
NavUtils.navigateUpFromSameTask(this);
}
...
The only thing that seems to work is a call to finish().
Example:
if (id == android.R.id.home) {
if (isXLargeTablet(this)) {
finish();
return true;
}
if (!super.onMenuItemSelected(featureId, item)) {
NavUtils.navigateUpFromSameTask(this);
}
return true;
}
The parent activity's (main activity) launchMode is set to "singleTop" in the manifest.
The same navigation works fine on smaller tablets and phones.
I'm not sure if my hacky solution is sufficient.
Is there another way to deal with this 'bug'?
Thanks.
I'm sorry if this question has been answered before. Honestly, I have searched this issue a lot and although there are similar cases, none of them helped me.
I am developing an Android Application for a TV. I have created a GridView because I want to show some thumbnails of pictures and videos. Each item in the gridview has a picture and a text info below.
The problem is that I can't get the dpad to work properly. If I set android:focusable="true" in the items, I can navigate through the GridView, but I can't display the image/video after pressing enter or using the mouse (no call to "onItemClick()"). If I do not set android:focusable="true", I can't navigate through the GridView (maybe cuz I do not see it) and also I can't press enter and see the image/video, but I do can click with the mouse the item and see the image/video.
What can I do to make the dpad work properly?
Thank you very much in advance. I have been struggling with this since a big while, I would sincerely appreciate your help.
I faced the exact same problem yesterday. What you need to do is add an onKeyListener to the GridView and inside the onKey function handle the key presses. I'll share what I did with it so that you can build on it.
gridView.setOnKeyListener(new View.OnKeyListener() {
#Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if(keyCode == KeyEvent.KEYCODE_DPAD_CENTER){
Toast.makeText(getActivity(), "CENTER", Toast.LENGTH_SHORT).show();
if(gridView.getSelectedItemPosition() == -1){
if(gridView.getCount() > 0)
gridView.setSelection(0);
else
return false;
}
CURRENT_VIDEO_NUM = gridView.getSelectedItemPosition();
}
else{
switch(keyCode){
case KeyEvent.KEYCODE_DPAD_RIGHT:
Toast.makeText(getActivity(), "RIGHT", Toast.LENGTH_SHORT).show();
if(event.getAction() == 0){
try {
if (gridView.getSelectedItemPosition() < gridViewAdapter.getCount() - 1) {
gridView.setSelection(gridView.getSelectedItemPosition() + 1);
return true;
}
} catch (Exception e) {
gridView.setSelection(gridViewAdapter.getCount() - 1);
return true;
}
}
break;
case KeyEvent.KEYCODE_DPAD_LEFT:
Toast.makeText(getActivity(), "LEFT", Toast.LENGTH_SHORT).show();
if(event.getAction() == 0){
try {
if (gridView.getSelectedItemPosition() > 0) {
gridView.setSelection(gridView.getSelectedItemPosition() - 1);
return true;
}
} catch (Exception e) {
gridView.setSelection(0);
return true;
}
}
break;
case KeyEvent.KEYCODE_DPAD_UP:
Toast.makeText(getActivity(), "UP", Toast.LENGTH_SHORT).show();
break;
case KeyEvent.KEYCODE_DPAD_DOWN:
Toast.makeText(getActivity(), "DOWN", Toast.LENGTH_SHORT).show();
break;
default:
Toast.makeText(getActivity(), "ELSE" + keyCode, Toast.LENGTH_SHORT).show();
break;
}
}
return false;
}
});
Now let me explain whats happening here.
1) I check if the center button is pressed, if thats the case, I'll perform the action that is to be performed when an item is clicked.
2) If RIGHT button is pressed, the selection is moved to right and the same for the left one.
3) UP and DOWN are a little less trivial. Since I was just building a demo, I didn't spend time on it. Won't be a problem though, just increment/decrement the total number of columns of the grid view keeping in mind the max/min of the items.
Try building on it and if you face any issue, do let me know.
I currently have multiple lisview's that have contextual menu's that allows users t delete items. I havent been able to find any topics on this. Is it possible to have all of the listviews triggered at the same time to delete them without having to click on each list to get their own contextual menu?
Currently I am only able to click on one listview after the contextualmenu is brought to front. I beleive it has to to with :
listBreakfast.setMultiChoiceModeListener(this);
listLunch.setMultiChoiceModeListener(this);
They are being implemented separately. Below is the implementations within the activity.
listBreakfast.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
listBreakfast.setMultiChoiceModeListener(this);
listLunch.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
listLunch.setMultiChoiceModeListener(this);
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_item_delete :
for (int i = listBreakfast.getCount() - 1; i >= 0; i--) {
if (listBreakfast.isItemChecked(i)) {
lb = logsAdapter1.getItem(i);
lb.delete1();
logsAdapter1.remove(logsAdapter1.getItem(i));
logsAdapter1.notifyDataSetChanged();
}
}
for (int i = listLunch.getCount() - 1; i >= 0; i--) {
if (listLunch.isItemChecked(i)) {
ll = logsAdapter11.getItem(i);
ll.delete();
logsAdapter11.remove(logsAdapter11.getItem(i));
logsAdapter11.notifyDataSetChanged();
}
}
mode.finish();
logsAdapter.notifyDataSetChanged();
logsAdapter11.notifyDataSetChanged();
return true;
default :
return false;
}
}
Using the developers guide found here, I am trying to make my icon navigate back to my home screen. I currently have a button which does this, and have copy and pasted the code in the onOptionsItemSelected() method. However tapping the icon never does anything. Is this a difference in ActionBar and ActionBarSherlock?
This is the code given as an example:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
// app icon in action bar clicked; go home
Intent intent = new Intent(this, HomeActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
return true;
default:
return super.onOptionsItemSelected(item);
}
}
This is the code that I am using:
public boolean onOptionsItemSelected( MenuItem item ) {
switch( item.getItemId() ) {
case R.id.mainTopBluetoothState:
Toast.makeText( this, "BluetoothState", Toast.LENGTH_SHORT ).show();
return true;
case R.id.mainTopAppState:
Toast.makeText( this, "BluetoothState", Toast.LENGTH_SHORT ).show();
return true;
case android.R.id.home:
Log.i( "In Home", "In Home" );
killToasts();
dispatchKeyEvent(new KeyEvent( KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_BACK ));
finish();
return true;
}
return super.onOptionsItemSelected( item );
}
When I tap the icon, nothing happens. The Log call in the code isn't ever shown in my LogCat either.
You are probably not enabling the ABS Activity logo to be clickable. Add this in onCreate()
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
Also, if you haven't done so already, read Implementing Ancestral Navigation so you navigate up properly (ignore their use of getActionBar(), they're not using ABS, and that's the actual Android API Action Bar method).
Im using action bar compability library. Im trying to open the options menu from a button with openOptionsMenu() function but it does nothing.
Menu shows as usual when pressing the menu key on my phone. What is wrong here?
public class ReadActivity extends ActionBarActivity {
...
#Override
public boolean onCreateOptionsMenu(Menu menu) {
boolean value;
MenuInflater menuInflater = getMenuInflater();
menuInflater.inflate(R.menu.read, menu);
value = super.onCreateOptionsMenu(menu);
if (Helper.SupportsNewApi()) {
getActionBar().hide();
} else {
((View) ((LinearLayout) findViewById(R.id.actionbar_compat))
.getParent()).setVisibility(View.GONE);
}
return value;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
finish();
break;
case R.id.menu_search:
// Toast.makeText(this, "Tapped search", Toast.LENGTH_SHORT).show();
break;
case R.id.menu_bookmark:
// selectText();
// setFullScreen(false);
break;
case R.id.menu_day_night_mode:
break;
case R.id.menu_settings:
break;
case R.id.menu_zoom_in:
showOverlay(false);
break;
case R.id.menu_zoom_out:
showOverlay(false);
break;
case R.id.menu_table_of_contents:
Intent tocIntent = new Intent(this, TocActivity.class);
int GET_SECTION_REFERENCE = 1;
startActivityForResult(tocIntent, GET_SECTION_REFERENCE);
break;
case R.id.menu_overflow:
Toast.makeText(this, "Tapped overflow", Toast.LENGTH_SHORT).show();
//closeOptionsMenu();
openOptionsMenu(); //tried the below aswell, no results
//getWindow().openPanel(Window.FEATURE_OPTIONS_PANEL, null);
break;
}
return super.onOptionsItemSelected(item);
}
#Override //disable volume buttons
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (!menuShown && (keyCode == 25 || keyCode == 24)) {
return true;
}
return super.onKeyDown(keyCode, event);
}
#Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
Log.d(tag, "Keycode is = "+keyCode);
if (keyCode == 82) {
if (!menuShown) {
//openOptionsMenu();
showOverlay(true);
} else {
showOverlay(false);
}
//don't want it to open when pressing menu
return true;
} else if (keyCode == 4 && menuShown) {
showOverlay(false);
return true;
} else if (keyCode == 25 && !menuShown) {
prevPage();
return true;
} else if (keyCode == 24 && !menuShown) {
nextPage();
return true;
}
return super.onKeyUp(keyCode, event);
}
}
I was having the same problem trying to go around this openOptionsMenu thing on an app
that I was doing that should run on Android 1.6 and up. Following the answer from Werner Van Belle I reached the conclusion that we could achieve a workaround to solve the problem.
So I came up with the following code, it's always beatiful when people don't mark a method as final, so we can always override it. It's perfect if you don't want to give up on targeting your app to the latest api (android:targetSdkVersion="17"). I hope you guys like it. :)
#Override
public void openOptionsMenu() {
Configuration config = getResources().getConfiguration();
if((config.screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK)
> Configuration.SCREENLAYOUT_SIZE_LARGE) {
int originalScreenLayout = config.screenLayout;
config.screenLayout = Configuration.SCREENLAYOUT_SIZE_LARGE;
super.openOptionsMenu();
config.screenLayout = originalScreenLayout;
} else {
super.openOptionsMenu();
}
}
To shed some light on this sad development by google. Google obviously wishes everybody to embrace the new ActionBar. They could have achieved that by making the ActionBar easier to use than the old menu system. That is however not how they planned the transition. No, they thought it would make sense to harras programmers by making the old menus impossible to use but without providing proper backward compatibility.
Below is the code taken from com.android.internal.policy.impl, which is supposed to create the optionsMenu panel. As you see, the code simply refuses to create an options Panel. Allthough, the ability is obviously there. So, to answer your question: forget it, Google doesn't want you to use that optionsPanel anymore.
// Don't open an options panel for honeycomb apps on xlarge devices.
// (The app should be using an action bar for menu items.)
if (st.featureId == FEATURE_OPTIONS_PANEL) {
Context context = getContext();
Configuration config = context.getResources().getConfiguration();
boolean isXLarge = (config.screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) ==
Configuration.SCREENLAYOUT_SIZE_XLARGE;
boolean isHoneycombApp = context.getApplicationInfo().targetSdkVersion >=
android.os.Build.VERSION_CODES.HONEYCOMB;
if (isXLarge && isHoneycombApp) {
return;
}
}
I cannot understand the forcing blocking Menu button usage as well. However, the following trick helped me with showing a menu on "restricted" types of devices.
First of all we need to define, whether we require the following hack or not.
boolean requireDirtyMenuButtonHack = Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB && (activity.getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_XLARGE) > 0;
Then:
protected final OnClickListener mMenuButtonClickListener = new OnClickListener() {
#Override
public void onClick(View v) {
if (requireDirtyMenuButtonHack) {
Configuration config = getContext().getResources().getConfiguration();
config.screenLayout &= ~Configuration.SCREENLAYOUT_SIZE_XLARGE;
config.screenLayout |= Configuration.SCREENLAYOUT_SIZE_LARGE;
}
getActivity().openOptionsMenu();
}
};
Don't forget to cleanup! (don't know if it's neccessary, but better to play kind)
public void onPrepareOptionsMenu(Menu menu) {
if (requireDirtyMenuButtonHack) {
Configuration config = getContext().getResources().getConfiguration();
config.screenLayout &= ~Configuration.SCREENLAYOUT_SIZE_LARGE;
config.screenLayout |= Configuration.SCREENLAYOUT_SIZE_XLARGE;
}
//do the preparing...
}
I'm not sure how relevant this is, but this forum post I found seems to be answerring the same question you have.
I hope this post is relevant enough to solve your problem.
Good luck!
android:targetSdkVersion="10" in manifest helped me.
openOptionsMenu() works as expected now on ICS+. In addition, there is "overflow" menu button appears at the bottom of screen (on device buttons panel).
ps: I use NoTitleBar theme (NoActionBar for sdk 11 and higher) +ViewPagerIndicator by Jake Wharton.
This worked for me, my code is pretty similar to yours, and what I want to do is from a button in the action bar, open the overflow menu:
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_home_about:
dialog = new Dialog(this);
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
dialog.setContentView(R.layout.customdialog);
dialog.show();
break;
default:
case R.id.menu_home_refresh:
updateLists(true);
break;
case R.id.menu_home_menu:
new Handler().postDelayed(new Runnable() {
public void run() {
openOptionsMenu();
}
}, 0);
return true;
}
return false;
}
Do you mean you want to show a button on the right side of the action bar?
Here is how I did mine:
res/menu/main.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="#+id/menu_share"
android:title="Logout"
android:icon="#android:drawable/ic_lock_power_off"
android:orderInCategory="1"
android:showAsAction="always" />
</menu>
Activity
1) take note of the ActionBarActivity; 2) MenuInflater in onCreateOptionsMenu 3) onOptionsItemsSelected (I think you need to return super.onOptionsItemSelected(item) )
public class BaseActivity extends ActionBarActivity {
....
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main, menu);
return true;
}
....
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_share:
//Do something
break;
}
return super.onOptionsItemSelected(item);
}
If you are using your custom toolbar, you can try:
toolBar.showOverflowMenu();