I'm trying to implement ActionBarSherlock with tabs but allow a pulldown menu in the action bar on certain tabs. I've read that the only way to get both is to create a custom actionProvider for the pulldown. Here is the code I wrote to implement:
menu_with_dropdown.xml (with a separate overflow menu that is working fine)
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="#+id/motivate_picker"
android:showAsAction="always"
android:title="Right Here"
android:actionProviderClass=".ActionBarSpinner">
</item>
<item
android:id="#+id/menu_item"
android:showAsAction="always"
android:icon="#drawable/action_bar_plus_icon">
<menu>
<item android:id="#+id/menu_1"
android:title="#string/menu_1" />
<item android:id="#+id/menu_2"
android:title="#string/menu_2" />
<item android:id="#+id/menu_3"
android:title="#string/menu_3"/>
<item android:id="#+id/menu_4"
android:title="#string/menu_4"/>
</menu>
</item>
</menu>
The tab fragment that uses this pulldown inflates it here
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu,inflater);
menu.clear();
getSherlockActivity().getSupportActionBar().setDisplayShowTitleEnabled(false);
getSherlockActivity().getSupportMenuInflater().inflate(R.menu.menu_with_dropdown, menu);
}
ActionBarSpinner.java
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import com.actionbarsherlock.view.ActionProvider;
import com.actionbarsherlock.view.MenuItem;
import com.actionbarsherlock.view.SubMenu;
public class ActionBarSpinner extends ActionProvider implements
MenuItem.OnMenuItemClickListener {
Context context_;
public ActionBarSpinner(Context context) {
super(context);
context_ = context;
}
#Override
public View onCreateActionView() {
LayoutInflater layoutInflater = LayoutInflater.from(context_);
View view = layoutInflater.inflate(R.layout.actionbar_menu,null);
//return view; //Will have formatted pulldown but not register clicks for submenu
return null; //Will register clicks and expand submenu but not be formatted as desired
}
#Override
public boolean onPerformDefaultAction() {
return false;
}
#Override
public boolean hasSubMenu() {
return true;
}
#Override
public void onPrepareSubMenu(SubMenu subMenu) {
MenuItem item = subMenu.add("Test1");
item.setOnMenuItemClickListener(this);
item = subMenu.add("Test3");
item.setOnMenuItemClickListener(this);
item = subMenu.add("Test2");
item.setOnMenuItemClickListener(this);
}
#Override
public boolean onMenuItemClick(MenuItem item) {
return true;
}
}
actionbar_menu.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal"
style="#android:style/Widget.ActionButton"
android:clickable="true">
<TextView
android:id="#+id/motivate_title"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Friend Picker"
/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|right"
android:src="#drawable/switcher_arrow"/>
</LinearLayout>
So the problem arises when I call onCreateActionView() in ActionBarSpinner. If I return the inflated View of actionbar_menu.xml, it never expands the subMenu that I created. If I return null in onCreateActionView(), the submenu expands when I click on it but it doesn't have the custom layout I made (it actually shows nothing). Any help would be appreciated.
you have to return null in order for the onPrepareSubMenu() being called.
Then, all these setups in onCreateActionView() need to go in to onCreateOptionsMenu() in probably MainActivity.
For example,
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main_activity, menu);
// Get the SearchView and set the searchable configuration
SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
SearchView searchView = (SearchView) menu.findItem(R.id.menu_search)
.getActionView();
searchView.setSearchableInfo(searchManager
.getSearchableInfo(getComponentName()));
// Override the default language icon to the language is being used
MenuItem mI = menu.findItem(R.id.menu_locale);
Locale locale = Locale.getDefault();
String locLan = locale.getLanguage();
if (locLan.equals(Locale.CHINESE.getLanguage())) {
mI.setIcon(R.drawable.insready);
} else if (locLan.equals(Locale.ENGLISH.getLanguage())) {
mI.setIcon(R.drawable.ic_action_locale_en);
} else if (locLan.equals(Locale.FRENCH.getLanguage())) {
mI.setIcon(R.drawable.ic_action_search);
}
return true;
}
Related
I'm not able to dispay MenĂ¹ in my main Activity and all the other Activities.
This is my main.xml:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:background="#color/cardview_dark_background">
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
card_view:cardBackgroundColor="#color/cardview_light_background">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/articoli"
android:onClick="visualizzaArticoli"
android:background="#null"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Articoli"
android:layout_gravity="center_vertical"
android:layout_marginLeft="50dp"/>
</LinearLayout>
</android.support.v7.widget.CardView>
</LinearLayout>
This is my main.java file:
package com.mcsolution.easymanagementandroid.main;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.View;
import android.widget.Toast;
import com.mcsolution.easymanagementandroid.R;
import com.mcsolution.easymanagementandroid.beans.Program;
import com.mcsolution.easymanagementandroid.connection.MyDatabase;
import com.mcsolution.easymanagementandroid.utility.SyncDati;
public class Main extends Activity {
public MyDatabase db;
public ProgressDialog dialog;
public String url="";
private static final Intent SCAN_INTENT = new Intent("com.google.zxing.client.android.SCAN");
#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.care_home, menu);
return super.onCreateOptionsMenu(menu);
}
private void apriConnessioneDB(){
db=new MyDatabase(getApplicationContext());
db.open(); //apriamo il db
}
public void visualizzaArticoli(View view){
Intent intent = new Intent(this, com.mcsolution.easymanagementandroid.articoli.viewArticoli.class);
startActivity(intent);
}
}
This is my menu care_home.xml:
<?xml version="1.0" encoding="utf-8"?>
<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_logout"
android:orderInCategory="100"
android:title="Logout"/>
</menu>
If I try to start my application, I don't have any error but I can't to see MenuBar. I have try to set a debug point into OnCreateOptionMenu method but, the method is never called.
How can I fixed it ?
You need to return true; in onCreateOptionsMenu() as shown in the code below
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.care_home, menu);
return true;
}
Simply use this:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.care_home, menu);
return true;
}
Your activity class extends Activity, not AppCompatActivity. The default theme for these activities does not include an Action Bar, which is where the menu would live. You will need to add a <Toolbar> to your activity's layout file, and then call setActionBar() from your onCreate() method.
For example, add this as the first child of your top-level <LinearLayout> tag:
<Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
And add this just after you call setContentView() in your onCreate():
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setActionBar(toolbar);
Now you will have an Action Bar in your activity, and so your menu will appear.
You should return true instead of super like this:
#SuppressLint("RestrictedApi")
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);
if (menu != null) {
}
return true;
}
Hope it helps.
You have to use both methods on your activity
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
return super.onOptionsItemSelected(item);
}
I am trying to imitate the style of how search is handled by the gmail app which looks as follows:
As shown above there is a (blue) blinking cursor after the search query in the searchView.
My respective code looks like this:
SearchReslutActivity.class
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu, menu);
SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
SearchView searchView = (SearchView) menu.findItem(R.id.search).getActionView();
searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
searchView.setQuery(getIntent().getStringExtra(SearchManager.QUERY), false);
searchView.setIconified(false);
searchView.clearFocus();
return true;
}
menu/search_menu.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="#+id/search"
android:title="#string/search_title"
app:actionViewClass="android.support.v7.widget.SearchView"
app:showAsAction="always" /> </menu>
xml/searchable.xml
<searchable xmlns:android="http://schemas.android.com/apk/res/android"
android:hint="#string/hint"
android:includeInGlobalSearch="true"
android:inputType="textCapWords"
android:label="#string/app_name"
android:searchSuggestAuthority="com.webaddress.myproject.data.Provider"
android:searchSuggestIntentAction="android.intent.action.VIEW"
android:searchSuggestIntentData="content://com.webaddress.myproject.data.Provider/table"
android:searchSuggestSelection=" ?"
android:searchSuggestThreshold="1" />
The above code achieves the same look as what is displayed in the gmail app except for having a blinking cursor. How can I add such a blinking cursor without requesting focus on the searchView (which in turn will make the soft keyboard pop up again)?
Thanks!
Add this code in onCreate()
searchView.setOnFocusChangeListener(new View.OnFocusChangeListener() {
#Override
public void onFocusChange(View v, boolean hasFocus) {
if (!searchView.hasFocus()) {
//this if condition is true when searchview lost focus...
int searchSrcText = searchView.getContext().getResources()
.getIdentifier("android:id/search_src_text", null, null);
EditText editText = (EditText) searchView.findViewById(searchSrcText);
editText.setCursorVisible(true);
searchView.setActivated(true);
searchView.setPressed(true);
}
}
});
Thanks to #Azizbekian's answer (which did not work on its own for me) I finally got it working with the following code (in an empty project - support libs 25.3.0):
java/MainActivity
package com.yourwebpage.yourapplication;
import android.app.SearchManager;
import android.os.Bundle;
import android.support.v4.view.MenuItemCompat;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.SearchView;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
public class MainActivity extends AppCompatActivity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
public boolean onCreateOptionsMenu(final Menu menu) {
getMenuInflater().inflate(R.menu.search_menu, menu);
return true;
}
#Override
public boolean onPrepareOptionsMenu(final Menu menu) {
MenuItem menuItem = menu.findItem(R.id.search);
SearchView searchView = (SearchView) MenuItemCompat.getActionView(menuItem);
searchView.setQuery(getIntent().getStringExtra(SearchManager.QUERY), false);
searchView.setIconified(false);
SearchView.SearchAutoComplete searchAutoComplete =
(SearchView.SearchAutoComplete) searchView.findViewById(R.id.search_src_text);
searchAutoComplete.setOnFocusChangeListener(new View.OnFocusChangeListener() {
#Override
public void onFocusChange(final View v, final boolean hasFocus) {
v.requestFocus();
}
});
searchView.clearFocus();
return super.onPrepareOptionsMenu(menu);
}
}
res/layout/activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.yourwebpage.yourapplication.MainActivity">
</android.support.constraint.ConstraintLayout>
res/menu/search_menu.xml
<?xml version="1.0" encoding="utf-8"?>
<menu
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="#+id/search"
android:title="Search"
app:actionViewClass="android.support.v7.widget.SearchView"
app:showAsAction="always"/>
</menu>
manifests/AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.yourwebpage.yourapplication">
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".MainActivity"
android:windowSoftInputMode="stateAlwaysHidden">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
I am posting this rather comprehensive solution in the hope of making it reproducible thereby.
Try this,
searchView.setOnSearchClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
searchView.setImeOptions(EditorInfo.IME_ACTION_SEARCH);
}
});
Perform this:
#Override
public boolean onCreateOptionsMenu(final Menu menu) {
getMenuInflater().inflate(R.menu.search_menu, menu);
return true;
}
#Override
public boolean onPrepareOptionsMenu(final Menu menu) {
MenuItem menuItem = menu.findItem(R.id.search);
SearchView searchView = (SearchView) MenuItemCompat.getActionView(menuItem);
SearchView.SearchAutoComplete searchAutoComplete =
(SearchView.SearchAutoComplete) searchView.findViewById(R.id.search_src_text);
searchAutoComplete.setOnFocusChangeListener(new View.OnFocusChangeListener() {
#Override
public void onFocusChange(final View v, final boolean hasFocus) {
v.requestFocus();
}
});
return super.onPrepareOptionsMenu(menu);
}
search_menu.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="#+id/search"
android:title="Search"
app:actionViewClass="android.support.v7.widget.SearchView"
app:showAsAction="ifRoom"/>
</menu>
Tested with support libs version 25.3.0.
This code is for custom toolbar
SearchView.SearchAutoComplete searchTextView = mSearchView.findViewById(R.id.search_src_text);
try {
Field mCursorDrawableRes = TextView.class.getDeclaredField("mCursorDrawableRes");
mCursorDrawableRes.setAccessible(true);
mCursorDrawableRes.set(searchTextView, 0);
//This sets the cursor resource ID to 0 or #null which will make it visible on white background
} catch (Exception e) {
e.printStackTrace();
}
i am trying for hours to setup a simple android.support.v7.widget.SearchView in a bottom (secondary) android.support.v7.widget.ToolBar.
I am already using another Toolbar up top set up as an ActionBar, so i cannot use the onCreateOptionsMenu callback on activity, instead i have to set up an OnMenuItemClickListener() . I have read the Android SearchView Tutorial, this tutorial about Toolbars.
Related Code,
simplified HomepageActivity
package something.somethingelse.activities;
import android.app.ProgressDialog;
import android.app.SearchManager;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.SearchView;
import android.support.v7.widget.SearchView.OnCloseListener;
import android.support.v7.widget.SearchView.OnQueryTextListener;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.EditText;
import android.widget.Toast;
public class HomepageActivity extends AppCompatActivity {
protected static final String TAG = "HomepageActivity";
private Toolbar mTopToolbar;
private Toolbar mBottomToolbar;
private FloatingActionButton mFab;
private Context mContext;
#Override
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mTopToolbar = (Toolbar) findViewById(R.id.topToolbar);
setSupportActionBar(mTopToolbar);
mBottomToolbar = (Toolbar) findViewById(R.id.bottomToolbar);
mBottomToolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
#Override
public boolean onMenuItemClick(MenuItem menuItem) {
SearchManager searchManager = (SearchManager) HomepageActivity.this.getSystemService(Context.SEARCH_SERVICE);
SearchView searchView = null;
if (menuItem != null) {
Log.d(TAG, "menuItem != null");
searchView = (SearchView) menuItem.getActionView();
}
if (searchView != null) {
Log.d(TAG, "searchView != null");
searchView.setSearchableInfo(searchManager.getSearchableInfo(HomepageActivity.this.getComponentName()));
}
searchView.setOnCloseListener(new OnCloseListener() {
#Override
public boolean onClose() {
mBottomToolbar.setVisibility(View.GONE);
return false;
}
});
searchView.setOnQueryTextListener(new OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String arg0) {
Log.d(TAG, "Submited: "+arg0);
return false;
}
#Override
public boolean onQueryTextChange(String arg0) {
Log.d(TAG, "Changed: "+arg0);
return false;
}
});
return false;
}
});
mBottomToolbar.inflateMenu(R.menu.bottom_toolbar);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.action_bar, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle presses on the action bar items
if (mDrawerToggle.onOptionsItemSelected(item)) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
simplified Homepage Layout
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:guide="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<android.support.v7.widget.Toolbar
android:id="#+id/topToolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:background="#color/white"
guide:elevation="4dp"
android:minHeight="?attr/actionBarSize"
guide:theme="#style/Toolbar_Theme" >
<ImageView
android:id="#+id/ivAb_logo"
android:layout_width="wrap_content"
android:layout_height="?attr/actionBarSize"
android:paddingBottom="10dp"
android:paddingLeft="10dp"
android:paddingRight="58dp"
android:paddingTop="10dp"
android:src="#drawable/generic_logo" />
</android.support.v7.widget.Toolbar>
<android.support.v4.widget.DrawerLayout
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#+id/topToolbar" >
<RelativeLayout
android:id="#+id/homepage_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/homepage_background"
android:orientation="vertical" >
<android.support.v7.widget.Toolbar
android:id="#+id/bottomToolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:background="#color/primaryDark"
guide:elevation="4dp" />
</RelativeLayout>
<!-- The navigation drawer -->
<ListView
android:id="#+id/left_drawer"
android:layout_width="220dp"
android:layout_height="fill_parent"
android:layout_gravity="start"
android:background="#60BBBBBB"
android:choiceMode="singleChoice"
android:divider="#FFFFFF"
android:dividerHeight="1px" />
</android.support.v4.widget.DrawerLayout>
menu bottom_toolbar.xml
<menu
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:guide="http://schemas.android.com/apk/res-auto">
<item
android:id="#+id/action_search"
android:title="#string/search"
android:icon="#drawable/ic_search_white"
guide:actionViewClass="android.support.v7.widget.SearchView"
guide:showAsAction="always">
</item>
searchable.xml
<?xml version="1.0" encoding="utf-8"?>
<searchable xmlns:android="http://schemas.android.com/apk/res/android"
android:hint="#string/search"
android:label="#string/app_name"
/>
AndroidManifest.xml related part
<activity
android:name="something.somethingelse.activities.HomepageActivity"
android:label="#string/app_name"
android:screenOrientation="portrait"
android:theme="#style/Theme.Default" >
<intent-filter>
<action android:name="something.somethingelse.activities.HomepageActivity" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.SEARCH" />
</intent-filter>
<meta-data
android:name="android.app.searchable"
android:resource="#xml/searchable" />
</activity>
If i run it like that, i get a SearchView but without my android:icon="#drawable/ic_search_white", instead i get the google SearchView icon, if i tap it i get a nice edit text, with clear and search functions, but no matter what i input or press, NONE of the Log.d inside the Toolbar.OnMenuItemClickListenergets fired up. (I cannot post images because of reputation).
If i use android:actionViewClass="android.support.v7.widget.SearchView" instead of guide:actionViewClass="android.support.v7.widget.SearchView" i get my android:icon="#drawable/ic_search_white" , if i tap it, i get an NPE on searchView.setOnCloseListener(new OnCloseListener() { because searchView is null .
I tried doing whats on this related question here, and this but no success so far.
Updated 23/09/15
I could not find any good solution, so, since i only wanted to get the SearchView item i decided to hack into it like so:
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if(savedInstanceState==null){
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.add(R.id.dlHomepageSpace, HomepageFragment.newInstance(mLanguage), HOMEPAGE_BUTTONS_TAG);
fragmentTransaction.commit();
}
mSearchState = SearchState.NOSEARCH;
mBottomToolbar = (Toolbar) findViewById(R.id.bottomToolbar);
mBottomToolbar.inflateMenu(R.menu.bottom_toolbar);
// Here we set the search view toolbar functions
if(mBottomToolbar.getMenu().size() > 0){
SearchManager searchManager = (SearchManager) HomepageActivity.this.getSystemService(Context.SEARCH_SERVICE);
MenuItem searchMenuItem = mBottomToolbar.getMenu().getItem(mBottomToolbar.getMenu().size()-1);
mSearchView = (SearchView) searchMenuItem.getActionView();
if (mSearchView != null) {
mSearchView.setSearchableInfo(searchManager.getSearchableInfo(HomepageActivity.this.getComponentName()));
}
mSearchView.setOnCloseListener(new OnCloseListener() {
#Override
public boolean onClose() {
Log.d(TAG, "onClose");
mBottomToolbar.getMenu().getItem(mBottomToolbar.getMenu().size()-1).collapseActionView();
switchToFab();
return false;
}
});
MenuItemCompat.setOnActionExpandListener(searchMenuItem, new MenuItemCompat.OnActionExpandListener() {
#Override
public boolean onMenuItemActionExpand(MenuItem item) {
Log.d(TAG, "onMenuItemActionExpand");
return true; // KEEP IT TO TRUE OR IT DOESN'T OPEN !!
}
#Override
public boolean onMenuItemActionCollapse(MenuItem item) {
Log.d(TAG, "onMenuItemActionCollapse");
switchToFab();
return true;
}
});
}
}
#Override
protected void onNewIntent(Intent intent) {
Log.d(TAG, "onNewIntent");
if(isSearchAction(intent)){
ArrayList<Detail> list = (ArrayList<Detail>) getListData(intent.getStringExtra(SearchManager.QUERY));
if(list.isEmpty()){
Toast.makeText(this, R.string.no_search_results_en, Toast.LENGTH_LONG).show();
}
} else {
ExtendedListFragment searchFragment = (ExtendedListFragment) getSupportFragmentManager().findFragmentByTag(HOMEPAGE_SEARCH_TAG);
mResultsList = list;
mSearchState = SearchState.SEARCH_LIST_SCREEN;
if(searchFragment==null){
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.addToBackStack(null);
fragmentTransaction.replace(R.id.dlHomepageSpace, ExtendedListFragment.newInstance(list), HOMEPAGE_SEARCH_TAG);
fragmentTransaction.commit();
} else {
searchFragment.setDetailList(list);
}
}
}
}
private boolean isSearchAction(Intent intent) {
Log.d(TAG, "handleIntent");
if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
Log.d(TAG, "ACTION_SEARCH");
return true;
}
return false;
}
In essence, i just look into the toolbar, and obtain the one and only Item into it, i cast it as a MenuItem and then i get the SearchView as the ActionView of the MenuItem.
Like that it works and i do not have to use setOnMenuItemClickListener() . When i tap in the view, i can type into it (i do not need a mSearchView.OnQueryTextListener but, i have seen it working) , when i press the magnifying glass on the keyboard i get the onNewIntent() call working.
Am having toolbar in my activity, I had tried to add Search View from Menu but am unable to add Search View in toolbar, How to add Search View in my activity toolbar.?
I have done with Fragment by this way.
I did with onTextChangeListener of search view, just check in your Logcat.
Screenshot reference:
menu.xml - (res -> menu)
<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=".HomeActivity">
<item
android:id="#+id/action_search"
android:icon="#android:drawable/ic_menu_search"
android:title="Search"
app:actionViewClass="android.support.v7.widget.SearchView"
app:showAsAction="always" />
</menu>
MainFragment.java
public class MainFragment extends Fragment {
private SearchView searchView = null;
private SearchView.OnQueryTextListener queryTextListener;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_main, container, false);
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.menu, menu);
MenuItem searchItem = menu.findItem(R.id.action_search);
SearchManager searchManager = (SearchManager) getActivity().getSystemService(Context.SEARCH_SERVICE);
if (searchItem != null) {
searchView = (SearchView) searchItem.getActionView();
}
if (searchView != null) {
searchView.setSearchableInfo(searchManager.getSearchableInfo(getActivity().getComponentName()));
queryTextListener = new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextChange(String newText) {
Log.i("onQueryTextChange", newText);
return true;
}
#Override
public boolean onQueryTextSubmit(String query) {
Log.i("onQueryTextSubmit", query);
return true;
}
};
searchView.setOnQueryTextListener(queryTextListener);
}
super.onCreateOptionsMenu(menu, inflater);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_search:
// Not implemented here
return false;
default:
break;
}
searchView.setOnQueryTextListener(queryTextListener);
return super.onOptionsItemSelected(item);
}
}
Done
menu_main.xml:
<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" />
\res\xml\searchable.xml:
<searchable xmlns:android="http://schemas.android.com/apk/res/android"
android:label="#string/app_name"
android:hint="#string/search_hint" />
AndroidManifest.xml:
<activity
android:name=".MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<meta-data android:name="android.app.searchable"
android:resource="#xml/searchable" />
</activity>
styles.xml:
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="android:Theme.Holo.Light">
<!-- Customize your theme here. -->
</style>
MainActivity.java:
package com.example.searchview;
import android.app.Activity;
import android.app.SearchManager;
import android.content.Context;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.SearchView;
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) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
// Associate searchable configuration with the SearchView
SearchManager searchManager =
(SearchManager) getSystemService(Context.SEARCH_SERVICE);
SearchView searchView =
(SearchView) menu.findItem(R.id.search).getActionView();
searchView.setSearchableInfo(
searchManager.getSearchableInfo(getComponentName()));
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.
return super.onOptionsItemSelected(item);
}
}
I need to create SearchView from my arrayList<String> and show the suggestions in the drop-down list same this
I look for tutorials that explain step by step how to build a SearchView in a action bar.
I have read the documentation and following the example google but it was not useful to me.
I have created the search
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="#+id/action_search"
android:title="Search"
android:icon="#android:drawable/ic_menu_search"
android:showAsAction="always"
android:actionViewClass="android.widget.SearchView" />
</menu>`
But I do not know how to set the parameters of the array of strings.
I tried to retrieve the result in a different Activity but not work.
It took a while to put together a solution for this, but have found this is the easiest way to get it to work in the way that you describe. There could be better ways to do this, but since you haven't posted your activity code I will have to improvise and assume you have a list like this at the start of your activity:
private List<String> items = db.getItems();
ExampleActivity.java
private List<String> items;
private Menu menu;
#Override
#TargetApi(Build.VERSION_CODES.HONEYCOMB)
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.example, menu);
this.menu = menu;
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
SearchManager manager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
SearchView search = (SearchView) menu.findItem(R.id.search).getActionView();
search.setSearchableInfo(manager.getSearchableInfo(getComponentName()));
search.setOnQueryTextListener(new OnQueryTextListener() {
#Override
public boolean onQueryTextChange(String query) {
loadHistory(query);
return true;
}
});
}
return true;
}
// History
#TargetApi(Build.VERSION_CODES.HONEYCOMB)
private void loadHistory(String query) {
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
// Cursor
String[] columns = new String[] { "_id", "text" };
Object[] temp = new Object[] { 0, "default" };
MatrixCursor cursor = new MatrixCursor(columns);
for(int i = 0; i < items.size(); i++) {
temp[0] = i;
temp[1] = items.get(i);
cursor.addRow(temp);
}
// SearchView
SearchManager manager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
final SearchView search = (SearchView) menu.findItem(R.id.search).getActionView();
search.setSuggestionsAdapter(new ExampleAdapter(this, cursor, items));
}
}
Now you need to create an adapter extended from CursorAdapter:
ExampleAdapter.java
public class ExampleAdapter extends CursorAdapter {
private List<String> items;
private TextView text;
public ExampleAdapter(Context context, Cursor cursor, List<String> items) {
super(context, cursor, false);
this.items = items;
}
#Override
public void bindView(View view, Context context, Cursor cursor) {
text.setText(items.get(cursor.getPosition()));
}
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.layout.item, parent, false);
text = (TextView) view.findViewById(R.id.text);
return view;
}
}
A better way to do this is if your list data is from a database, you can pass the Cursor returned by database functions directly to ExampleAdapter and use the relevant column selector to display the column text in the TextView referenced in the adapter.
Please note: when you import CursorAdapter don't import the Android support version, import the standard android.widget.CursorAdapter instead.
The adapter will also require a custom layout:
res/layout/item.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView
android:id="#+id/item"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</RelativeLayout>
You can now customize list items by adding additional text or image views to the layout and populating them with data in the adapter.
This should be all, but if you haven't done this already you need a SearchView menu item:
res/menu/example.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="#+id/search"
android:title="#string/search"
android:showAsAction="ifRoom"
android:actionViewClass="android.widget.SearchView" />
</menu>
Then create a searchable configuration:
res/xml/searchable.xml
<searchable xmlns:android="http://schemas.android.com/apk/res/android"
android:label="#string/search"
android:hint="#string/search" >
</searchable>
Finally add this inside the relevant activity tag in the manifest file:
AndroidManifest.xml
<intent-filter>
<action android:name="android.intent.action.SEARCH" />
</intent-filter>
<meta-data
android:name="android.app.default_searchable"
android:value="com.example.ExampleActivity" />
<meta-data
android:name="android.app.searchable"
android:resource="#xml/searchable" />
Please note: The #string/search string used in the examples should be defined in values/strings.xml, also don't forget to update the reference to com.example for your project.
If anyone else is having a nullptr on the searchview variable, I found out that the item setup is a tiny bit different:
old:
android:showAsAction="ifRoom"
android:actionViewClass="android.widget.SearchView"
new:
app:showAsAction="ifRoom|collapseActionView"
app:actionViewClass="androidx.appcompat.widget.SearchView"
pre-android x:
app:showAsAction="ifRoom|collapseActionView"
app:actionViewClass="android.support.v7.widget.SearchView"
For more information, it's updated documentation is located here.
SearchDialog or SearchWidget ?
When it comes to implement a search functionality there are two suggested approach by official Android Developer Documentation.
You can either use a SearchDialog or a SearchWidget.
I am going to explain the implementation of Search functionality using SearchWidget.
How to do it with Search widget ?
I will explain search functionality in a RecyclerView using SearchWidget. It's pretty straightforward.
Just follow these 5 Simple steps
1) Add searchView item in the menu
You can add SearchView can be added as actionView in menu using
app:useActionClass = "android.support.v7.widget.SearchView" .
<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="rohksin.com.searchviewdemo.MainActivity">
<item
android:id="#+id/searchBar"
app:showAsAction="always"
app:actionViewClass="android.support.v7.widget.SearchView"
/>
</menu>
2) Set up SerchView Hint text, listener etc
You should initialize SearchView in the onCreateOptionsMenu(Menu menu) method.
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
MenuItem searchItem = menu.findItem(R.id.searchBar);
SearchView searchView = (SearchView) searchItem.getActionView();
searchView.setQueryHint("Search People");
searchView.setOnQueryTextListener(this);
searchView.setIconified(false);
return true;
}
3) Implement SearchView.OnQueryTextListener in your Activity
OnQueryTextListener has two abstract methods
onQueryTextSubmit(String query)
onQueryTextChange(String newText
So your Activity skeleton would look like this
YourActivity extends AppCompatActivity implements SearchView.OnQueryTextListener{
public boolean onQueryTextSubmit(String query)
public boolean onQueryTextChange(String newText)
}
4) Implement SearchView.OnQueryTextListener
You can provide the implementation for the abstract methods like this
public boolean onQueryTextSubmit(String query) {
// This method can be used when a query is submitted eg. creating search history using SQLite DB
Toast.makeText(this, "Query Inserted", Toast.LENGTH_SHORT).show();
return true;
}
#Override
public boolean onQueryTextChange(String newText) {
adapter.filter(newText);
return true;
}
5) Write a filter method in your RecyclerView Adapter.
Most important part. You can write your own logic to perform search.
Here is mine. This snippet shows the list of Name which contains the text typed in the SearchView
public void filter(String queryText)
{
list.clear();
if(queryText.isEmpty())
{
list.addAll(copyList);
}
else
{
for(String name: copyList)
{
if(name.toLowerCase().contains(queryText.toLowerCase()))
{
list.add(name);
}
}
}
notifyDataSetChanged();
}
Relevant link:
Full working code on SearchView with an SQLite database in this Music App
For Searchview use these code
For XML
<android.support.v7.widget.SearchView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/searchView">
</android.support.v7.widget.SearchView>
In your Fragment or Activity
package com.example.user.salaryin;
import android.app.ProgressDialog;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.view.MenuItemCompat;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.SearchView;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;
import com.example.user.salaryin.Adapter.BusinessModuleAdapter;
import com.example.user.salaryin.Network.ApiClient;
import com.example.user.salaryin.POJO.ProductDetailPojo;
import com.example.user.salaryin.Service.ServiceAPI;
import java.util.ArrayList;
import java.util.List;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
public class OneFragment extends Fragment implements SearchView.OnQueryTextListener {
RecyclerView recyclerView;
RecyclerView.LayoutManager layoutManager;
ArrayList<ProductDetailPojo> arrayList;
BusinessModuleAdapter adapter;
private ProgressDialog pDialog;
GridLayoutManager gridLayoutManager;
SearchView searchView;
public OneFragment() {
// Required empty public constructor
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.one_fragment,container,false);
pDialog = new ProgressDialog(getActivity());
pDialog.setMessage("Please wait...");
searchView=(SearchView)rootView.findViewById(R.id.searchView);
searchView.setQueryHint("Search BY Brand");
searchView.setOnQueryTextListener(this);
recyclerView = (RecyclerView) rootView.findViewById(R.id.recyclerView);
layoutManager = new LinearLayoutManager(this.getActivity());
recyclerView.setLayoutManager(layoutManager);
gridLayoutManager = new GridLayoutManager(this.getActivity().getApplicationContext(), 2);
recyclerView.setLayoutManager(gridLayoutManager);
recyclerView.setHasFixedSize(true);
getImageData();
// Inflate the layout for this fragment
//return inflater.inflate(R.layout.one_fragment, container, false);
return rootView;
}
private void getImageData() {
pDialog.show();
ServiceAPI service = ApiClient.getRetrofit().create(ServiceAPI.class);
Call<List<ProductDetailPojo>> call = service.getBusinessImage();
call.enqueue(new Callback<List<ProductDetailPojo>>() {
#Override
public void onResponse(Call<List<ProductDetailPojo>> call, Response<List<ProductDetailPojo>> response) {
if (response.isSuccessful()) {
arrayList = (ArrayList<ProductDetailPojo>) response.body();
adapter = new BusinessModuleAdapter(arrayList, getActivity());
recyclerView.setAdapter(adapter);
pDialog.dismiss();
} else if (response.code() == 401) {
pDialog.dismiss();
Toast.makeText(getActivity(), "Data is not found", Toast.LENGTH_SHORT).show();
}
}
#Override
public void onFailure(Call<List<ProductDetailPojo>> call, Throwable t) {
Toast.makeText(getActivity(), t.getMessage(), Toast.LENGTH_SHORT).show();
pDialog.dismiss();
}
});
}
/* #Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
getActivity().getMenuInflater().inflate(R.menu.menu_search, menu);
MenuItem menuItem = menu.findItem(R.id.action_search);
SearchView searchView = (SearchView) MenuItemCompat.getActionView(menuItem);
searchView.setQueryHint("Search Product");
searchView.setOnQueryTextListener(this);
}*/
#Override
public boolean onQueryTextSubmit(String query) {
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
newText = newText.toLowerCase();
ArrayList<ProductDetailPojo> newList = new ArrayList<>();
for (ProductDetailPojo productDetailPojo : arrayList) {
String name = productDetailPojo.getDetails().toLowerCase();
if (name.contains(newText) )
newList.add(productDetailPojo);
}
adapter.setFilter(newList);
return true;
}
}
In adapter class
public void setFilter(List<ProductDetailPojo> newList){
arrayList=new ArrayList<>();
arrayList.addAll(newList);
notifyDataSetChanged();
}