Join FlipAndroid.COM Telegram Group: https://t.me/joinchat/F_aqThGkhwcLzmI49vKAiw


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

  • Más espacio entre líneas en TextView
  • Cómo ampliar una vista de texto en android?
  • Abrir vínculos de TextView en otra actividad, no en el navegador predeterminado
  • Programáticamente establecido izquierda dibujable en un TextView
  • Img src atributo de json valor que muestra pequeña caja de color azul en Android TextView
  • Configuración de la fuente Roboto en TextView - xml
  • Cómo hacer que el TextView arrastre en LinearLayout suave, en android?
  • Barra de acción de corte / copia personalizada para EditText que muestra las manijas de selección de texto
  • 5 Solutions collect form web for “¿Cómo resalto el texto buscado en mi filtro de búsqueda?”

    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); } 
    FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.