2011-10-20 6 views
1

カスタムアダプタを使用して、文字列のコレクションをバインドするListViewがあります。私はまた、テキスト中のあるキーワードを強調しています。私は単語に下線を付けるためにSpannableStringと正規表現を使用していますが、これが最も効率的な方法であるかどうか疑問です。私はjava.util.regex.Matcherとregex.util.regex.Patternクラスの割り当てトラッカーで多くの割り当てを気付いています。これはアプリケーションでメモリリークの原因となっている可能性があります。私は正規表現の高価かもしれないことを知っているが、私は私がする必要があることを行う別の方法がわからない。あなたが必要としないパターンとの照合プログラムの多くを作成ListViewのSpannableString正規表現

public class Main extends ListActivity 
    { 
     private static CustomAdapter adapter = null; 
private static List<Keyword> keywords; 
private static Matcher matcher; 

    @Override 
    public void onCreate(Bundle icicle) 
    { 
      List<Item> items = new ArrayList<Item>(); 
    keywords = GetKeywords(); 
     items = GetItems(); 
      adapter = new CustomAdapter(); 

      for (Item item : items) 
       adapter.addItem(item); 

      this.setListAdapter(adapter); 

    adapter.notifyDataSetChanged(); 
    } 

     /* ADAPTER */ 
private class CustomAdapter extends BaseAdapter 
     {  
    private final List<Item> mData = new ArrayList<Item>(); 
    private final LayoutInflater mInflater; 
    public CustomAdapter() { 
     mInflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
    } 

    public void addItem(Item item) { 
     mData.add(item); 
    } 

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

    @Override 
    public Object getItem(int position) { 
     return mData.get(position); 
    } 

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

    @Override 
    public View getView(int position, View convertView, ViewGroup parent) 
    { 
     final ViewHolder holder; 
     final Item item = (Item)this.getItem(position); 

     if (convertView == null) 
     { 
      holder = new ViewHolder(); 

      convertView = mInflater.inflate(R.layout.main, parent, false); 

      holder.text = (TextView)convertView.findViewById(R.id.text); 

      convertView.setTag(holder); 
     } 
     else 
     { 
      holder = (ViewHolder)convertView.getTag(); 
     } 

      holder.text.setText(Highlight(item.getTitle(), keywords, matcher), BufferType.SPANNABLE); 

     return(convertView); 
    } 
} 

static class ViewHolder { 
    TextView text, date, site; 
} 

private SpannableString Highlight(String text, List<Keyword> keywords, Matcher matcher) 
{ 
    final SpannableString content = new SpannableString(text); 

    for (Keyword keyword : keywords) 
    { 
     matcher = Pattern.compile("\\b" + keyword + "\\b").matcher(text); 

     if (matcher.find()) 
     { 
      start = matcher.start(); 
      end = matcher.end(); 
      content.setSpan(new UnderlineSpan(), start, end, 0); 
     } 
    } 
    } 


    return content; 
    } 
} 

答えて

3

あなたある

private SpannableString Highlight(String text, List<Keyword> keywords) 
{ 
    final SpannableString content = new SpannableString(text); 

    if (keywords.size() > 0) 
    { 
    /* create a regex of the form: \b(?:word1|word2|word3)\b */ 
    StringBuilder sb = ne StringBuilder("\\b(?:").append(keywords.get(0).toString()); 
    for (int i = 1; i < keywords.size(); i++) 
    { 
     sb.append("|").append(keywords.get(i).toString()); 
    } 
    sb.append(")\\b"); 

    Matcher m = Pattern.compile(sb.toString()).matcher(text); 

    while (m.find()) 
    { 
     content.setSpan(new UnderlineSpan(), m.start(), m.end(), 0); 
    } 
    } 

    return content; 
} 

パターンのオブジェクトが作成するのは非常に高価なので、あなたの本当の貯蓄から来る場所それはだ:私はあなたがこのような全てのキーワードに一致する一つの正規表現を作成することをおすすめします。一方、Matchersは比較的安価です。そのため、静的インスタンスを使用することから、毎回新しいインスタンスを作成することに切り替えました。

+0

ありがとう、私はこれを後でテストしてお知らせします。 –

+0

このコードを実装するだけで、うまくいきました。私の割り当ての多くを減らしました。どうもありがとう! –