I've got a problem trying to add a SearchView widget to the ActionBar in my activity - I get a null value when calling getActionView to get my SearchView object.
I've been following the Android Developer guide and also went through a ton of SO questions as well as some other links on the Internet; all to no avail. It could be something simple but I wasn't able to figure it out - it seems to me my code is basically the same as that from google (apart from changing some names etc.) but it still won't work.
Any help would be appreciated.
Included below are relevant bits of the code. Please let me know if anything's unclear of if you have any idea as to what could possibly be wrong.
Activity code:
private ListView workflowListView;
private DrawerLayout drawerLayout;
private ListView drawerList;
private ActionBarDrawerToggle drawerToggle;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().requestFeature(Window.FEATURE_ACTION_BAR);
setContentView(R.layout.activity_workflow_list);
workflowListView = (ListView) findViewById(R.id.workflowListView);
drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
drawerList = (ListView) findViewById(R.id.drawer_list);
drawerToggle = new ActionBarDrawerToggle(
this, /* host Activity */
drawerLayout, /* DrawerLayout object */
R.drawable.ic_launcher, /* nav drawer icon to replace 'Up' caret */
R.string.app_name, /* "open drawer" description */
R.string.app_name /* "close drawer" description */
) {
/** Called when a drawer has settled in a completely closed state. */
public void onDrawerClosed(View view) {
// getActionBar().setTitle("Closed drawer");
}
/** Called when a drawer has settled in a completely open state. */
public void onDrawerOpened(View drawerView) {
// getActionBar().setTitle("Open drawer");
}
};
drawerLayout.setDrawerListener(drawerToggle);
ActionBar actionBar = getActionBar();
actionBar.setDisplayShowTitleEnabled(false);
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setHomeButtonEnabled(true);
actionBar.setIcon(android.R.color.transparent);
String[] testData = {"a", "b", "c", "d"};
ArrayList<String> workflowList = new ArrayList<String>();
for (String s : testData) {
workflowList.add(s);
}
ArrayAdapter<String> workflowAdapter = new ArrayAdapter<String>(this.getApplicationContext(), R.layout.workflow_list_item, workflowList);
workflowListView.setAdapter(workflowAdapter);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.workflow_list, menu);
inflater.inflate(R.menu.options_menu, menu);
// Associate searchable configuration with the SearchView
SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
// The below line returned null even though it was used in Google sample code
SearchView searchView = (SearchView) menu.findItem(R.id.search).getActionView();
searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
return super.onCreateOptionsMenu(menu);
}
xml/searchable.xml:
<?xml version="1.0" encoding="utf-8"?>
<searchable xmlns:android="http://schemas.android.com/apk/res/android"
android:label="#string/app_name"
android:hint="#string/search_hint"
android:includeInGlobalSearch="false" />
menu/options_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="#string/search_title"
android:icon="#drawable/ic_action_search"
android:showAsAction="always|collapseActionView"
android:actionViewClass="android.support.v7.widget.SearchView" />
</menu>
Try to replace the failing line with:
mSearchMenuItem = menu.findItem(R.id.action_search);
mSearchView = (EnglishVerbSearchView) MenuItemCompat.getActionView(mSearchMenuItem);
Where R.id.action_search is the id of your search item in the menu.
EDIT
Your manifest should look like that:
<activity
android:name="com.bronzelabs.twc.activities.WorkflowListActivity"
android:label="#string/app_name"
android:theme="#style/Theme.AppCompat.Light" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".activities.SearchResultActivity"
android:theme="#style/Theme.AppCompat.Light"
android:launchMode="singleTop">
<intent-filter>
<action android:name="android.intent.action.SEARCH" />
</intent-filter>
<meta-data android:name="android.app.searchable" android:resource="#xml/searchable"
android:value=".activities.SearchResultActivity" />
</activity>
The way you call setSearchableInfo is:
mSearchView.setSearchableInfo(searchManager.getSearchableInfo(
new ComponentName(getApplicationContext(), SearchResultActivity.class)));
EDIT 2
Make sure your menu xml file is like that (pay attention to those 2 attributes with yourapp namespace - this is needed when you use the compat library):
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:yourapp="http://schemas.android.com/apk/res-auto" >
<item android:id="#+id/action_search"
android:title="#string/action_search"
android:icon="#drawable/action_search"
yourapp:showAsAction="always|collapseActionView"
yourapp:actionViewClass="android.support.v7.widget.SearchView" />
</menu>
I had a similar probably that appeared on my release builds but not my debug builds when switching over to the v21 support library. Turned out to be an obfuscation problem, and adding this line to my proguard-rules.txt file fixed it:
-keep class android.support.v7.widget.SearchView { *; }
First check you are using app namespace for actionViewClass.
android:actionViewClass="android.support.v7.widget.SearchView"-this throws NPE
app:actionViewClass="android.support.v7.widget.SearchView"-use this
and second
Check if you are using same searchView in menu.xml and in your Activity
I had a very similar issue where the following line was returning null
SearchView searchView = (android.support.v7.widget.SearchView)MenuItemCompat.getActionView(searchMenuItem);
The fix was in my styles.xml file, i changed my AppTheme's parent to Theme.AppCompat.Light
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light">
For anyone still searching, I followed everything above and could not seem to get things going. I wrapped my searchView.setSearchableInfo... in a null check and voila! It ran just like it ought to.
if (searchView != null) {
searchView.setSearchableInfo(searchManager.getSearchableInfo(
new ComponentName(getApplicationContext(), SearchActivity.class)));
}
for me, This is the right answer:
In menu/options_menu.xml, use this:
app:actionViewClass="android.support.v7.widget.SearchView"
I think you're occupying FragmentActivity, you need to extend of ActionBarActivity
I had the same problem. My solution is:
replace
android:actionViewClass="android.support.v7.widget.SearchView"
with
android:actionViewClass="android.widget.SearchView"
Related
I am creating an android app, i am trying to hide default action bar and us my own custom toolbar as action bar but the problem is that default navigation icon and title of action bar are not being hidden and when i open navigation drawer from right side my custom navigation icon from left side hides and android's default navigation icon is displayed instead.
i have tried using NoActionBar and NoTheme styles too but its not working.
Here is a sample of my code, where i am going wrong
Any help will be appreciated.
public class MyActivity extends AppCompatActivity
{
Toolbar main_toolbar;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my);
setUpToolBar();
}
public void setUpToolBar()
{
main_toolbar=(Toolbar)findViewById(R.id.toolbar)
//set up the home_main_toolbar
android.app.ActionBar actionBar = getActionBar();
actionBar.setDisplayShowHomeEnabled(false);
actionBar.setDisplayShowTitleEnabled(false);
setSupportActionBar(main_toolbar);
if (activity.getSupportActionBar() != null)
main_toolbar.setNavigationIcon(R.drawable.img_toolbar);
main_toolbar.setNavigationOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View view) {
//Open navigation drawer
}
});
}
}
<activity android:name=".MainActivity" android:screenOrientation="portrait" android:theme="#style/AppTheme.NoActionBar" />
use this code in your android menifest , surely it will work
try it in manifest where your activity is defined.
android:theme="#style/AppTheme.NoActionBar"
Go to Styles.xml
add this style there
<style name="AppTheme.NoActionBar">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
</style>
and use it in manifest
<activity
android:name=".MainActivity"
android:label="#string/app_name"
android:theme="#style/AppTheme.NoActionBar" />
I want my action bar to display 5 icons. Since I don't have enough space for displaying main content. So I couldn't use two tabs instead of one. I want the actionbar look like this.
But Instead it looks something like this taking un-necessary space.
I'm not interested in displaying the Appname or app icon. I tried doing several things from stackoverflow but most of them are not working probably because I'm using appcompat theme but android has deprecated the ActionBarActivity so I am bound to use the AppCompat. And most of the answers on stackoverflow works with ActionBarActivity. So, I'm stuck with this problem for last two days
Here's the main Activity
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import com.navdrawer.SimpleSideDrawer;
public class MainActivity extends AppCompatActivity {
private SimpleSideDrawer mNav;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mNav = new SimpleSideDrawer(this);
mNav.setRightBehindContentView(R.layout.activity_behind_left_simple);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
// Inflate the menu items for use in the action bar
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu_main, menu);
return super.onCreateOptionsMenu(menu);
}
#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.
switch (item.getItemId()) {
case R.id.action_map:
return true;
case R.id.action_transport:
return true;
case R.id.action_hotel_food:
return true;
case R.id.action_travel_more:
return true;
case R.id.action_logo:
mNav.toggleRightDrawer();
default:
return super.onOptionsItemSelected(item);
}
}
}
Menu xml code
<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"
xmlns:Journey="http://schemas.android.com/apk/res-auto"
tools:context=".MainActivity">
<item android:id="#+id/action_map"
android:icon="#drawable/ic_action_map"
android:title="#string/action_map"
Journey:showAsAction="always"/>
<item android:id="#+id/action_transport"
android:icon="#drawable/ic_action_transport"
android:title="#string/action_transport"
Journey:showAsAction="always"/>
<item android:id="#+id/action_hotel_food"
android:icon="#drawable/ic_action_hotel_food"
android:title="#string/action_hotel_food"
Journey:showAsAction="always"/>
<item android:id="#+id/action_travel_more"
android:icon="#drawable/ic_action_travel_more"
android:title="#string/action_travel_more"
Journey:showAsAction="always"/>
<item android:id="#+id/action_logo"
android:icon="#drawable/ic_action_logo"
android:title="#string/action_logo"
Journey:showAsAction="always"/>
</menu>
styles.xml file
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light">
<!-- Customize your theme here. -->
</style>
</resources>
Manifest File
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="********" >
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".MainActivity"
android:icon="#mipmap/ic_launcher">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
I'm new to programming and I have a design background. So if the answer is explained with proper codes then that will be very useful. Thanks a lot for help.
In my android app .. I am trying t put a search edittext with seARCH icon .. but I cant see the search icon in action bar rather the title is seeing in overflow. I am giving my code below
activity
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:id="#+id/action_search"
android:icon="#drawable/ic_action_search"
android:title="#string/action_search"
android:showAsAction="always"/>
<item
android:id="#+id/action_settings"
android:title="Settings"/>
</menu>
MainActvity
public class MainActivity extends ActionBarActivity
{
WebView wv1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
wv1 = (WebView) findViewById(R.id.wView1);
wv1.getSettings().setJavaScriptEnabled(true);
wv1.loadUrl("http://www.example.com/songs/");
}
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.activity_main_actions, menu);
return super.onCreateOptionsMenu(menu);
}
}
Use Search Manager n search view in onCreateOptionsMenu
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.activity_main_actions, menu);
// Associate searchable configuration with the SearchView
SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
SearchView searchView = (SearchView) menu.findItem(R.id.action_search)
.getActionView();
searchView.setSearchableInfo(searchManager
.getSearchableInfo(getComponentName()));
return super.onCreateOptionsMenu(menu);
}
and in your main.xml add this item for search
<item android:id="#+id/action_search"
android:icon="#drawable/ic_action_search"
android:title="#string/action_search"
android:showAsAction="ifRoom"
android:actionViewClass="android.widget.SearchView"/>
I think you must return `true` instead of
super.onCreateOptionsMenu(menu)
in `onCreateOptionsMenu(Menu menu)` method
Excuses. That was wrong.
I think this problem has something to do with the base class you are using. Your are subclassing ActionBarActivity instead of Activity. This means that you are using compatibility for previous versions. For this to work, you need to set your application's Theme to Theme.AppCompat (or a similar one), and also include the Support Library. Look here
I just realized how to fix the problem!
your menu xml file should have an starting tag like:
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:myApp="http://schemas.android.com/apk/res-auto" >
you can replace
myApp
with any names you want, NOW the important part is when you define an action item:
<item
android:id="#+id/actionitem_switch_view"
android:title="#string/view_as"
android:showAsAction="always"
myApp:showAsAction="always"
android:icon="#drawable/ic_action_view_as_list"/>
You'd have two showAsAction tags,one for API<11 devices and one for the others,
Look closely that the two showAsAction tags are different,one is from Android namespace and the other's from the tag you defined in menu Starting point
The problem occurs when interacting with the SearchView or when the activity with the Searchview loads. When using setIconifiedByDefault(true) the problem occurs after the activity loads when interacting with the SearchView, but when using setIconifiedByDefault(false) the problem occurs when the activity loads.
The following error is output in LogCat:
java.lang.NullPointerException
at android.widget.SearchView.adjustDropDownSizeAndPosition(SearchView.java:1244)
Here is the code:
ExampleActivity.java
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.example, 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.setIconifiedByDefault(true);
search.setOnQueryTextListener(new OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
// Perform search
return true;
}
});
}
return true;
}
menu/example.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="#+id/search"
android:title="Search"
android:showAsAction="ifRoom"
android:actionViewClass="android.widget.SearchView" />
</menu>
xml/searchable.xml
<searchable xmlns:android="http://schemas.android.com/apk/res/android"
android:label="#string/search"
android:hint="#string/search" >
</searchable>
The "search" string used in searchable.xml is defined in values/strings.xml. Also the searchable.xml file is referenced correctly in the activity tag in AndroidManifest.xml:
<meta-data
android:name="android.app.default_searchable"
android:value="com.example.MainActivity" />
<meta-data
android:name="android.app.searchable"
android:resource="#xml/searchable" />
This problem is caused by styles being applied to the EditText in the action bar SearchView.
You can fix this by removing any style you have applied to EditText such as:
res/values/styles.xml
<item name="android:editTextStyle">#style/editor</item>
Then go to each EditText view in your layout XML and apply the style directly:
<EditText style="#style/editor" />
I'm using actionBar and searchView, and this is my code:
public class MainActivity extends FragmentActivity {
#Override
public void onCreate(Bundle savedBundle) {
super.onCreate(savedBundle);
setContentView(R.layout.main_layout);
setupImageLoader();
setupSlidingMenu();
}
....
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.options_menu, menu);
return true;
}
}
and my menu file is:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="#+id/search"
android:icon="#drawable/ic_search"
android:showAsAction="collapseActionView|ifRoom"
android:actionViewClass="android.widget.SearchView"/>
</menu>
Now what I see is this:
When not selected the SearchView is on the bottom of the screen, and it becames part of the actionbar only when active. How can I embed it like in Play store?
From your java-code, it seems that you are using FragmentActivity and thus the android-support library. But your selected SearchView-class is from the native Android framework.
Look at the developer-docs to see how it should be done:
http://developer.android.com/guide/topics/ui/actionbar.html#ActionView
Also, it seems you have the splitActionbar enabled, or else your search-button would appear in the upper actionbar. So check your AndroidManifest.xml for something like this:
<activity uiOptions="splitActionBarWhenNarrow" ... >
<meta-data android:name="android.support.UI_OPTIONS"
android:value="splitActionBarWhenNarrow" />
</activity>