Popup menu using ABS - android

Is it possible to have POPUP menu like play store attached to each row of adapter
what i done so far
holder.rl_overflow.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
PopupMenu popup = new PopupMenu(context, holder.rl_overflow);
popup.getMenuInflater().inflate(R.menu.overflow, popup.getMenu());
popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
#Override
public boolean onMenuItemClick(MenuItem item) {
Toast.makeText(context,"You Clicked : " + item.getTitle(),Toast.LENGTH_SHORT).show();
return false;
}
});
popup.show();
}
});
but constructor for POPUP menu says its available from API 11. I go through the developers.android.com and i found, its can be added using SUPPORT V7 library "https://developer.android.com/reference/android/support/v7/widget/PopupMenu.html" but i'm not able to implement this using ABS, please help someone.

Use like this PopupMenu in ActionBarSherlock.
Styling of the PopupMenu -
<item name="popupMenuStyle">#style/PopupMenu.MyAppTheme</item>
<style name="PopupMenu.MyAppTheme" parent="#style/Widget.Sherlock.ListPopupWindow">
<item name="android:popupBackground">#android:color/white</item>
</style>

If you are using the support library you should discard using the ABS. Instead, import the support library into your workspace which can be found in ~/adt-bundle-linux-x86_64-20130729/sdk/extras/android/support/v7/appcompact and use is in your project. And also don't forget to add the support library which can be brought up right clicking into your project and entering Android Tools -> Add Support Library
Using appcompact you will have to extend your activity class with ActionBarActivity. And also using the appcompact you have to make changes in your styles folder. You could refer to this. Do not also forget to update the values-v11 and values-v14 file. Doing all of this will make your application compatible.
P.S. If any error occurs in your appcompact library. Don't panic look at the error logs and open the file that seems to contain the error. Most probably you will have to refresh the file and after that you just fix project properties, and the error goes away.
Hope this helps :)

Related

Convert an old style Android menu to work on newer phones

My old app has one simple menu on the main activity. It has only a few simple options, for instance "About" causing a popup with some info about the app.
It works perfectly on emulator Nexus One (API23), because there is an emulated physical menu button.
However, on most modern phones, there is no button, which means that my menus cannot be accessed.
I actually vaguely remember running it on a phone years ago which didn't have a menu button, yet somehow one could still access the menus. I may remember wrong.
(I started digging into this some days ago, and started modifying my code, the main activity inheriting from something more posh than Activity, which then caused some older API versions to be left out - and things quickly spun out of control. After hours of "maven gradle settings" and "Support Library" stuff and many pages of "AAPT2 errors" and messing up my whole system trying to fix that, I had to throw everything away and get a fresh clone from the repo. Fortunately I could also repair the other changes I had made to the system.)
How does one convert an old-style app menu to work on modern phones? It doesn't have to be fancy.
/** Setup menu */
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main, menu);
return true;
}
/** Handle menu clicks */
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle item selection
switch (item.getItemId()) {
case R.id.action_about:
final SpannableString s =
new SpannableString(getApplicationContext().getText(R.string.about));
Linkify.addLinks(s, Linkify.ALL);
AlertDialog d = new AlertDialog.Builder(this)
.setIcon(android.R.drawable.ic_dialog_info)
.setTitle("About")
.setMessage(s)
//.setView(message)
.show();
((TextView)d.findViewById(android.R.id.message)).setMovementMethod(LinkMovementMethod.getInstance());
return true;
default:
new AlertDialog.Builder(this)
.setIcon(android.R.drawable.ic_dialog_info)
.setTitle("Currently not used.")
.show();
return super.onOptionsItemSelected(item);
}
}
I'll admit that I no longer understand all the details above from years ago.. it worked, so I never paid it much attention. It looks a bit wordy... probably there are simpler ways to do it.
This is menu/main.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="#+id/action_settings"
android:orderInCategory="100"
android:title="#string/action_settings"/>
<item
android:id="#+id/action_about"
android:orderInCategory="3"
android:title="About"/>
<item
android:id="#+id/action_manual"
android:orderInCategory="4"
android:title="Manual"/>
</menu>
Maybe there is some "theme" to just add somewhere that makes the menu button show up somewhere on the screen, and that's that? (I know I am optimistic. :))
Everything looks fine.
I think your problem is because you are extending Activity.
change Activity to AppComatActivity.
and change your appThem to android:theme="#style/Theme.AppCompat.Light.DarkActionBar"
Note:
To use the AppCompatActivity, make sure you have the Google Support Library downloaded (you can check this in your Tools -> Android -> SDK manager). Then just include the gradle dependency in your app's gradle.build file:
compile 'com.android.support:appcompat-v7:27.0.2'
SOLUTION:
The only way to a solution that I could find was to create a completely new project with default settings in the latest Android Studio. This gives a "latest fashion" setup. Then I moved code in from the old project manually.
Everything now works perfectly!
ISSUES / REASONS:
As mentioned in the comment section above, every attempt I made to modernize the code resulted in a maze of problems. It was an old project, from way back when Android Studio was not even in Beta stage. Hence, it was based on Eclipse. The current Android version back then was Jelly Bean (Kitkat was just released).
In summary, we had an ancient project based on an older IDE. Perhaps it would be doable to convert a modern Eclipse project into Android Studio. Perhaps it would be doable to convert an older AS project into a modern one. However, performing both these major jumps at the same time was too great a challenge for me.
Another issue which has nothing to do with the old code, but which confused the matter greatly is that something called AAPT2 currently for whatever reason assumes american characters only in the search path to the .gradle directory. I use the word "assumes", because if the characters are anything else, you get pages of errors in the build log. None of the errors point very clearly to the reason.
AFAIK I don't even use AAPT2! After some sleepless nights, I solved it by changing the global setting in Android Studio to simply use another path.

