how do I highlight the searched text in my search filter?

后端 未结 5 2339
无人及你
无人及你 2020-12-09 12:27

I am trying to do a search such that all the \"visible\" search letters should be highlighted. I tried using spannable but that didn\'t do the trick, maybe I wasnt doing it

相关标签:
5条回答
  • 2020-12-09 12:33

    Put this code before setting text in 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);
    
    0 讨论(0)
  • 2020-12-09 12:36

    Let's assume you have create a custom adapter, then you can refer to the following code:

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

    The mSearchText will be updated at the following inside performFiltering of ArrayFilter class.

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

    You can find more details in my sample code here or my GitHub (with lastest update).

    Here is the screenshot

    0 讨论(0)
  • 2020-12-09 12:36

    In your filter method, store the string used to perform the filter:

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

    You must declare a member string to store it:

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

    And, in getView you highlight the search term:

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

    Hope it helps.

    0 讨论(0)
  • 2020-12-09 12:41

    Hi on your adapter class ,make a spanneble text and set it to your textview, the below code you can use for reference.

     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);
        }
    
    0 讨论(0)
  • 2020-12-09 12:53

    This is only demo for highlight text, you can implement your self by calling highlight(searchText, originalText) in filter,

    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;
        }
     }
    }
    
    0 讨论(0)
提交回复
热议问题