¿Cómo resalto el texto buscado en mi filtro de búsqueda?

Estoy intentando hacer una búsqueda tal que todas las letras "visibles" de la búsqueda se deben destacar. Intenté usar spannable pero eso no hizo el truco, quizás no lo hice derecho? Basado en esto: Resalte el texto buscado en los elementos ListView ¿Cómo puedo resaltar el texto visible? Aquí está mi filtro:

private LayoutInflater mInflater; private ValueFilter valueFilter; public MySimpleArrayAdapter(Activity context) { this.context = context; mInflater = LayoutInflater.from(context); } private class ValueFilter extends Filter { //Invoked in a worker thread to filter the data according to the constraint. @Override protected synchronized FilterResults performFiltering(CharSequence constraint) { FilterResults results = new FilterResults(); if (constraint != null && constraint.length() > 0) { ArrayList<Integer> filterList = new ArrayList<>(); int iCnt = listItemsHolder.Names.size(); for (int i = 0; i < iCnt; i++) { if(listItemsHolder.Types.get(i).toString().indexOf("HEADER_")>-1){ continue; } if (listItemsHolder.Names.get(i).matches(getRegEx(constraint))||(listItemsHolder.Names.get(i).toLowerCase().contains(constraint.toString().toLowerCase()))) { if(filterList.contains(i)) continue; filterList.add(i); } } results.count = filterList.size(); results.values = filterList; }else { String prefixString = getRegEx(constraint); mSearchText = prefixString; results.count = listItemsHolder.Names.size(); ArrayList<Integer> tList = new ArrayList<>(); for(int i=0;i<results.count;i++){ tList.add(i); } results.values = tList; } return results; } //Invoked in the UI thread to publish the filtering results in the user interface. @SuppressWarnings("unchecked") @Override protected void publishResults(CharSequence constraint, FilterResults results) { ArrayList<Integer> resultsList = (ArrayList<Integer>)results.values; if(resultsList != null) { m_filterList = resultsList; } notifyDataSetChanged(); } } public String getRegEx(CharSequence elements){ String result = "(?i).*"; for(String element : elements.toString().split("\\s")){ result += element + ".*"; } result += ".*"; return result; } Thanks in advance! 

Aquí está mi getview

 @Override public View getView(int position, View convertView, ViewGroup parent) { View rowView = convertView; ViewHolder holder; if(filtering && m_filterList != null && m_filterList.size() > position) position = m_filterList.get(position); if (rowView == null) { holder = new ViewHolder(); mInflater = context.getLayoutInflater(); rowView = mInflater.inflate(R.layout.rowlayout, null); // configure view holder holder.text = (TextView) rowView.findViewById(R.id.label); holder.text.setTextColor(Color.WHITE); holder.text.setSingleLine(); holder.text.setTextSize(15); holder.text.setEllipsize(TextUtils.TruncateAt.END); holder.text.setPadding(2, 2, 6, 2); Typeface label = Typeface.createFromAsset(holder.text.getContext().getAssets(), "fonts/arial-bold.ttf"); holder.text.setTypeface(label); holder.image = (ImageView) rowView.findViewById(R.id.icon); holder.image.setPadding(6, 4, 0, 4); holder.image.getLayoutParams().height = (int) getResources().getDimension(R.dimen.icon_width_height); holder.image.getLayoutParams().width = (int) getResources().getDimension(R.dimen.icon_width_height); rowView.setBackgroundResource(R.drawable.row_border); rowView.setPadding(2, 2, 6, 2); rowView.setTag(holder); }else { // fill data holder = (ViewHolder) rowView.getTag(); } String id = listItemsHolder.getid(position); String name = listItemsHolder.getName(position); holder.image.setVisibility(View.VISIBLE); if (name != null) { holder.text.setText(listItemsHolder.getName(position)); ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) holder.text.getLayoutParams(); params.leftMargin = 20; }else{ holder.text.setText(id); } String fullText = listItemsHolder.getName(position); // highlight search text if (mSearchText != null && !mSearchText.isEmpty()) { int startPos = fullText.toLowerCase(Locale.US).indexOf(mSearchText.toLowerCase(Locale.US)); int endPos = startPos + mSearchText.length(); if (startPos != -1) { Spannable spannable = new SpannableString(fullText); ColorStateList blueColor = new ColorStateList(new int[][]{new int[]{}}, new int[]{Color.BLUE}); TextAppearanceSpan highlightSpan = new TextAppearanceSpan(null, Typeface.BOLD, -1, blueColor, null); spannable.setSpan(highlightSpan, startPos, endPos, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); holder.text.setText(spannable); } else { holder.text.setText(fullText); } } else { holder.text.setText(fullText); } return rowView; } 

Supongamos que tiene crear un adaptador personalizado, a continuación, puede consultar el código siguiente:

  @Override public View getView(int position, View convertView, ViewGroup parent) { View view; TextView text; if (convertView == null) { view = mInflater.inflate(mResource, parent, false); } else { view = convertView; } try { if (mFieldId == 0) { // If no custom field is assigned, assume the whole resource is a TextView text = (TextView) view; } else { // Otherwise, find the TextView field within the layout text = (TextView) view.findViewById(mFieldId); } } catch (ClassCastException e) { Log.e("ArrayAdapter", "You must supply a resource ID for a TextView"); throw new IllegalStateException( "ArrayAdapter requires the resource ID to be a TextView", e); } String item = getItem(position); text.setText(item); String fullText = getItem(position); // highlight search text if (mSearchText != null && !mSearchText.isEmpty()) { int startPos = fullText.toLowerCase(Locale.US).indexOf(mSearchText.toLowerCase(Locale.US)); int endPos = startPos + mSearchText.length(); if (startPos != -1) { Spannable spannable = new SpannableString(fullText); ColorStateList blueColor = new ColorStateList(new int[][]{new int[]{}}, new int[]{Color.BLUE}); TextAppearanceSpan highlightSpan = new TextAppearanceSpan(null, Typeface.BOLD, -1, blueColor, null); spannable.setSpan(highlightSpan, startPos, endPos, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); text.setText(spannable); } else { text.setText(fullText); } } else { text.setText(fullText); } return view; } 

El mSearchText se actualizará en la siguiente performFiltering dentro de performFiltering de ArrayFilter .

 String prefixString = prefix.toString().toLowerCase(); mSearchText = prefixString; 

Puede encontrar más detalles en mi código de ejemplo aquí o en mi GitHub (con la última actualización) .

Aquí está la captura de pantalla

Introduzca aquí la descripción de la imagen

En su método de filtro , almacene la cadena utilizada para realizar el filtro:

 // Filter Class public void filter(String searchString) { this.searchString = searchString; ... // Filtering stuff as normal. } 

Debe declarar una cadena de miembro para almacenarla:

 public class ListViewAdapter extends BaseAdapter { ... String searchString = ""; ... 

Y, en getView resalta el término de búsqueda:

 public View getView(final int position, View view, ViewGroup parent) { ... // Set the results into TextViews WorldPopulation item = worldpopulationlist.get(position); holder.rank.setText(item.getRank()); holder.country.setText(item.getCountry()); holder.population.setText(item.getPopulation()); // Find charText in wp String country = item.getCountry().toLowerCase(Locale.getDefault()); if (country.contains(searchString)) { Log.e("test", country + " contains: " + searchString); int startPos = country.indexOf(searchString); int endPos = startPos + searchString.length(); Spannable spanText = Spannable.Factory.getInstance().newSpannable(holder.country.getText()); // <- EDITED: Use the original string, as `country` has been converted to lowercase. spanText.setSpan(new ForegroundColorSpan(Color.RED), startPos, endPos, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); holder.country.setText(spanText, TextView.BufferType.SPANNABLE); } ... } 

Espero eso ayude.

Esto es sólo demo para resaltar texto, puede implementar su auto llamando a highlight(searchText, originalText) en el filtro,

 public class MainActivity extends AppCompatActivity { EditText editText; TextView text; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); editText = (EditText) findViewById(R.id.editText); text = (TextView) findViewById(R.id.textView1); editText.addTextChangedListener(new TextWatcher() { @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @Override public void onTextChanged(CharSequence s, int start, int before, int count) { text.setText(highlight(editText.getText().toString(), text.getText().toString())); } @Override public void afterTextChanged(Editable s) { } }); } public static CharSequence highlight(String search, String originalText) { String normalizedText = Normalizer.normalize(originalText, Normalizer.Form.NFD).replaceAll("\\p{InCombiningDiacriticalMarks}+", "").toLowerCase(); int start = normalizedText.indexOf(search); if (start <= 0) { return originalText; } else { Spannable highlighted = new SpannableString(originalText); while (start > 0) { int spanStart = Math.min(start, originalText.length()); int spanEnd = Math.min(start + search.length(), originalText.length()); highlighted.setSpan(new BackgroundColorSpan(Color.YELLOW), spanStart, spanEnd, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); start = normalizedText.indexOf(search, spanEnd); } return highlighted; } } } 

Ponga este código antes de establecer el texto en getview

 Spannable wordtoSpan = new SpannableString("Your_text_in_getviews"); wordtoSpan.setSpan(new ForegroundColorSpan(Color.RED), 0, edtFilter .getText().toString().length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); txt_contact.setText(wordtoSpan); 

Hola en tu clase del adaptador, haces un texto del spanneble y lo fijas a tu textview, el código abajo que puedes utilizar para la referencia.

  if ("text contains filter value".toLowerCase().contains("filter".toLowerCase())) { Spannable spanText = Spannable.Factory.getInstance().newSpannable("text contains filter value".toLowerCase()); Matcher matcher = Pattern.compile("filter".toLowerCase()) .matcher("text contains filter value".toLowerCase()); while (matcher.find()) { spanText.setSpan(new ForegroundColorSpan(Color.RED), matcher.start(), matcher.start() + "filter".length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); } yourTextView.setText(spanText); } 
  • Agregar oyentes diferentes para texto en TextView
  • Cómo alinear el texto dentro de TextView en Android?
  • El texto en cursiva no funciona en la pestaña Samsung Galaxy
  • Android: maneja "Enter" en un EditText
  • ¿Cómo se cambia el texto a negrita en Android?
  • Android - ¿Por qué autolink ignora la ruta raíz de una URL?
  • Escala automática TextView Text para ajustar dentro de límites
  • El texto de Android TextView no aparece en los dispositivos Samsung
  • Codificación en Android TextView
  • ¿Cómo agregar la imagen en un texto de TextView?
  • Cómo saber cuando la página siguiente / anterior ha cargado completamente en el efecto de curl de página por harism?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.