Setting content description for option menu android Talkback

I am implementing "Read Aloud" or "Talkback" for an app. Everything is working with contentDescription text, but with option menu, I found nothing related to contentDescription, I want system read "Menu "+ item's name.
EX: My menu has 2 items: "Create New Folder" and "Delete current folder", currently, when I focus a menu item (Support trackball and bluetooth key), system can talk exactly the menu's text. But I want it talks more like "1: Menu Create New Folder" and "2: Menu Delete current folder".
So, How can I change the read text? How can I get the focused menu item when bluetooth keyboard press UP/DOWN key?
MenuItemCompat in the v4 support libraries has a
android.support.v4.view.MenuItemCompat.setContentDescription(MenuItem menuItem, CharSequence contentDescription)
method for backwards compatibility on pre-Oreo devices.
For AndroidX see this answer:
https://stackoverflow.com/a/57950952/1236327
As my investigation, in Android internal source code, class ActionMenuItemView.java method setTitle(CharSequence title), the source code also sets setContentDescription(title), so Android will read your MenuItem's text as default. I don't know why the core has so inflexible in this case.
Updated:
Thanks for #sofakingforever answer.
Seem Google just added the setContentDescription(CharSequence contentDescription) method to the MenuItem class on API 26 (Android O).
Updated:
Thanks for new #tim.paetz answer .
Look like all versions are now supported setContentDescription for menu item using android support v4 libraries.
this answer post AndroidX
androidx.core.view.MenuItemCompat.setContentDescription(menuItem, contentDescription)
It seems they just added the setContentDescription(CharSequence contentDescription) method to the MenuItem class on API 26 (Android O)
Full sample:
#Override
public void onCreateOptionsMenu(#NonNull Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.client_menu_close, menu);
super.onCreateOptionsMenu(menu, inflater);
MenuItem closeMenu = menu.findItem(R.id.client_menu_close_action);
androidx.core.view.MenuItemCompat.setContentDescription(closeMenu, R.string.str_accessibility_client_screen_close);
}

How can I implement actionbar to api level 8 easily?

I search on google and stackoverflow this topic.I ve found a few way to implement.
one of these is actionbarsherlock , but actually I do not understand how can implement this to my project. Is there any simple way? I mean a few classes or just add a library I do not know but I have a huge project and I want to implement this .Could you show me how can do it easily?
thanks
If you want to use ActionbarCompat library.
1) Import the ActionbarCompat library project into your workspace first and add the library to your project
https://developer.android.com/tools/support-library/setup.html#libs-with-res
2) Extend your Activity Class with ActionBarActivity
3) set your theme in manifest as
android:theme="#style/Theme.AppCompat"
Please check this link.
You can use android support library for this. No need of any other library.
Example also there in side link.
If You want to use ActionBar that supports devices with lower api..
you can do two things ...
1)Use the support Library(ActionbarCompat)
2)Use ActionBarSherlock
I use ActionBarsherlock
Steps to Use
1)YOURACTIVITY extends SherlockActivity
2) Use onCreateOptionsMenu to get the menu
`
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
SubMenu subMenu1 = menu.addSubMenu("");
subMenu1.add(0,2,Menu.NONE,"Rate Us").setIcon(R.drawable.ic_action_good);
MenuItem subMenu1Item = subMenu1.getItem();
subMenu1Item.setIcon(R.drawable.ic_action_overflow);
subMenu1Item.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS | MenuItem.SHOW_AS_ACTION_WITH_TEXT);
return super.onCreateOptionsMenu(menu);
}
3) Use onOptionsItemSelected to get the item selected
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case 2:
//rate app
break;
return super.onOptionsItemSelected(item);
}
4)Finally in your AndroidManifest File, add this under your activity
android:theme="#style/Theme.Sherlock"
`
5) and you are Done ...:)
For setup support library see-
https://developer.android.com/tools/support-library/setup.html
And for implementing action bar using support library see this-
http://antonioleiva.com/actionbarcompat-how-to-use/

