Android: evita el truncamiento de texto en las sugerencias de SearchView?

Las sugerencias que aparecen en el ListView predeterminado debajo de mi SearchView contienen texto truncado. Quisiera que el texto fuera exhibido en su totalidad (en líneas múltiples si es necesario).

He encontrado dos posibles maneras de resolver esto pero, sin ejemplos que se encuentran en la red, esperaba que alguien de aquí pudiera ayudar …

Enfoque # 1 / Q1: ¿Cómo puedo acceder y modificar directamente la apariencia de los TextViews que contienen el texto SUGGEST_COLUMN_TEXT_1 y SUGGEST_COLUMN_TEXT_1 ?

Enfoque # 2 / Q2: Alternativamente, SearchView tiene un setSuggestionsAdapter(CursorAdapter adapter) que parece que puede ser (más?) Adecuado que el enfoque # 1. Aunque he leído en CursorAdapters y tengo uno ya implementado en mi aplicación, no estoy seguro de cómo configuraría uno para el SearchView (especialmente en términos de acceso al cursor), por lo que podría alguien me ayude con algunas orientaciones generales O un ejemplo esqueleto?

Aquí está el código existente de mi clase 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; } 

}

Actualización: ¡SOLUCIONADO!

Gracias a la respuesta aceptada, he creado este código que es bastante limpio y hace el trabajo bien …

 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); } */ } } 

Y aquí está mi 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> 

… el resultado no es el truncamiento del texto. Todos los derechos reservados

Parece que desea un diseño personalizado para los resultados de la vista de búsqueda. Voy a tratar de esbozar algunos pasos claros a continuación:

Para que la vista de búsqueda funcione debemos tener un searchable.xml en la res/xml folder y un content provider en todo momento.

Ejemplo searchable.xml:

 <searchable xmlns:android="http://schemas.android.com/apk/res/android" android:label="@string/app_name" android:searchSuggestAuthority="com.example.searchProvider" ></searchable> 

La label y searchSuggestAuthority son obligatorios. La searchSuggestAuthority debe apuntar a la ubicación del proveedor de contenido

Agregue los metadatos del filtro de intenciones a la actividad del manifiesto. Ejemplo:

  <meta-data android:name="android.app.searchable" android:resource="@xml/searchable"/> 

En la actividad / fragmento, obtenga su objeto searchView y pase el adaptador personalizado para mostrar el diseño personalizado.

 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)); } }; 

Asegúrese de que el adaptador personalizado extienda el 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; } } 

En el código anterior, R.layout.item refiere a su archivo xml personalizado que puede utilizar para inflar en los resultados de la búsqueda.

Asegúrese de que está utilizando un content provider sin embargo. El searchView no funciona sin uno. No importa aunque sólo esté almacenando en caché los datos de manera temporal.

¡Espero que esto ayude!

La respuesta de user2511882 es perfecta, pero ese constructor está obsoleto.

 Deprecated : public ExampleAdapter(Context context, Cursor cursor) { super(context, cursor); this.cursor= cursor; } 

Usted puede utilizar el siguiente uno en lugar de eso.

 public ExampleAdapter(Context context, Cursor c, int flags) { super(context, c, flags); } 

Y luego lo llaman así.

 searchView.setSuggestionsAdapter(new ExampleAdapter(context,YOUR_DATA,CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER)); 

https://developer.android.com/reference/android/widget/CursorAdapter.html

Creo que necesitará crear un CustomAdapter que acceda a su propio diseño para hacer esto. Es sorprendente que esto no se haya hecho más fácil de modificar. SuggestionsAdapter no es público, por lo que no puede extenderlo. No es bonito, pero la solución más fácil será copiar SuggestionsAdapter.java en su propio proyecto y apuntarlo a un diseño en su propio res / layouts. Volvería a copiar la versión del código fuente de Android y modificarla a sus necesidades.

La versión para Android 5 es aún peor para modificar, así que esta es la versión de KitKat: http://grepcode.com/file_/repository.grepcode.com/java/ext/com.google.android/android/4.4.4_r1/android/ Widget / SuggestionsAdapter.java /? V = fuente

Cambie esta línea para apuntar a su archivo de diseño:

 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 

http://grepcode.com/file_/repository.grepcode.com/java/ext/com.google.android/android/4.4.4_r1/frameworks/base/core/res/res/layout/search_dropdown_item_icons_2line.xml/?v = Fuente

 <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 --> 

También en el archivo de diseño:

 <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 --> 

La respuesta de user2511882 es probablemente mejor que este hack rápido.

  • Excepción de puntero nulo al utilizar SearchView con AppCompat
  • No se puede llamar a void android.view.View.setElevation (float) en un objeto nulo en lapism / SearchView
  • Adición de SearchView en el fragmento
  • Widget SearchView no aparece en la barra de acciones
  • No se puede obtener la vista de búsqueda en la barra de acciones para trabajar
  • Puntero nulo en ExpandedView para la búsqueda de ActionBar
  • ¿Es posible alinear a la izquierda SearchView en AppCompat 21 con la barra de herramientas?
  • ¿Cómo manejar el evento de clic de sugerencia con SearchView en ActionBar, ContentProvider llamando a webService, devolviendo el cursor?
  • Cuándo cerrar Cursor utilizado en SimpleCursorAdapter
  • SearchView en AppCompat distorsiona el icono
  • ¿Cómo implementar WhatsApp como el diseño de materiales SearchView?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.