在自定义适配器列表视图中突出显示搜索到的文本

Highlight searched text in custom adapter listview

我有一个列表视图,想从中搜索文本。我已经成功完成了,但现在我想搜索该项目并在列表视图中突出显示搜索到的文本。这是我在 ListViewAdapter 中的过滤函数:

public void filter(String charText) {

    charText = charText.toLowerCase(Locale.getDefault());
    worldpopulationlist.clear();
    if (charText.length() == 0) {
        worldpopulationlist.addAll(arraylist);
    } 
    else 
    {
        for (WorldPopulation wp : arraylist) 
        {
            // Find charText in wp
            int startPos = wp.getCountry().toLowerCase(
                    Locale.getDefault()).indexOf(charText.toLowerCase(Locale.getDefault()));
            int endPos = startPos + charText.length();
            if (startPos != -1) 
            {
                   Spannable spannable = new SpannableString(wp.getCountry());
                    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);
                   //    countryTextView.setText(spannable);
                    worldpopulationlist.add(wp);

            }

        }
    }
    notifyDataSetChanged();

}

我用谷歌搜索了一下,我知道 Spannable 用于此目的,但它不起作用。如果您需要任何其他相关代码,请帮助我并告诉我。

编辑:

我遵循的教程来自 here。我使用了相同的代码并做了一些小改动。我只想在列表视图中突出显示搜索到的文本(在本例中只是一项,例如国家/地区)。

嗯,我下载了示例工程,终于来了如下。根据您的需要调整代码。

在您的过滤方法中,存储用于执行过滤的字符串:

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

您必须声明一个成员字符串来存储它:

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

然后,在 getView 中突出显示搜索词:

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

希望对您有所帮助。

你可以这样做..

 public class ListViewAdapter extends BaseAdapter {

    // Declare Variables
    Context mContext;
    LayoutInflater inflater;
    String searchstring="";
    private List<WorldPopulation> worldpopulationlist = null;
    private ArrayList<WorldPopulation> arraylist;

    public ListViewAdapter(Context context, List<WorldPopulation> worldpopulationlist) {
        mContext = context;
        this.worldpopulationlist = worldpopulationlist;
        inflater = LayoutInflater.from(mContext);
        this.arraylist = new ArrayList<WorldPopulation>();
        this.arraylist.addAll(worldpopulationlist);
    }

    public class ViewHolder {
        TextView rank;
    }

    @Override
    public int getCount() {
        return worldpopulationlist.size();
    }

    @Override
    public WorldPopulation getItem(int position) {
        return worldpopulationlist.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    public View getView(final int position, View view, ViewGroup parent) {
        final ViewHolder holder;
        if (view == null) {
            holder = new ViewHolder();
            view = inflater.inflate(R.layout.listview_item, null);
            // Locate the TextViews in listview_item.xml
            holder.rank = (TextView) view.findViewById(R.id.ranklabel);

            view.setTag(holder);
        } else {
            holder = (ViewHolder) view.getTag();
        }
        // Set the results into TextViews

        String faqsearchstr=worldpopulationlist.get(position).getRank().toLowerCase(Locale.getDefault());

         if (faqsearchstr.contains(searchstring)) {
                Log.e("test", faqsearchstr + " contains: " + searchstring);
                System.out.println("if search text"+faqsearchstr);
                int startPos = faqsearchstr.indexOf(searchstring);
                int endPos = startPos + searchstring.length();

                Spannable spanText = Spannable.Factory.getInstance().newSpannable(worldpopulationlist.get(position).getRank()); // <- EDITED: Use the original string, as `country` has been converted to lowercase.
                spanText.setSpan(new ForegroundColorSpan(Color.GREEN), startPos, endPos, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

                holder.rank.setText(spanText, TextView.BufferType.SPANNABLE);
            }
         else 
         {
             System.out.println("else search text"+faqsearchstr);
             holder.rank.setText(worldpopulationlist.get(position).getRank());
         }


        // Listen for ListView Item Click
        view.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View arg0) {
                // Send single item click data to SingleItemView Class
                Intent intent = new Intent(mContext, QuestionActivity.class);
                // Pass all data rank
            //  intent.putExtra("rank",(worldpopulationlist.get(position).getRank()));
                intent.putExtra("QuestionsIntent",((worldpopulationlist.get(position).getFaqpopulatedData())));

                System.out.println("questionsss.."+(worldpopulationlist.get(position).getFaqpopulatedData()));
                // Start SingleItemView Class
                mContext.startActivity(intent);
            }
        });

        return view;
    }

    // Filter Class
    public void filter(String charText) {
        this.searchstring=charText;
        charText = charText.toLowerCase(Locale.getDefault());
        worldpopulationlist.clear();
        if (charText.length() == 0) {
            System.out.println("inside filter if");
            worldpopulationlist.addAll(arraylist);
        } 
        else 
        {
            for (WorldPopulation wp : arraylist) 
            {
                if (wp.getRank().toLowerCase(Locale.getDefault()).contains(charText)) 
                {
                    System.out.println("inside filter else");
                    worldpopulationlist.add(wp);
                }
            }
        }
        notifyDataSetChanged();
    }
 }

使用以下代码突出显示来自 search/edit text

的搜索文本

input is filtered name and mTextview is your text view which you want to highlight use this method after setting value to text view.

 private void highlightString(String input, TextView mTextView) {
    SpannableString spannableString = new SpannableString(mTextView.getText());
    ForegroundColorSpan[] backgroundSpans = spannableString.getSpans(0, spannableString.length(), ForegroundColorSpan.class);

    for (ForegroundColorSpan span : backgroundSpans) {
        spannableString.removeSpan(span);
    }

    int indexOfKeyword = spannableString.toString().indexOf(input);

    while (indexOfKeyword > 0) {
        spannableString.setSpan(new ForegroundColorSpan(Color.GREEN), indexOfKeyword, indexOfKeyword + input.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);

        indexOfKeyword = spannableString.toString().indexOf(input, indexOfKeyword + input.length());
    }

    mTextView.setText(spannableString);
}