Android - Предотвратить усечение текста в предложениях SearchView?
Предложения, которые появляются по умолчанию ListView
под моим SearchView
содержит текст, который усечен. Я хотел бы, чтобы текст отображался полностью (в несколько строк, если это необходимо).
Я придумала два возможных способа решения этой проблемы, но без примеров в сети, я надеялась, что кто-то здесь сможет помочь...
Подход № 1 / Q1: Как я могу напрямую получить доступ и изменить внешний вид TextViews, которые содержат SUGGEST_COLUMN_TEXT_1
а также SUGGEST_COLUMN_TEXT_1
текст?
Подход № 2 / Q2: в качестве альтернативы, SearchView имеет setSuggestionsAdapter(CursorAdapter adapter)
метод, который выглядит так, как будто он (больше?) подходит, чем подход № 1. Хотя я прочитал CursorAdapters и уже внедрил его в свое приложение, я не уверен, как бы настроить его для SearchView (особенно с точки зрения доступа к курсору), поэтому кто-нибудь может мне помочь с некоторыми общими рекомендациями или пример скелета?
Вот существующий код из моего класса SearchViewFragment:
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;
}
}
Обновление: решено!
Благодаря принятому ответу, я создал этот код, который довольно чистый и хорошо выполняет свою работу...
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);
}
*/
}
}
А вот и мой 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>
... результат - отсутствие усечения текста.:-)
3 ответа
Похоже, что вы хотите пользовательский макет для результатов поиска. Я постараюсь изложить некоторые четкие шаги ниже:
Чтобы заставить работать представление поиска, нам нужно иметь searchable.xml
в res/xml folder
и content provider
всегда.
пример searchable.xml:
<searchable xmlns:android="http://schemas.android.com/apk/res/android"
android:label="@string/app_name"
android:searchSuggestAuthority="com.example.searchProvider" ></searchable>
label
а также searchSuggestAuthority
являются обязательными. searchSuggestAuthority
должен указывать на местоположение поставщика контента
Добавьте метаданные фильтра намерений к действию в манифесте. Пример:
<meta-data android:name="android.app.searchable" android:resource="@xml/searchable"/>
В упражнении / фрагменте получите ваш объект searchView и передайте ему пользовательский адаптер для отображения пользовательского макета.
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));
}
};
Убедитесь, что пользовательский адаптер расширяет курсор Adapter.
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;
}
}
В приведенном выше коде R.layout.item
относится к вашему обычаю xml
файл, который вы можете использовать для раздувания в результатах поиска.
Убедитесь, что вы используете content provider
хоть. searchView
не работает без него. Это не имеет значения, даже если вы кэшируете данные только на временной основе.
Надеюсь это поможет!
user2511882 идеален, но этот конструктор устарел.
Deprecated :
public ExampleAdapter(Context context, Cursor cursor) {
super(context, cursor);
this.cursor= cursor;
}
Вы можете использовать ниже, вместо этого.
public ExampleAdapter(Context context, Cursor c, int flags) {
super(context, c, flags);
}
и затем назовите это так
searchView.setSuggestionsAdapter(new ExampleAdapter(context,YOUR_DATA,CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER));
https://developer.android.com/reference/android/widget/CursorAdapter.html
Я думаю, что вам нужно будет создать CustomAdapter, который обращается к вашему собственному макету, чтобы сделать это. Удивительно, но это не так легко изменить. SuggestionsAdapter не является общедоступным, поэтому вы не можете его расширить. Это не красиво, но самое простое решение - скопировать SuggestionsAdapter.java в ваш собственный проект и указать его на макете в ваших собственных res / layouts. Я бы снова скопировал версию из исходного кода Android и изменил ее в соответствии с вашими потребностями.
Версия Android 5 еще хуже для модификации, так что это версия KitKat: http://grepcode.com/file_/repository.grepcode.com/java/ext/com.google.android/android/4.4.4_r1/android/widget/SuggestionsAdapter.java/?v=source
Измените эту строку, чтобы она указала на ваш файл макета:
super(context,
com.android.internal.R.layout.search_dropdown_item_icons_2line, // make it you layout xml (see below)
null, // no initial cursor
true); // auto-requery
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:paddingStart="@dimen/dropdownitem_text_padding_left"
android:paddingEnd="4dip"
android:layout_width="match_parent"
android:layout_height="wrap_content" > <!-- changed -->
Также в файле макета:
<TextView android:id="@android:id/text2"
style="?android:attr/dropDownItemStyle"
android:textAppearance="?android:attr/textAppearanceSearchResultSubtitle"
<!-- android:singleLine="true" --> <!-- remove this line -->
android:layout_width="match_parent"
android:layout_height="wrap_content" <!-- changed -->
Ответ user2511882, вероятно, лучше, чем этот быстрый взлом.