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);
}
Related
My activity has a menu which includes a SearchView, and I'm setting the SearchView visibility programmatically. I'm using savedInstanceState to preserve the Visibility value eg between rotations, but this aspect is not working: in the scenario where the SearchView visibility is GONE before rotation, the SearchView icon is showing after rotation.
If I debug and evaluate mSearchView.getVisibility() after picking up its value from savedInstanceState, it appears to be correctly set to 8.
There are lines in my code which setVisibility(View.VISIBLE), but none of them are hit between the value from savedInstanceState being set, and the rotated layout appearing to the user.
Layout:
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<!-- "Mark Favorite", should appear as action button if possible -->
<item android:id="#+id/action_search"
android:title="#string/action_search"
app:actionViewClass="androidx.appcompat.widget.SearchView"
app:showAsAction="ifRoom"/>
Activity (onSaveInstanceState):
public void onSaveInstanceState(Bundle outState){
super.onSaveInstanceState(outState);
switch (mSearchView.getVisibility()){
case View.VISIBLE:
outState.putInt("SearchViewVisibility",View.VISIBLE);
case View.GONE:
outState.putInt("SearchViewVisibility",View.GONE);
};
}
Activity (Menu setup):
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main, menu);
//setup SearchView and callbacks
final MenuItem searchItem = menu.findItem(R.id.action_search);
mSearchView = (SearchView) searchItem.getActionView();
if(mSavedInstanceState != null){
switch (mSavedInstanceState.getInt("SearchViewVisibility")){
case View.VISIBLE:
mSearchView.setVisibility(View.VISIBLE);
case View.INVISIBLE:
mSearchView.setVisibility(View.INVISIBLE);
case View.GONE:
mSearchView.setVisibility(View.GONE);
}
}
mSearchView.setOnQueryTextListener(new SearchView.OnQueryTextListener(){
#Override
public boolean onQueryTextSubmit(String query) {
SetFragmentAndFilter(query);
return true;
}
#Override
public boolean onQueryTextChange(String query) {
// check whether this change is clearing all text from the search
if(query.isEmpty()){
// close the searchView
mSearchView.post(new Runnable(){
#Override
public void run(){
mSearchView.clearFocus();
}
});
mSearchView.setIconified(true);
}
//have the list match the new query text
SetFragmentAndFilter(query);
return true;
}
});
return true;
}
Would really appreciate any thoughts!
You should use setVisible method to set the visibility of a menu item.
Change your code to
// Add this property
MenuItem mSearchMenuItem;
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putBoolean("isVisible", mSearchMenuItem.isVisible());
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main, menu);
//setup SearchView and callbacks
mSearchMenuItem = menu.findItem(R.id.action_search);
if (mSavedInstanceState != null) {
boolean isVisible = mSavedInstanceState.getBoolean("isVisible", true);
mSearchMenuItem.setVisible(isVisible);
}
mSearchView = (SearchView) mSearchMenuItem.getActionView();
mSearchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
return true;
}
#Override
public boolean onQueryTextChange(String query) {
// check whether this change is clearing all text from the search
if (query.isEmpty()) {
// close the searchView
mSearchView.post(new Runnable() {
#Override
public void run() {
mSearchView.clearFocus();
}
});
mSearchView.setIconified(true);
}
return true;
}
});
return true;
}
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 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.