Equivalent of NavUtils when not using the Android support library?

This question has also been asked by someone on the Android Developers Google Group (link), but it does not have an answer...
I recently removed the v4 support library from my Android project in Eclipse, because my application only targets Android 4.0 (Ice Cream Sandwich) and up. I'm now going through all the support library references that are giving me errors.
One in particular is NavUtils, which seems to be a support library class used in Activity navigation. Example:
#Override
public boolean onOptionsItemSelected(MenuItem item)
{
switch (item.getItemId())
{
case android.R.id.home:
NavUtils.navigateUpFromSameTask(this);
return true;
}
return super.onOptionsItemSelected(item);
}
What is the equivalent of NavUtils when not using the support library?
Look at the source code of NavUtils, if necessary just copy it to your project. It just gets the parent activity set in the manifest and starts it.
I found #Nikolay's approach to be the best if you don't want to have the whole android v4 support library in your project.
This is the list of classes you should copy into your project:
NavUtils
NavUtilsJB
IntentCompat
IntentCompatHoneycomb
IntentCompatIcsMr1
Android version from Jelly Beans have the NavUtils incorporated into the Activity class.
There is no need to handle the case : android.R.id.home in onOptionsItemSelected().
OR you can just return false for this case in onOptionsItemSelected().
Here is this simplest answer I could find, and what I did in my code:
Simply replace:
NavUtils.navigateUpFromSameTask(this);
with:
navigateUpTo(getParentActivityIntent());
Hope this helps!

How to force use of overflow menu on devices with menu button

