在自定义适配器ListView中突出显示搜索文本

3

我有一个ListView,并想从中搜索文本。我已经成功实现了搜索功能,但现在我想在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 用于此目的,但它无法工作。请帮助我,并告诉我是否需要其他相关代码。

编辑:
我所遵循的教程来自这里。我使用了相同的代码,只做了一些小改动。我只想在列表视图中(例如本例中的一个国家)突出显示搜索到的文本。

您没有将 spannable 设置到任何视图中。它只是被创建了,但没有在任何地方使用。 - Juanjo Vega
我也尝试将其设置为视图,但是当我打印时,我得到的视图是空的。这是我尝试过的代码:final ViewHolder holder = new ViewHolder(); View view = inflater.inflate(R.layout.listview_item, null); holder.country = (TextView) view.findViewById(R.id.country); holder.country.setText(spannable); - Sibtain
请用您目前的代码更新您的回答,我会查看它。 - Juanjo Vega
实际上我是从这里 http://www.androidbegin.com/tutorial/android-search-listview-using-filter/ 下载了代码。我使用的是同样的代码,只是不知道如何突出显示搜索到的文本。请帮帮我,谢谢。 - Sibtain
http://stackoverflow.com/questions/30206679/searching-custom-listview-with-searched-textcolor-highlighted-in-listview-androi - Quick learner
3个回答

16

好的,我下载了示例项目并最终得出以下结果。根据您的需求调整代码。

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

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

希望这有所帮助。


0

使用以下代码来从搜索/编辑文本中突出显示搜索文本

输入是已过滤的名称,mTextview是您想要突出显示的文本视图,在设置文本视图的值之后,请使用此方法。

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

0

你可以这样做...

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接