The suggestions that appear in the default ListView
beneath my SearchView
contain text that is truncated. I would like the text to be displayed in its entirety (on multiple lines if necessary).
I have come up with two possible ways to solve this but, with no examples to be found on the net, I was hoping someone on here may be able to help...
Approach #1 / Q1: How can I directly access and modify the appearance of the TextViews that hold the SUGGEST_COLUMN_TEXT_1
and SUGGEST_COLUMN_TEXT_1
text?
Approach #2 / Q2: Alternatively, SearchView has a setSuggestionsAdapter(CursorAdapter adapter)
method which looks like it may be (more?) suitable than approach #1. Although I have read up on CursorAdapters and have one already implemented in my app, I'm not sure how I would configure one for the SearchView (esp. in terms of accessing the cursor), so could anyone help me out with some general guidance or a skeleton example?
Here is the existing code from my SearchViewFragment class:
public class SearchViewFragment extends Fragment {
public SearchViewFragment() {
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View fragmentView = inflater.inflate(R.layout.fragment_search_view, container, false);
// Use the Search Manager to find the SearchableInfo related to this Activity
SearchManager searchManager = (SearchManager)getActivity().getSystemService(Context.SEARCH_SERVICE);
SearchableInfo searchableInfo = searchManager.getSearchableInfo(getActivity().getComponentName());
// Bind the Activity's SearchableInfo to the Search View
SearchView searchView = (SearchView)fragmentView.findViewById(R.id.searchView);
searchView.setSearchableInfo(searchableInfo);
searchView.setIconifiedByDefault(false);
searchView.setSubmitButtonEnabled(true);
//searchView.setQueryRefinementEnabled(true);
return fragmentView;
}
}
Update: SOLVED!
Thanks to the accepted answer, I have created this code which is pretty clean and does the job well...
public class SearchViewFragment extends Fragment {
private static final String LOG_TAG = SearchViewFragment.class.getSimpleName();
public SearchViewFragment() {
}
@Override
public void onCreate(Bundle savedInstanceState) {
setRetainInstance(true); //todo - not working - Remember search term
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View fragmentView = inflater.inflate(R.layout.fragment_search_view, container, false);
// Use the Search Manager to find the SearchableInfo related to this Activity
SearchManager searchManager = (SearchManager)getActivity().getSystemService(Context.SEARCH_SERVICE);
SearchableInfo searchableInfo = searchManager.getSearchableInfo(getActivity().getComponentName());
// Bind the Activity's SearchableInfo to the Search View
final SearchView searchView = (SearchView)fragmentView.findViewById(R.id.searchView);
searchView.setSearchableInfo(searchableInfo);
searchView.setIconifiedByDefault(false);
searchView.setSubmitButtonEnabled(true);
//searchView.setQueryRefinementEnabled(true);
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String s) {
//DO whatever you want here on text submit in the search View
Log.d(LOG_TAG, "onQueryTextSubmit(" + s + ")");
return true;
}
@Override
public boolean onQueryTextChange(String textChange) {
Log.d(LOG_TAG, "onQueryTextChange(" + textChange + ")");
ContentResolver cr = getActivity().getContentResolver();
Uri uri = DbContentProvider.CONTENT_URI_REAL_PRODUCTS;
String[] projection = DbContentProvider.getProjectionIn(DbContentProvider.REAL_PRODUCTS_SUGGEST);
String selection = DbContentProvider.getSelection(false);
String[] selectionArgs = {Utilities.formatQueryString(textChange)};
String sortOrder = null;
Cursor cursor = cr.query(uri, projection, selection, selectionArgs, sortOrder);
Log.d(LOG_TAG, "Setting setSuggestionsAdapter. cursor: " + cursor);
searchView.setSuggestionsAdapter(new SearchSuggestionsAdapter(getActivity(), cursor));
return true;
}
});
return fragmentView;
}
private static class SearchSuggestionsAdapter extends SimpleCursorAdapter {
private static final String[] mVisible = {SearchManager.SUGGEST_COLUMN_TEXT_1, SearchManager.SUGGEST_COLUMN_TEXT_2};
private static final int[] mViewIds = {R.id.product_name, R.id.product_shelf};
public SearchSuggestionsAdapter(Context context, Cursor cursor) {
super(context, R.layout.search_view_suggestions, cursor, mVisible, mViewIds, 0);
}
/*
@Override
public void bindView(View view, Context context, Cursor cursor) {
Log.d(LOG_TAG, "bindView(" + view + ", " + context + ", " + cursor + ")");
super.bindView(view, context, cursor);
}
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
Log.d(LOG_TAG, "newView(" + context + ", " + cursor + ", " + parent + ")");
return super.newView(context, cursor, parent);
}
*/
}
}
And here is my search_view_suggestions.xml...
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin" >
<TextView
android:id="@+id/product_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Product Name placeholder"
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
android:id="@+id/product_shelf"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Product Shelf placeholder" />
</LinearLayout>
...the result is no text truncation. :-)
To add a SearchView widget to the app bar, create a file named res/menu/options_menu. xml in your project and add the following code to the file. This code defines how to create the search item, such as the icon to use and the title of the item.
SearchView widget can be implemented over ToolBar/ActionBar or inside a layout. SearchView is by default collapsible and set to be iconified using setIconifiedByDefault(true) method of SearchView class. For making search field visible, SearchView uses setIconifiedByDefault(false) method.
It seems like you want a custom layout for your search view results. I will try to outline some clear steps below:
To make the search view to work we need to have a searchable.xml
in the res/xml folder
and a content provider
at all times.
searchable.xml example:
<searchable xmlns:android="http://schemas.android.com/apk/res/android"
android:label="@string/app_name"
android:searchSuggestAuthority="com.example.searchProvider" ></searchable>
The label
and searchSuggestAuthority
are required. The searchSuggestAuthority
should point to the location of the content provider
Add the intent-filter meta-data to the activity in the manifest. Example:
<meta-data android:name="android.app.searchable" android:resource="@xml/searchable"/>
In the activity/fragment, get your searchView object and pass it the custom adapter for displaying the custom layout.
searchView.setSearchableInfo(manager.getSearchableInfo(getActivity().getComponentName()));
final SearchView.OnQueryTextListener queryTextListener = new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String s) {
//DO whatever you want here on text submit in the search View
return true;
}
@Override
public boolean onQueryTextChange(String textChange) {
searchView.setSuggestionsAdapter(new ExampleAdapter(context,yourData));
}
};
Make sure the custom adapter extends the cursorAdapter.
public class ExampleAdapter extends CursorAdapter {
private Cursor cursor;
private TextView text;
public ExampleAdapter(Context context, Cursor cursor) {
super(context, cursor);
this.cursor= cursor;
}
@Override
public void bindView(View view, Context context, Cursor cursor) {
text.setText((cursor.getString(cursor.getColumnIndex(YOUR_STRING_KEY));));
}
@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;
}
}
In the above code R.layout.item
refers to your custom xml
file that you can use to inflate in the searchview results.
Make sure you are using a content provider
though. The searchView
doesn't work without one. It doesn't matter even if you are only caching the data on a temporary basis.
Hope this helps!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With