Android span在列表视图中删除正则表达式
我有一个ListView,我正在使用自定义适配器将字符串集合绑定到它。我还在文本中的某些关键字下划线。我使用了一个SpannableString和一个正则表达式来给单词加下划线,但我想知道这是否是最有效的方法?我注意到java.util.regex.Matcher和regex.util.regex.Pattern类的分配跟踪程序中存在大量分配,这可能会导致我的应用程序内存泄漏。我知道正则表达式可能很昂贵,但我不确定是否有其他方法来完成我需要做的事情Android span在列表视图中删除正则表达式,android,regex,spannablestring,Android,Regex,Spannablestring,我有一个ListView,我正在使用自定义适配器将字符串集合绑定到它。我还在文本中的某些关键字下划线。我使用了一个SpannableString和一个正则表达式来给单词加下划线,但我想知道这是否是最有效的方法?我注意到java.util.regex.Matcher和regex.util.regex.Pattern类的分配跟踪程序中存在大量分配,这可能会导致我的应用程序内存泄漏。我知道正则表达式可能很昂贵,但我不确定是否有其他方法来完成我需要做的事情 public class Main e
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;
}
}
public类主扩展ListActivity
{
私有静态CustomAdapter=null;
私有静态列表关键字;
私有静态匹配器;
@凌驾
创建公共空间(捆绑冰柱)
{
列表项=新建ArrayList();
关键词=获取关键词();
items=GetItems();
适配器=新的CustomAdapter();
用于(项目:项目)
适配器.附件(项目);
这个.setListAdapter(适配器);
adapter.notifyDataSetChanged();
}
/*适配器*/
私有类CustomAdapter扩展了BaseAdapter
{
私有最终列表mData=new ArrayList();
私人最终布局平面图;
公共自定义适配器(){
mInflater=(LayoutInflater)getSystemService(Context.LAYOUT\u INFLATER\u SERVICE);
}
公共无效附加项(项目){
mData.add(项目);
}
@凌驾
public int getCount(){
返回mData.size();
}
@凌驾
公共对象getItem(int位置){
返回mData.get(位置);
}
@凌驾
公共长getItemId(int位置){
返回位置;
}
@凌驾
公共视图getView(int位置、视图转换视图、视图组父视图)
{
最终持票人;
最终项目=此.getItem(位置)的(项目);
if(convertView==null)
{
holder=新的ViewHolder();
convertView=mInflater.充气(R.layout.main,父项,false);
holder.text=(TextView)convertView.findViewById(R.id.text);
convertView.setTag(支架);
}
其他的
{
holder=(ViewHolder)convertView.getTag();
}
holder.text.setText(突出显示(item.getTitle()、关键字、匹配器)、BufferType.SPANNABLE);
返回(转换视图);
}
}
静态类视窗夹{
文本查看文本、日期、站点;
}
私人SpannableString高亮显示(字符串文本、列表关键字、匹配器匹配器)
{
最终SpannableString内容=新SpannableString(文本);
for(关键字:关键字)
{
matcher=Pattern.compile(“\\b”+关键字+“\\b”).matcher(文本);
if(matcher.find())
{
start=matcher.start();
end=matcher.end();
setSpan(新的下划线span(),开始,结束,0);
}
}
}
返回内容;
}
}
您正在创建许多不需要的模式和匹配器。我建议您创建一个正则表达式来匹配所有关键字,如下所示:
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;
}
private SpannableString高亮显示(字符串文本、列表关键字)
{
最终SpannableString内容=新SpannableString(文本);
如果(关键字.size()>0)
{
/*创建以下格式的正则表达式:\b(?:word1 | word2 | word3)\b*/
StringBuilder sb=ne StringBuilder(“\\b(?).append(关键字.get(0).toString());
对于(int i=1;i
模式对象的创建非常昂贵,所以这才是您真正节省的地方。另一方面,Matcher相对便宜,这就是为什么我每次都从使用静态实例切换到创建一个新实例的原因。谢谢,我稍后会对此进行测试并让您知道。刚刚实现了这段代码,效果非常好。减少了我的很多分配。非常感谢!