I'm new to android trying to create a popup menu, but my app is crashing when I'm calling createMenu() in my activity which is extending to AppCompatActivity can anybody help me about the issue?
#SuppressLint("RestrictedApi")
public void createMenu() {
MenuBuilder menuBuilder = new MenuBuilder(this);
MenuInflater inflater = new MenuInflater(this);
inflater.inflate(R.menu.popup_menu, menuBuilder);
MenuPopupHelper optionsMenu = new MenuPopupHelper(this, menuBuilder);
optionsMenu.setForceShowIcon(true);
menuBuilder.setCallback(new MenuBuilder.Callback() {
#Override
public boolean onMenuItemSelected(MenuBuilder menu, MenuItem item) {
switch (item.getItemId()) {
case R.id.one:
return true;
default:
return false;
}
}
#Override
public void onMenuModeChange(MenuBuilder menu) {
}
});
optionsMenu.show();
}
In my XML
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="#+id/one"
android:icon="#drawable/ic_one"
android:title="One"
android:orderInCategory="0"/>
</menu>
calling it
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.option) {
createMenu();
}
}
getting error
java.lang.IllegalStateException: MenuPopupHelper cannot be used without an anchor
Add this to menu file android:showAsAction="always"
Use this menu file
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="#+id/one"
android:icon="#drawable/ic_one"
android:title="One"
android:showAsAction="always"
android:orderInCategory="0"/>
The issue is the null action view. So showing the menuitem as action view solves the issue
And call this using this code
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.option) {
createMenu(item.getActionView());
}
}
And change your createMenu() to
#SuppressLint("RestrictedApi")
public void createMenu(View v) {
PopupMenu popup = new PopupMenu(getActivity(), v);
MenuInflater inflater = popup.getMenuInflater();
inflater.inflate(R.menu.popup_menu, popup.getMenu());
popup.show();
}
Related
My toolbar has a searchView inside and both ate not registering any touch events on android 4.3 (in fact the event goes to the view below them). It should register homeAsUp, the searchView field (requestFocus) and X button to clear the field. For now what I am thinking is attaching listeners to these but is there a better way.
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
super.onPrepareOptionsMenu(menu);
MenuItem menuItem = menu.findItem(R.id.app_bar_search);
SearchView searchView = new SearchView(this);
searchView.setIconifiedByDefault(false);
searchView.setIconified(false);
searchView.requestFocus();
searchView.setMaxWidth(Integer.MAX_VALUE);
searchView.setQueryHint(getString(R.string.search));
ImageView searchViewIcon = (ImageView)searchView.findViewById(android.support.v7.appcompat.R.id.search_mag_icon);
ViewGroup linearLayoutSearchView =(ViewGroup) searchViewIcon.getParent();
linearLayoutSearchView.removeView(searchViewIcon);
menuItem.setActionView(searchView);
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) { return false; }
#Override
public boolean onQueryTextChange(String newText) {
presenter.queryChanged(newText);
return true;
}
});
return true;
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.search, menu);
return true;
}
menu/search.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="#+id/app_bar_search"
app:actionViewClass="android.support.v7.widget.SearchView"
android:icon="#drawable/ic_search_white_24dp"
android:title="#string/search"
app:showAsAction="always" />
</menu>
It works fine in newer versions though (don't know which one is the border between working/not working).
EDIT:
Attaching a listener to the searchview doesn't work either.
don't make new instance of SearchView fetch it from the menuItem:
replace this line
SearchView searchView = new SearchView(this);
with
SearchView searchView = (SearchView) menuItem .getActionView();
and remove following line:
menuItem.setActionView(searchView);
following code is working fine for me:
#Override
public boolean onCreateOptionsMenu( Menu menu) {
getMenuInflater().inflate( R.menu.menu_main, menu);
MenuItem myActionMenuItem = menu.findItem( R.id.action_search);
final SearchView searchView = (SearchView) myActionMenuItem.getActionView();
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
if (TextUtils.isEmpty(newText)) {
adapter.filter("");
listView.clearTextFilter();
} else {
adapter.filter(newText);
}
return true;
}
});
return true;
}
what about doing it using EditText ... it is going to run for all versions.
1- In YourActivity.xml remove android.support.design.widget.AppBarLayout attribute then add
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:popupTheme="#style/AppTheme.PopupOverlay" >
<EditText
android:id="#+id/search_edit_text"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginStart="24dp"
android:backgroundTint="[TINT_COLOR]"
android:hint="Search"
android:inputType="[INPUT TYPE]"
android:textColorHint="[HINT_COLOR]"
android:layout_marginEnd="16dp"/>
</android.support.v7.widget.Toolbar>
2-In YourActivity.java code add this listener on search edittext
private TextWatcher searchTextWatcher =
new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
#Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
presenter.queryChanged(charSequence.toString());
}
#Override
public void afterTextChanged(Editable editable) {
}
};
I'm new to Android Studio and I'm having many problems doing a menubar. I have searched for many solutions but they weren't going right.
I tried this but I don't know what to do next:
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
public boolean onCreateOptionsMenu (Menu menu) {
super.onCreateOptionsMenu(menu);
//Inflate the menu; this adds item to the action
//bar if its present
getMenuInflater().inflate(R.menu.my_context_menu, menu);
String title = "Item Three";
int groupId = Menu.NONE;
int itemID = MENU_ITEM;
int order = 103;
menu.add(groupId, itemId, order, title);
return true;
}
First create a main_menu.xml file in your menu rescource folder (or any other...) :
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="#+id/one"
android:title="Button 1"/>
<item android:id="#+id/two"
android:title="Button 2"/>
</menu>
Then
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main_menu, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle item selection
switch (item.getItemId()) {
case R.id.one:
// do something
return true;
case R.id.two:
//do something
return true;
default:
return super.onOptionsItemSelected(item);
}
}
I have a tabbed activity with two tabs, and when I am in the second one I want to have a search action be shown in the actionbar. I do not want it to show in the first tab, only the second.
This is what I have for my LaunchActivity.java
public class LaunchActivity extends ActionBarActivity {
ViewPager pager;
int Numboftabs = 2;
boolean searchDisabled = false;
...
#Override
protected void onCreate(Bundle savedInstanceState) {
...
pager = (ViewPager) findViewById(R.id.pager);
pager.setAdapter(adapter);
pager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
if (position == 0) {
searchDisabled = true;
}
}
#Override
public void onPageScrollStateChanged(int state) {
}
});
}
...
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu_launch, menu);
return super.onCreateOptionsMenu(
}
...
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
MenuItem search = menu.findItem(R.id.action_search);
if(searchDisabled) {
search.setEnabled(false);
}
super.onPrepareOptionsMenu(menu);
return true;
}
}
menu_launch.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context=".LaunchActivity">
<item android:id="#+id/action_search"
android:title="#string/action_search"
android:icon="#drawable/ic_action_search"
app:showAsAction="ifRoom" />
<item android:id="#+id/action_settings"
android:title="#string/action_settings"
android:orderInCategory="100"
app:showAsAction="never" />
</menu>
Does anyone know why this is not working? The search action shows up but doesn't hide when on the first tab.
Approach:
You can solve this by adding a class variable for the MenuItem.
MenuItem search;
Then in onPrepareOptionsMenu you only initialize it:
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
search = menu.findItem(R.id.action_search);
super.onPrepareOptionsMenu(menu);
return true;
}
Then in your onPageChangeListener you do this to show/hide the search item:
#Override
public void onPageSelected(int position) {
if (position == 0) {
search.setEnabled(false);
search.setVisible(false);
} else {
search.setEnabled(true);
search.setVisible(true);
}
}
That should achieve what you want to do.
Approach:
Alternative better solution would be to set up the options menu in the fragment:
Add hasOptionsMenu(true) to your Fragment:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
And set the visibility in onCreateOptionsMenu (also in the fragment!):
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
MenuItem search = menu.findItem(R.id.action_search);
search.setEnabled(false);
search.setVisible(false);
super.onCreateOptionsMenu(menu, inflater);
}
I am trying to make a collapsible EditText in the Action Bar. I have followed the Android Developers guide. But when I click on my search icon, nothing happens.
What can I do?
Here is my code.
The activity:
public class ElementPagerActivity extends ActionBarActivity
implements ElementListFragment.onElementClickListener,
CalculateFragment.OnCalculateClickListener{
ViewPager theViewPager;
private ActionBar actionBar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
actionBar = getSupportActionBar();
theViewPager = new ViewPager(this);
theViewPager.setId(0x1);
theViewPager.setAdapter(new FragmentStatePagerAdapter(getSupportFragmentManager()) {
#Override
public Fragment getItem(int position) {
if(position == 0){
return new ElementListFragment();
} return Element.values()[position - 1].toFragment();
}
#Override
public int getCount() {
return Element.values().length + 1;
}
});
theViewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int i, float v, int i2) {
}
#Override
public void onPageSelected(int position) {
invalidateOptionsMenu();
if(position == 0){
actionBar.setTitle(R.string.Element_info_activity_label);
actionBar.selectTab(null);
} else {
actionBar.setTitle(Element.values()[position - 1].getName());
actionBar.selectTab(actionBar.getTabAt(position - 1));
}
}
#Override
public void onPageScrollStateChanged(int i) {
}
});
actionBar = actionBar;
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
ActionBar.TabListener tabListener = new ActionBar.TabListener(){
#Override
public void onTabSelected(ActionBar.Tab tab, android.support.v4.app.FragmentTransaction fragmentTransaction) {
int position = tab.getPosition();
theViewPager.setCurrentItem(position + 1, true);
}
#Override
public void onTabUnselected(ActionBar.Tab tab, android.support.v4.app.FragmentTransaction fragmentTransaction) {
}
#Override
public void onTabReselected(ActionBar.Tab tab, android.support.v4.app.FragmentTransaction fragmentTransaction) {
int position = tab.getPosition();
theViewPager.setCurrentItem(position + 1, true);
}
};
for (int i = 0; i < Element.values().length; i++){
actionBar.addTab(
actionBar.newTab()
.setText(Element.values()[i].getName())
.setTabListener(tabListener));
}
theViewPager.setCurrentItem(0);
actionBar.selectTab(null);
setContentView(theViewPager);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.element_pager, menu);
menu.findItem(R.id.pager_activity_show_list_action).setVisible(!(theViewPager.getCurrentItem() == 0));
menu.findItem(R.id.pager_activity_edit_text_action).expandActionView();
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.pager_activity_show_list_action){
theViewPager.setCurrentItem(0, true);
return true;
} else if (id == R.id.pager_activity_edit_text_action){
return false;
}
return super.onOptionsItemSelected(item);
}
#Override
public void onBackPressed() {
if (theViewPager.getCurrentItem() == 0){
super.onBackPressed();
} else {
theViewPager.setCurrentItem(0);
}
}
#Override
public void onElementClick(int position) {
theViewPager.setCurrentItem(position + 1, true);
}
#Override
public Element onRequestElement() {
return Element.values()[theViewPager.getCurrentItem() - 1];
}
}
Menu resources:
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:context=".MainActivity" >
<item android:id="#+id/pager_activity_edit_text_action"
app:showAsAction="always|collapseActionView"
android:title="text here"
android:icon="#android:drawable/ic_menu_search"
android:actionLayout="#layout/test"/>
<item android:id="#+id/pager_activity_show_list_action"
android:title="#string/action_bar_pager_show_list"
android:orderInCategory="100"
app:showAsAction="ifRoom|withText" />
</menu>
Action layout (test.xml):
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="element"
android:inputType="textCapWords"/>
</LinearLayout>
And here is a short film demonstrating the problem.
I appreciate all answers.
Greetings from the Netherlands
You can use a SearchView, which will make things a bit easier for you.
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="#+id/search"
android:title="#string/search_title"
android:icon="#drawable/ic_search"
android:showAsAction="collapseActionView|ifRoom"
android:actionViewClass="android.widget.SearchView" />
</menu>
more here: http://developer.android.com/training/search/setup.html
I have created an action bar with two Menu Items. When I try using an intent for the buttons they don't work. When click on the menu item, web page will be loaded.How to do it.
main.xml:
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:yourapp="http://schemas.android.com/apk/res-auto" >
<item
android:id="#+id/action_settings"
android:orderInCategory="100"
yourapp:showAsAction="never"
android:title="#string/action_settings"/>
<item
android:id="#+id/camera"
android:icon="#drawable/ic_menu_camera"
android:title="Camera"
yourapp:showAsAction="always"/>
<item
android:id= "#+id/emoticons"
android:icon="#drawable/ic_menu_emoticons"
android:title="Emoticon"
yourapp:showAsAction="always"/>
</menu>
MainActivity.java:
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main, menu);
return super.onCreateOptionsMenu(menu);
}
public boolean OnOptionsItemSelected(MenuItem item){
switch(item.getItemId()) {
case R.id.camera:
startActivity(new Intent(android.content.Intent.ACTION_VIEW, Uri.parse("http://www.google.com/")));
return true;
case R.id.emoticons:
startActivity(new Intent(android.content.Intent.ACTION_VIEW, Uri.parse("http://www.google.com/")));
return true;
default:
return super.onOptionsItemSelected(item);
}
}
}
Thanks
Your method is overridden with wrong name (thus is not overridden but is a different method) and thus is not called by menu.
public boolean OnOptionsItemSelected(MenuItem item) {
Should be starting with small "o"
#Override
public boolean onOptionsItemSelected(MenuItem item) {
You should use Override annotation to avoid such mistakes.