I want to be able to select an option from a PopupMenu using keys (i.e. the numbers 1-4). The device I'm writing an app for has a built in numeric keypad, making them always accessible (not using soft keyboard).
The aim is for the user to be able to press a number/button and the menu will be shown, which is working, here (this is in my activity):
#Override
public boolean onKeyUp(int keyCode, KeyEvent event){
Log.d("onKeyUp", KeyEvent.keyCodeToString(keyCode));
if (event.getKeyCode() == KeyEvent.KEYCODE_5) {
showPopupMenu((Button) findViewById(R.id.btnMenu));
}
return true;
}
I would like to be able to then select one of the options from the menu using the key pad, however when the menu is visible, the onKeyUp event isn't fired whenever a key is pressed.
Here's the menu code:
public void showPopupMenu(View v){
PopupMenu popupMenu = new PopupMenu(this, v);
final MenuInflater menuInflator = popupMenu.getMenuInflater();
popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
#Override
public boolean onMenuItemClick(MenuItem menuItem) {
//Do something
return true;
}
});
menuInflator.inflate(R.menu.current_screen_menu, popupMenu.getMenu());
popupMenu.show();
}
This is using Android 4.1 (API 16). Thanks for any help! Happy to provide more code where needed.
You need to set keyevent listener in popupwindow object like this
public void showPopupMenu(View v){
PopupMenu popupMenu = new PopupMenu(this, v);
final MenuInflater menuInflator = popupMenu.getMenuInflater();
popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
#Override
public boolean onMenuItemClick(MenuItem menuItem) {
//Do something
return true;
}
});
menuInflator.inflate(R.menu.current_screen_menu, popupMenu.getMenu());
popupMenu.show();
// You have to implement following listner
popupMenu.getContentView().setOnKeyListener(new View.OnKeyListener() {
#Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_MENU &&
event.getRepeatCount() == 0 &&
event.getAction() == KeyEvent.ACTION_DOWN) {
// ... payload action here. e.g. popupMenu.dismiss();
return true;
}
return false;
}
});
}
Related
I have activity with custom actionbar(Basically custom layout xml), therefore I have created a custom menu button as well in layout file and showing a popup,
I am usingthis callback to showing same popup on tap of hardware option menu, but give a weird behaviour e.g this will open custom menu whenvery onresume is run.
#Override
public boolean onCreateOptionsMenu(Menu menu) {
//return super.onCreateOptionsMenu(menu);
showHideMenu();
return false;
}
can you please suggest where I can placeshowHideMenu(); will which work like custom option menu
//showHideMenu() code
private void showHideMenu() {
if (mPopUpMenu.isShowing())
dismissPopUpMenu();
else
showMenu();
}
private void dismissPopUpMenu() {
// dismiss menu
if (mPopUpMenu != null)
mPopUpMenu.dismiss();
}
You should look for an up keyevent:
public boolean onKeyUp(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_MENU) {
showHideMenu();
return true;
}
return super.onKeyUp(keyCode, event);
}
Include this for PopUp:
mPopUpMenu.getContentView().setOnKeyListener(new View.OnKeyListener() {
#Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_MENU) {
// ... payload action here. e.g. popupMenu.dismiss();
return true;
}
return false;
}
});
Reference:
Detecting physical Menu key press in Android
you can use PopupMenu for showing custom menu.
for this you have to find a view to attach menu.and then you can wrote
//Creating the instance of PopupMenu
PopupMenu popup = new PopupMenu(MainActivity.this, button1);
//Inflating the Popup using xml file
popup.getMenuInflater().inflate(R.menu.popup_menu,popup.getMenu());
popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
public boolean onMenuItemClick(MenuItem item) {
Toast.makeText(MainActivity.this,"You Clicked : " + item.getTitle(),Toast.LENGTH_SHORT).show();
return true;
}
});
popup.show();//showing popup menu
for more information you can see http://www.androidhive.info/2011/09/how-to-create-android-menus/
In my application I have attached popup menu with each item in listview. The popup menu has further two items when we click on popup menu icon.I have implemented OnMenuItemClickListener in my activity to listen for popup menu item clicks which is working fine.But the problem is that How do I get to know the listitem id (not popup menu item id) when I click on popup menu icon for any listview item.The popup menu code is below:
public void showPopup(View v) {
PopupMenu popup = new PopupMenu(this, v);
popup.setOnMenuItemClickListener(this);
popup.inflate(R.menu.actions);
popup.show();
}
#Override
public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_play:
return true;
default:
return false;
}
}
Please tell me what is "listitem id" that you want to know? I doubt that it's a "listitem view's id". Probably you're thinking about "position", right?
I don't know where do you call showPopup(View v) from, but you also need to pass the position there:
public void showPopup(View v, int listItemPosition) {
PopupMenu popup = new PopupMenu(this, v);
popup.setOnMenuItemClickListener(this);
popup.inflate(R.menu.actions);
popup.show();
}
Your goal is to know this position in the onMenuItemClick(MenuItem item) callback.
The simplest way to achieve this is to create variable "listItemPositionForPopupMenu", store this position there and read it in the onMenuItemClick callback:
private int listItemPositionForPopupMenu;
public void showPopup(View v, int listItemPosition) {
listItemPositionForPopupMenu = listItemPosition;
PopupMenu popup = new PopupMenu(this, v);
popup.setOnMenuItemClickListener(this);
popup.inflate(R.menu.actions);
popup.show();
}
#Override
public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_play:
// read the listItemPositionForPopupMenu here
return true;
default:
return false;
}
}
You can also do it in many other ways, like creating you own OnMenuItemClickListener listener with listItemPosition variable in constructor and create custom interface with onMenuItemClick(MenuItem item, int listItemPosition). Or you can just create an anonymous class, then you don't need to have the listItemPositionForPopupMenu member variable:
public void showPopup(View v, final int listItemPosition) {
PopupMenu popup = new PopupMenu(this, v);
popup.setOnMenuItemClickListener(new OnMenuItemClickListener() {
#Override
public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_play:
// read the listItemPosition here
return true;
default:
return false;
}
}
});
popup.inflate(R.menu.actions);
popup.show();
}
I have search view in my fragment. when I click on it , keyboard is open and I can type text. I want when I click on search button in keyboard , my query send to my server and get result but I don't know how get search event. any solution?
You have to extend OnQueryTextListener, attach the listener and implement onQueryTextSubmit.
Example:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
searchView = (SearchView) menu.findItem(R.id.mActionSearch).getActionView();
searchView.setOnQueryTextListener(this);
return true;
}
#Override
public boolean onQueryTextSubmit(String query) {
//Do something here
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
return false;
}
Pozzo Apps Answer is right
but for api below 11 and compat library you can use something like this :
MenuItem search_menu=(MenuItem)menu.findItem(R.id.action_search);
SearchView searchView =(SearchView)MenuItemCompat.getActionView(search_menu);
You can also apply setOnKeyListener on search view like as below:
searchview.setOnKeyListener(new View.OnKeyListener(
{
Public boolean onKey(View v, int keyCode, KeyEvent event)
{
if(event.getAction() == KeyEvent.ACTION_DOWN)
{
switch(keyCode)
{
Case KeyEvent.KECODE_ENTER:
// Apply action which you want on search key press on keypad
return true;
default:
break;
}
} return false;
}
});
You have to add new OnQueryTextListener, and implement onQueryTextSubmit. This also works in a fragment.
Example:
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.main_search, menu);
SearchView sv = (SearchView) menu.findItem(R.id.action_search).getActionView();
sv.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
//Do something here
Toast.makeText(getActivity(), "Search: " + query, Toast.LENGTH_SHORT ).show();
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
return false;
}
});
super.onCreateOptionsMenu(menu,inflater);
}
I am using a search field in the actionbar by reffering it to an xml in the layout folder called search_layout.xml.In the 2.3.3 version of android, there is an issue like the search icon is not shown in the keypad for the first time after I enter the text. Instead I have to click to the "enter" key, then on the textfield and then only the "search" icon appears. This does not happen in higher versions like 4.0.4 and 4.4.2 of android.
Here is the search_layout.xml:
And this xml is reffererd to in res>>menu>>menu.xml
<item
android:id="#+id/action_notification"
android:actionLayout="#layout/search_layout"
android:icon="#drawable/ic_searchicon"
android:orderInCategory="0"
android:showAsAction="always|collapseActionView"
android:title="Search"/>
This is the code snippet I am using for this in my activity called Activity_HomeScreen class.
public boolean onCreateOptionsMenu(Menu menu)
{
MenuInflater inflater = getSupportMenuInflater();
inflater.inflate(R.menu.menu, menu);
MenuItem itemListMap,itemRefresh;
editsearch = (EditText) menu.findItem(R.id.action_notification).getActionView();
editsearch.addTextChangedListener(textWatcher);
editsearch.setOnEditorActionListener(new OnEditorActionListener()
{
#Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event)
{
if (actionId == EditorInfo.IME_ACTION_SEARCH)
{
editsearch.clearFocus();
InputMethodManager imm = (InputMethodManager)Activity_HomeScreen.this.getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(editsearch.getWindowToken(), 0);
captureViepagerFragments(mVpContainer.getCurrentItem());
}
return false;
}
});
MenuItem menuSearch = menu.findItem(R.id.action_notification);
menuSearch.setOnActionExpandListener(new OnActionExpandListener()
{
// Menu Action Collapse
#Override
public boolean onMenuItemActionCollapse(MenuItem item)
{
// Empty EditText to remove text filtering
editsearch.setText("");
editsearch.clearFocus();
InputMethodManager imm = (InputMethodManager)Activity_HomeScreen.this.getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(editsearch.getWindowToken(), 0);
captureViepagerFragments(mVpContainer.getCurrentItem());
return true;
}
// Menu Action Expand
#Override
public boolean onMenuItemActionExpand(MenuItem item)
{
// Focus on EditText
editsearch.requestFocus();
// Force the keyboard to show on EditText focus
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);
return true;
}
});
return super.onCreateOptionsMenu(menu);
}
Solved this issue by doing like this:
public boolean onMenuItemActionExpand(MenuItem item)
{
editsearch.clearFocus();
editsearch.post(new Runnable() {
#Override
public void run() {
editsearch.requestFocus();
final InputMethodManager imm = (InputMethodManager) Activity_Cat_Products.this
.getSystemService(Context.INPUT_METHOD_SERVICE);
imm.showSoftInput(editsearch, InputMethodManager.SHOW_IMPLICIT);
}
});
return true;
}
I have added a button in the action bar, it works fine but if I press the physical menu button, the menu appears action_settings. Instead I want to use only the menu in the ActionBar and not that of the physical menu button.
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
getActivity().getMenuInflater().inflate(R.menu.menu_scegli, menu);
super.onCreateOptionsMenu(menu, inflater);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.add_c:
Intent intent = null;
intent = new Intent(getActivity(), Inserisci_.class);
startActivity(intent);
return true;
case R.id.action_settings:
return false;
default:
return super.onOptionsItemSelected(item);
}
}
You can try overriding onKeyDown method in your activity and returning true if the menu key was pressed - this will effectively prevent android from internally handling the menu key:
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if(keyCode == KeyEvent.KEYCODE_MENU) {
return true;
}
else {
return false;
}
}