I'd like to have all of the menu items that don't fit into the ActionBar go into the overflow menu (the one that is reached from the Action Bar not the menu button) even on devices that do have a Menu button. This seems much more intuitive for users than throwing them into a separate menu list that requires the user to jump from a touch(screen) interaction to a button based interaction simply because the layout of the ActionBar can't fit them on the bar.
On the emulator I can set the "Hardware Back/Home Keys" value to "no" and get this effect.
I've searched for a way to do this in code for an actual device that has a menu button but can't fine one. Can anyone help me?
You can also use this little hack here:
try {
ViewConfiguration config = ViewConfiguration.get(this);
Field menuKeyField = ViewConfiguration.class.getDeclaredField("sHasPermanentMenuKey");
if (menuKeyField != null) {
menuKeyField.setAccessible(true);
menuKeyField.setBoolean(config, false);
}
} catch (Exception ignored) {
}
Good place to put it would be the onCreate-Method of your Application class.
It will force the App to show the overflow menu. The menu button will still work, but it will open the menu in the top right corner.
[Edit] Since it has come up several times now: This hack only works for the native ActionBar introduced in Android 3.0, not ActionBarSherlock. The latter uses its own internal logic to decide whether to show the overflow menu. If you use ABS, all platforms < 4.0 are handled by ABS and are thus subjected to its logic. The hack will still work for all devices with Android 4.0 or greater (you can safely ignore Android 3.x, since there aren't really any tablets out there with a menu button).
There exists a special ForceOverflow-Theme that will force the menu in ABS, but apperently it is going to be removed in future versions due to complications.
EDIT: Modified to answer for the situation of physical menu button.
This is actually prevented by design. According to the Compatibility Section of the Android Design Guide,
"...the action overflow is available from the menu hardware key. The resulting actions popup... is displayed at the bottom of the screen."
You'll note in the screenshots, phones with a physical menu button don't have an overflow menu in the ActionBar. This avoids ambiguity for the user, essentially having two buttons available to open the exact same menu.
To address the issue of consistency across devices: Ultimately it's more important to the user experience that your app behave consistently with every other app on the same device, than that it behave consistently with itself across all devices.
I use to workaround it by defining my menu like this (also with ActionBarSherlock icon used in my example):
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="#+id/menu_overflow"
android:icon="#drawable/abs__ic_menu_moreoverflow_normal_holo_light"
android:orderInCategory="11111"
android:showAsAction="always">
<menu>
<item
android:id="#+id/menu_overflow_item1"
android:showAsAction="never"
android:title="#string/overflow_item1_title"/>
<item
android:id="#+id/menu_overflow_item2"
android:showAsAction="never"
android:title="#string/overflow_item2_title"/>
</menu>
</item>
</menu>
I admit that this may require manual "overflow-management" in your xml, but I found this solution useful.
You can also force device to use HW button to open the overflow menu, in your activity:
private Menu mainMenu;
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// TODO: init menu here...
// then:
mainMenu=menu;
return true;
}
#Override
public boolean onKeyUp(int keycode, KeyEvent e) {
switch(keycode) {
case KeyEvent.KEYCODE_MENU:
if (mainMenu !=null) {
mainMenu.performIdentifierAction(R.id.menu_overflow, 0);
}
}
return super.onKeyUp(keycode, e);
}
:-)
If you are using the action bar from the support library (android.support.v7.app.ActionBar), use the following:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:yorapp="http://schemas.android.com/apk/res-auto" >
<item
android:id="#+id/menu_overflow"
android:icon="#drawable/icon"
yourapp:showAsAction="always"
android:title="">
<menu>
<item
android:id="#+id/item1"
android:title="item1"/>
<item
android:id="#+id/item2"
android:title="item2"/>
</menu>
</item>
</menu>
This kind of method is prevented by the Android Developers Design System, but I found a way to pass it:
Add this to your XML menu file:
<item android:id="#+id/pick_action_provider"
android:showAsAction="always"
android:title="More"
android:icon="#drawable/ic_action_overflow"
android:actionProviderClass="com.example.AppPickActionProvider" />
Next, create a class named 'AppPickActionProvider', and copy the following code to it:
package com.example;
import android.content.Context;
import android.util.Log;
import android.view.ActionProvider;
import android.view.MenuItem;
import android.view.MenuItem.OnMenuItemClickListener;
import android.view.SubMenu;
import android.view.View;
public class AppPickActionProvider extends ActionProvider implements
OnMenuItemClickListener {
static final int LIST_LENGTH = 3;
Context mContext;
public AppPickActionProvider(Context context) {
super(context);
mContext = context;
}
#Override
public View onCreateActionView() {
Log.d(this.getClass().getSimpleName(), "onCreateActionView");
return null;
}
#Override
public boolean onPerformDefaultAction() {
Log.d(this.getClass().getSimpleName(), "onPerformDefaultAction");
return super.onPerformDefaultAction();
}
#Override
public boolean hasSubMenu() {
Log.d(this.getClass().getSimpleName(), "hasSubMenu");
return true;
}
#Override
public void onPrepareSubMenu(SubMenu subMenu) {
Log.d(this.getClass().getSimpleName(), "onPrepareSubMenu");
subMenu.clear();
subMenu.add(0, 1, 1, "Item1")
.setIcon(R.drawable.ic_action_home).setOnMenuItemClickListener(this);
subMenu.add(0, 2, 1, "Item2")
.setIcon(R.drawable.ic_action_downloads).setOnMenuItemClickListener(this);
}
#Override
public boolean onMenuItemClick(MenuItem item) {
switch(item.getItemId())
{
case 1:
// What will happen when the user presses the first menu item ( 'Item1' )
break;
case 2:
// What will happen when the user presses the second menu item ( 'Item2' )
break;
}
return true;
}
}
Well I think that Alexander Lucas has provided the (unfortunately) correct answer so I'm marking it as the "correct" one. The alternative answer I'm adding here is simply to point any new readers to this post in the Android Developers blog as a rather complete discussion of the topic with some specific suggestions as to how to deal with your code when transitioning from pre-level 11 to the new Action Bar.
I still believe it was a design mistake not have the menu button behave as a redundant "Action Overflow" button in menu button enabled devices as a better way to transition the user experience but its water under the bridge at this point.
I'm not sure if this is what you're looking for, but I built a Submenu within the ActionBar's Menu and set its icon to match the Overflow Menu's Icon. Although it wont have items automatically sent to it, (IE you have to choose what's always visible and what's always overflowed) it seems to me that this approach may help you.
In the gmail app that comes with ICS pre-installed, the menu button is disabled when you have multiple items selected. The overflow menu is here "forced" to be triggered by the use of the overflow button instead of the physical menu button. Theres a 3rd-party lib called ActionBarSherlock which lets you "force" the overflow menu. But this will only work on API level 14 or lower(pre-ICS)
If you use Toolbar, you can show the overflow on all versions and all devices, I've tried on some 2.x devices, it works.
Sorry if this problem is dead.
Here is what I did to resolve the error. I went to layouts and created two ones containing toolbars. One was a layout for sdk version 8 and the other was for sdk version 21. On version 8, I used the android.support.v7.widget.Toolbar while I used android.widget.Toolbar on the sdk 21 layout.
Then I inflate the toolbar in my activity. I check the sdk to see if it was 21 or higher. I then inflate the corresponding layout. This forces the hardware button to map onto the toolbar you actually designed.
For anyone using the new Toolbar:
private Toolbar mToolbar;
#Override
protected void onCreate(Bundle bundle) {
super.onCreate(bundle);
mToolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(mToolbar);
...
}
#Override
public boolean onKeyUp(int keycode, KeyEvent e) {
switch(keycode) {
case KeyEvent.KEYCODE_MENU:
mToolbar.showOverflowMenu();
return true;
}
return super.onKeyUp(keycode, e);
}

Categories

Resources