android+lucene实现全文检索并高亮关键字

转载 2015年07月09日 23:24:49

这里先假设读者对Lucene的使用比较熟悉的。

由于代码量比较多,这里我只写出一些关键的代码,全部源码请到这里下载:

android+lucene实现全文检索并高亮关键字

android+lucene实现全文检索并高亮关键字索引库

请将下载到的索引库解压后放到sdcard根目录下

源码里边的注释写的也比较详细

在andorid里实现字体高亮,若单独实现其实不是很难,但若和lucene结合使用,实现被搜索的关键字高亮,就有些麻烦事。原因在于,关键字高亮是有lucene提供的一个类(Highlighter)来管理。它的实现方式其实很简单,就是将关键字用html标签包裹起来。下边先来看一下几段关键性的代码

1.先定义一对html标签,用两个String常量来保存

  1. private static final String STARTTAG = "<font color='red'>";  
  2. private static final String ENDTAG = "</font>";  

2.通过SimpleHTMLFormatter类,我们可以设置高亮文本的样式,它返回一个Formatter类

  1. Formatter formatter = new SimpleHTMLFormatter(STARTTAG, ENDTAG);  

3.设置query对象,在query对象中,有查询的关键字

  1. Scorer scorer = new QueryScorer(query);  

4.新建一个Highlighter类,并设置参数

  1. Highlighter highlighter = new Highlighter(formatter, scorer);  
  2. // 设置高亮后的字符长度  
  3. highlighter.setTextFragmenter(new SimpleFragmenter(length));  
5.通过Highlighter类的getBestFragment方法匹配关键字,并将关键字包裹在关键字上
  1. String result = highlighter.getBestFragment(LuceneConfigurationUtil.getAnalyzer(), null, text);  
注意,这里返回的结果是存放在lucene的Document对象里边的到此就能把出现的关键字高亮起来。如果我们把这结果在浏览器显示,浏览器会帮我们解析这些html标签。但是现在结果是要显示在android上的,android如何解析?我们可以通过android提供的一个Html类来解析(这里我只提供一种解决方案,或许还有更好的解决方案,但限于能力不足,未能给出,若有,望指教)

首先我们需要将Document对象里边的数据转换成我们自定义的对象,先看一段代码

  1. public static Book DocumentToBook(Document doc) {  
  2.         Book book = new Book();  
  3.         book.setId(Integer.parseInt(doc.get("id")));  
  4.         book.setName(doc.get("name"));  
  5.         book.setFirstTitle(doc.get("firstTitle"));  
  6.         book.setSecondTitle(doc.get("secondTitle"));  
  7.         book.setContent(doc.get("content"));  
  8.         book.setUrl(doc.get("url"));  
  9.         return book;  
  10.     }  
这个方法就是把Document对象转换成我们自定义的Book对象,有了这个Book对象后,我们就可以取出book里边的属性值,用Html类的fromHtml()方法来解析html标签,先看段代码
  1. this.nameTv.setText(Html.fromHtml(name));  
  2. this.firstTitleTv.setText(Html.fromHtml(firstTitle));  
  3. this.secondTitleTv.setText(Html.fromHtml(secondTitle));  
  4. this.contentTv.setText(Html.fromHtml(content));  

这样进过解析的文本信息就可以直接放到Textview中,并在Activity中显示

这是运行的效果图:




