Currently i'm encountering a strange problem with the SearchView in the ActionBar on especially Samsung Galaxy Tab Devices.
The app has a standard ActionBar (not Sherlock) and displays a SearchView. This View is intended to be visible at all time. And that also works perfectly.
The problem appears after the Dismissing the Soft-Keyboard in the SearchView. On Nexus (4.4) or Asus Devices (4.0) the SearchView looses Focus. On the Galaxy Tab this does not happen.
If you set a listener to the SearchView with "setOnQueryTextFocusChangeListener" it is only called when it requests the focus. But not, when the user dismisses the Keyboard. (This also only is so on these Galaxy Stuff). When using "clearFocus()" programmatically both events are shown and fired.
These behavior makes using the app really terribly:
1) Enter some text into SearchView
2) Dismiss Keyboard
3) Open menu from the action bar (...)
4) Dismiss menu without selecting an entry
=> Keyboard slides up and SearchView is focused
Any ideas? We don't want to write our own implementation of things, which should be Android core.
Here's an image where you can clearly see, that the SearchView still has Focus after the user dismissed the keyboard.
I created some small demo app which could help you to understand what i did.
MainActivity
public class MainActivity extends Activity {
protected static final String TAG = "MainActivity";
private SearchView mSearchView = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
mSearchView = (SearchView) menu.findItem(R.id.menu_search).getActionView();
mSearchView.setQueryHint("Search something");
mSearchView.setIconifiedByDefault(false);
mSearchView.setOnQueryTextFocusChangeListener(new OnFocusChangeListener() {
#Override
public void onFocusChange(View v, boolean hasFocus) {
Log.d(TAG, "Focus is: " + hasFocus);
Toast.makeText(MainActivity.this, "Focus is: " + hasFocus, Toast.LENGTH_SHORT).show();
}
});
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_browse:
//Just find out how focus changes if another activity is launched
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.google.com"));
startActivity(browserIntent);
return true;
case R.id.action_setFocus:
if (mSearchView != null) {
mSearchView.requestFocus();
}
return true;
case R.id.action_clearFocus:
if (mSearchView != null) {
mSearchView.clearFocus();
}
return true;
default:
if (mSearchView != null) {
mSearchView.clearFocus();
}
return super.onOptionsItemSelected(item);
}
}
}
activity_main.xml
<RelativeLayout 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"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:descendantFocusability="beforeDescendants"
android:focusable="true"
android:focusableInTouchMode="true"
tools:context=".MainActivity" >
<EditText
android:id="#+id/testEditText"
android:layout_width="300dp"
android:layout_height="wrap_content"
android:hint="#string/hello_world">
</EditText>
</RelativeLayout>
main.xml (Menu)
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:id="#+id/menu_search"
android:showAsAction="always"
android:focusable="false"
android:actionViewClass="android.widget.SearchView" />
<item
android:id="#+id/action_browse"
android:orderInCategory="100"
android:showAsAction="always"
android:title="Browse"/>
<item
android:id="#+id/action_setFocus"
android:orderInCategory="100"
android:showAsAction="never"
android:title="Set Focus"/>
<item
android:id="#+id/action_clearFocus"
android:orderInCategory="100"
android:showAsAction="never"
android:title="Clear Focus"/>
</menu>
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<uses-permission
android:name="android.permission.INTERNET" />
<uses-sdk
android:minSdkVersion="16"
android:targetSdkVersion="18" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="com.example.searchviewtest.MainActivity"
android:windowSoftInputMode="stateAlwaysHidden"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Try this:
SearchView searchView = (SearchView) MenuItemCompat.getActionView(item);
searchView.clearFocus();
View focused = searchView.getFocusedChild();
if (focused != null) {
focused.clearFocus();
}
where item is the menu item you clicked on
Related
I am developing an app, and in that app have 3 activities
Login
Main
PhotoViewer extends fragmentActivity
in the manifest:
<activity
android:name=".PhotoViewerActivity"
android:configChanges="orientation|keyboardHidden|screenSize"
android:label="#string/title_activity_photo_viewer"
android:parentActivityName=".MainActivity"
android:theme="#style/FullscreenTheme" >
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.ceiva.snap.MainActivity" />
</activity>
Can someone please advice me how to add "Customizer" text to the right of the actionbar for just the PhotoViewerActivity.
Also I tried doing this:
getActionBar().setDisplayHomeAsUpEnabled(true);
getActionBar().setDisplayShowTitleEnabled(true);
// getActionBar().setIcon(android.R.color.transparent);
getActionBar().setTitle("Back");
Log.i(TAG, "actionbar " + getActionBar().isShowing());
ActionBar actionBar = getActionBar();
TextView customizerView = new TextView(getApplicationContext());
customizerView.setEnabled(true);
customizerView.setVisibility(View.VISIBLE);
customizerView.setText(getString(R.string.action_customizer));
customizerView.setTextSize(16);
customizerView.setPadding(100, 40, 40, 40);
actionBar.setCustomView(customizerView);
the back title shows up on the left side but the textview doesnt show up.
You can try with this
1.Create xml file in menu folder
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:id="#+id/action_customize"
android:icon="#drawable/ic_action_customize"
android:title="#string/action_customize"
android:showAsAction="ifRoom"/>
</menu>
2.In your activity
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.activity_main_actions, menu);
return super.onCreateOptionsMenu(menu);
}
3.You can set actions for your menu item with
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Take appropriate action for each action item click
switch (item.getItemId()) {
case R.id.action_customize:
// DO STUFF
return true;
default:
return super.onOptionsItemSelected(item);
}
}
This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 7 years ago.
I'm trying to implement a search widget in my app . I found a useful tutorial from here.
My Activity A
But my app crashed.
Activity A
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.create_menu, 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.
switch (item.getItemId()) {
case R.id.add: // create new file
View menuItemView = findViewById(R.id.add);
PopupMenu po = new PopupMenu(HomePage.this, menuItemView); //for drop-down menu
po.getMenuInflater().inflate(R.menu.popup_menu, po.getMenu());
po.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
public boolean onMenuItemClick(MenuItem item) {
// Toast.makeText(MainActivity.this, "You Clicked : " + item.getTitle(), Toast.LENGTH_SHORT).show();
if ("Create New File".equals(item.getTitle())) {
Intent intent = new Intent(HomePage.this, Information.class); // go to Information class
startActivity(intent);
} else if ("Edit File".equals(item.getTitle())) {
Intent intent = new Intent(HomePage.this, Edit.class);
startActivity(intent);
}
return true;
}
});
po.show(); //showing popup menu
}
return super.onOptionsItemSelected(item);
}
searchable in xml folder
<?xml version="1.0" encoding="utf-8"?>
<searchable xmlns:android="http://schemas.android.com/apk/res/android"
android:label="#string/app_name"
android:hint="Search by date" />
create_menu
<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 by date"
android:icon="#mipmap/search"
app:showAsAction="collapseActionView|ifRoom"
android:actionViewClass="android.widget.SearchView" />
<item
android:icon="#mipmap/menu"
android:id="#+id/add"
android:orderInCategory="100"
android:title="Main Menu"
app:showAsAction="always" />
</menu>
declare this in mainfest
<meta-data android:name="android.app.searchable"
android:resource="#xml/searchable" />
Error LogCat
01-18 18:31:09.298 9215-9215/com.example.project.myapplication E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.example.project.myapplication, PID: 9215
java.lang.NullPointerException
at com.example.project.myapplication.GUI.HomePage.onCreateOptionsMenu(HomePage.java:104)
at android.app.Activity.onCreatePanelMenu(Activity.java:2646)
at android.support.v4.app.FragmentActivity.onCreatePanelMenu(FragmentActivity.java:298)
at android.support.v7.internal.view.WindowCallbackWrapper.onCreatePanelMenu(WindowCallback
This is the line where error pointed to searchView.setSearchableInfo(
You should use support SearchView's support version:
<item android:id="#+id/action_search"
android:title="#string/search_title"
android:icon="#android:drawable/ic_menu_search"
app:showAsAction="ifRoom"
app:actionViewClass="android.support.v7.widget.SearchView" />
And you'd add in Manifest.xml the proper Intent Filter
<intent-filter>
<action android:name="android.intent.action.SEARCH" />
</intent-filter>
<meta-data
android:name="android.app.searchable"
android:resource="#xml/searchable" />
I am trying to create android application that takes multiple parameters when searching. Currently, I have a searchable interface and am able search from my action bar. However, I want to create a yelp like search bar where I have 2 text fields to enter in data as shown in the image:
How can I add an additional text field when searching?
Here is the code I am using to initalize the search
#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_home, menu);
// Associate searchable configuration with the SearchView
SearchManager searchManager =
(SearchManager) getSystemService(Context.SEARCH_SERVICE);
final SearchView searchView =
(SearchView) menu.findItem(R.id.action_search).getActionView();
searchView.setSearchableInfo(
searchManager.getSearchableInfo(getComponentName()));
// set query change listener to hide keyboard after input has been
// submitted
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextChange(String newText) {
return false;
}
#Override
public boolean onQueryTextSubmit(String query) {
// hides and then unhides search tab to make sure keyboard
// disappears when query is submitted
searchView.clearFocus();
return false;
}
});
and here is my menu_layout:
<item
android:id="#+id/action_search"
android:title="#string/search"
android:orderInCategory="100"
impulz:showAsAction="always"
impulz:actionViewClass="android.widget.SearchView"/>
<item android:id="#+id/action_settings" android:title="#string/action_settings"
android:orderInCategory="100" impulz:showAsAction="never" />
Thank you very much.
you can use
actionBar.setCustomView(R.layout.custom_search);
and set the actionBar programmatically "custom view"
like this:
custom_search.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="right"
android:orientation="horizontal">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical" >
<com.actionbarsherlock.widget.SearchView
android:id="#+id/search1"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:iconifiedByDefault="false"
android:visibility="invisible" />
<com.actionbarsherlock.widget.SearchView
android:id="#+id/search2"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:iconifiedByDefault="false"
android:visibility="invisible" />
</LinearLayout>
<ImageButton
android:id="#+id/btn_search_content"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:src="#drawable/search_content" />
</LinearLayout>
menu.xml
<item
android:id="#+id/menu_search"
android:icon="#drawable/red_icon"
android:showAsAction="always"
android:title="search" />
use setCustomView into your onCreate()
MainActivity
#Override
public void onCreate(Bundle savedInstanceState) {
// ...
actionBar.setCustomView(R.layout.custom_search);
actionBarCustomView = action_bar.getCustomView();
searchView = ((SearchView) actionBarCustomView.findViewById(R.id.search1));
searchView2 = ((SearchView) actionBarCustomView.findViewById(R.id.search2));
searchView.setOnCloseListener(new SearchView.OnCloseListener() {
#Override
public boolean onClose() {
searchView.setVisibility(View.INVISIBLE);
searchView2.setVisibility(View.INVISIBLE);
return false;
}
});
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_search:
//set visibilty
//do what ever you want
break;
}
return true;
}
Hope this will work out for you.
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>