安静我要说的还没有完呢,从上边的显示结果可以看出,搜索出来的结果集是放在ListView中的。如果我们用简单的SimpleAdapter来装载ListView是不能实现高亮的。这时候我们需要自定义一个适配器,先看一下代码

  1. public class ListViewAdapter extends BaseAdapter {  
  2.   
  3.     private Context context = null;  
  4.     private ArrayList<HashMap<String, Object>> listItem = null;  
  5.     private TextView nameTv = null;  
  6.     private TextView firstTitleTv = null;  
  7.     private TextView secondTitleTv = null;  
  8.     private TextView contentTv = null;  
  9.   
  10.     public ListViewAdapter(Context context,  
  11.             ArrayList<HashMap<String, Object>> listItem) {  
  12.         super();  
  13.         this.context = context;  
  14.         this.listItem = listItem;  
  15.     }  
  16.   
  17.     @Override  
  18.     public int getCount() {  
  19.         return listItem.size();  
  20.   
  21.     }  
  22.   
  23.     @Override  
  24.     public Object getItem(int arg0) {  
  25.         return listItem.get(arg0);  
  26.   
  27.     }  
  28.   
  29.     @Override  
  30.     public long getItemId(int position) {  
  31.         return position;  
  32.     }  
  33.   
  34.     @Override  
  35.     public View getView(int position, View convertView, ViewGroup parent) {  
  36.         // 取出数据  
  37.         String name = listItem.get(position).get("name").toString();  
  38.         String firstTitle = listItem.get(position).get("firstTitle").toString();  
  39.         String secondTitle = listItem.get(position).get("secondTitle")  
  40.                 .toString();  
  41.         String content = listItem.get(position).get("content").toString();  
  42.         View view;  
  43.   
  44.         // 获取四个Textview控件  
  45.         if (convertView == null) {  
  46.             RelativeLayout relativeLayout = (RelativeLayout) View.inflate(  
  47.                     context, R.layout.law_item, null);  
  48.             this.nameTv = (TextView) relativeLayout.findViewById(R.id.name);  
  49.             this.firstTitleTv = (TextView) relativeLayout  
  50.                     .findViewById(R.id.firstTitle);  
  51.             this.secondTitleTv = (TextView) relativeLayout  
  52.                     .findViewById(R.id.secondTitle);  
  53.             this.contentTv = (TextView) relativeLayout  
  54.                     .findViewById(R.id.content);  
  55.   
  56.             view = relativeLayout;  
  57.         } else {  
  58.             view = convertView;  
  59.   
  60.             this.nameTv = (TextView) view.findViewById(R.id.name);  
  61.             this.firstTitleTv = (TextView) view.findViewById(R.id.firstTitle);  
  62.             this.secondTitleTv = (TextView) view.findViewById(R.id.secondTitle);  
  63.             this.contentTv = (TextView) view.findViewById(R.id.content);  
  64.         }  
  65.   
  66.         // 解析在LuceneConfigurationUtil设置的html格式代码  
  67.         this.nameTv.setText(Html.fromHtml(name));  
  68.         this.firstTitleTv.setText(Html.fromHtml(firstTitle));  
  69.         this.secondTitleTv.setText(Html.fromHtml(secondTitle));  
  70.         this.contentTv.setText(Html.fromHtml(content));  
  71.           
  72.         return view;  
  73.     }  
  74.   
  75. }  

自定义适配器继承了BaseAdapter抽象类。我们这么做目的是通过重写getView()方法来获取当前的view,,进而获取到view下边的各个控件,最后才能执行那段解析html格式的代码大笑

好啦,说到这里就差不多了,具体的就看我上传的源码吧。

多说几句,这里侧重的是功能的实现,对于lucene的索引库我没有去做怎样的优化。还有,分词器用的是中国人自己开发的IKAnalyzer。老外的太蛋疼了,用过lucene的人,你们懂的。。。。

给些下载连接   

lucene-3.0.0

IKAnalyzer3.2.8


相关文章推荐

在android上使用lucene 4

lucene4使用了codec,搜索时通过反射

android 和 lucene

lucene可以放到android中使用吗?如果需要修改lucene源码,要怎么改呢?我用lucene写了一个放在android平板上的搜索器,可是不报错,但也不运行,这是怎么回事?有谁会改吗? ...

Delphi7高级应用开发随书源码

  • 2003年04月30日 00:00
  • 676KB
  • 下载

Delphi7高级应用开发随书源码

  • 2003年04月30日 00:00
  • 676KB
  • 下载

android下的全文检索支持

android系统支持全文检索, 是通过sqlite的fts3来提供支持的. 见: http://androidappdocs.appspot.com/guide/topics/searc...

Delphi7高级应用开发随书源码

  • 2003年04月30日 00:00
  • 676KB
  • 下载

FTS3数据库全文检索初体验(_id为0的灾难)

项目有个需求:移动端操作本地数据库,最大十万级数据量,需要做快速查询,当然增删改也是必不可少的。刚开始建普通表的时候就心存忧虑速度问题,果不其然查询起来超级卡,根本没法使用,网上搜索到资源FTS3/F...

iOS/Android SQLite 全文检索——FTS (Full Text Search)

前言我们的APP部分功能为了满足用户离线使用搜索的场景,使用了内置SQLite数据库的方式,随着内容的日益丰富,数据库记录快速增多,导致搜索速度明显变慢,为了提升搜索速度,给我们的数据做了全文检索的支...

如何读取搜索创建的Lucene索引内容

今天下午也总结了下Lucene索引读取搜索的过程。 先总结一下我所用的搜索索引过程中常用的API: IndexSearcher:它是用来在建立好的索引上进行搜索的,它只能以只读(IndexRead...

JAVA_WEB项目之Lucene实现检索结果排序和关键字在索引库中多字段查询结果进行高亮显示

上一篇介绍了JAVA_WEB项目之Lucene使用中文分词器IKAnalyzer3.2.8
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:android+lucene实现全文检索并高亮关键字
举报原因:
原因补充:

(最多只允许输入30个字)