名词解释功能:TextView 给部分文字加下划线并实现点击事件

本文介绍了一种在Android应用中实现文本关键词高亮显示及点击跳转的方法,通过自定义TextView并结合数据库查询,实现了关键词的识别、高亮及点击后的详细解释展示。

原文:http://my.oschina.net/freestyletime/blog/113149

效果图先摆上,其中只有一个关键字,但无论几个都行的,作者已然测试了很多遍。

最近要做一个名词解释的功能:在一段文本里有N个关键名词,这些关键名词需要将这段文本与本地数据库相比较后得到。

1 public PhraseItem(long id, String name) {
2             this.id = id;
3             this.name = name;}
这个Bean中有两个属性,分别代表在数据库中的ID(方便以后查),和关键词,比如:窦性心率过速。



1 public Map<Integer, PhraseItem> searchKeyWords(String string)


该函数将识别一段文本中的所有关键字, 返回一个TreeMap (自动排序),其中的key值代表该关键字的Index。

 

01 final Map<Integer, PhraseItem> keywords = mKeyWordManger.searchKeyWords(content);
02  
03 Set<Entry<Integer, PhraseItem>> entrys = keywords.entrySet();
04             int count = 0;
05             int start = 0;
06             String key;
07             for (Entry<Integer, PhraseItem> entry : entrys) {
08  
09                 start = entry.getKey();
10                 key = entry.getValue().getName();
11  
12                 tv_msg.append(content.substring(count, start));
13                 tv_msg.append(Html.fromHtml("<a href=" + start + " ><u>" + key
14                         "</u></a>"));
15  
16                 count = start + key.length();
17             }
18  
19             tv_msg.append(content.substring(count));


其中的tv_msg是TextView,它有一个append函数,可以不断的向其中添加可视文本。

我遍历了整个关键字的Map , 因为它本身是TreeMap ,所以里面的Entry已经帮你按key值的大小从小到大帮你排好了序。所以可以从容的对一段文本中的普通文本与关键字进行切割。

置于For循环以外的tv_msg.append(content.substring(count))指的是添加在最后一个关键字以后的普通文本,这是必须要加的,否则整个文本将不完整。这还是很简单的,

不过关键的地方在于tv_msg.append(Html.fromHtml("<a href=" + start + " ><u>" + key + "</u></a>"));

我们将利用这句话给关键字加下划线,利用其中的href属性识别关键字为进行点击做准备。


01 tv_msg.setMovementMethod(LinkMovementMethod.getInstance());
02     CharSequence text = tv_msg.getText();
03  
04     if (text instanceof Spannable) {
05         int end = text.length();
06         Spannable sp = (Spannable) text;
07         URLSpan[] urls = sp.getSpans(0, end, URLSpan.class);
08         SpannableStringBuilder style = new SpannableStringBuilder(text);
09         style.clearSpans();
10         for (final URLSpan url : urls) {
11         style.setSpan(
12             new ClickableSpan() {  
13                 @Override
14                 public void onClick(View keyView) {
15                 PhraseItem word = keywords.get(Integer.valueOf(url.getURL()));
16                 Intent mIntent = new Intent(MessageActivity.this,KeyWordActivity.class);
17                 mIntent.putExtra(KeyWordActivity.KEY_NAME,word.getName());
18                 mIntent.putExtra(KeyWordActivity.KEY_INFOS,
19                 mKeyWordManger.searchPhrase(word.getId()));
20                     startActivity(mIntent);
21                 }}, sp.getSpanStart(url), sp.getSpanEnd(url),
22                 Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
23                 }
24         tv_msg.setText(style);
25         }


这个从数据库到前台做了3天,查阅了好些资料经过各种尝试才搞出来的。想要把名词解释变的很简单,必须得好好设计一下数据库的表结构才行,如果你还想点击后让超链接变色,可以尝试重写TextView的onTouch事件,这个很复杂了,不过是可以实现的。或者给<a/>标签添加style属性,这个得熟悉CSS,作者没试过这种方法,大家可以试试。

这里是Freestyletime@foxmail.com,欢迎交流。

本人原创作品,转载请标明出处。


续:点击后让超链接变色楼主已经找到了解决方法!!!


上图:


在项目的维护过程中,楼主想到了一个简单的办法解决了超链接点击后无法变色以提醒用户看过该信息的功能。

01 style.setSpan(
02                             new ClickableSpan() {
03  
04                                 private boolean isClick = false;
05                                 private TextPaint ds;
06                                  
07                                 @Override
08                                 public void updateDrawState(TextPaint ds) {
09                                      
10                                     if(isClick){
11                                         ds.setColor(Color.GREEN);
12                                     }else{
13                                         this.ds = ds;
14                                         ds.setColor(Color.RED);
15                                     }
16                                     ds.setUnderlineText(true);
17                                 }
18  
19                                 @Override
20                                 public void onClick(View keyView) {
21                                      
22                                     isClick = true;
23                                      
24                                     PhraseItem word = keywords.get(Integer
25                                             .valueOf(url.getURL()));
26  
27                                     Intent mIntent = new Intent(
28                                             MessageActivity.this,
29                                             KeyWordActivity.class);
30  
31                                     mIntent.putExtra(KeyWordActivity.KEY_NAME,
32                                             word.getName());
33                                     mIntent.putExtra(KeyWordActivity.KEY_INFOS,
34                                             mKeyWordManger.searchPhrase(word
35                                                     .getId()));
36  
37                                     startActivity(mIntent);
38                                      
39                                     updateDrawState(ds);
40  
41                                 }
42                             }, sp.getSpanStart(url), sp.getSpanEnd(url),
43                             Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

让你的ClickableSpan再点击后再次调用内部的updateDrawState这个方法更新一下当前文本颜色即可,简单吧!!

有什么更好的可以提出大家一起讨论。

内容概要:本文提出了一种基于改进扩散模型的高海拔地区新能源高波动出力场景生成方法,提供了完整的Python代码实现。该方法针对高海拔地区风能、光伏等新能源出力波动剧烈、不确定性高的特点,通过优化扩散模型的结构与训练策略,有效捕捉历史数据的概率分布特征与时序相关性,从而生成高质量、多样化的出力场景。文中详细阐述了模型的数学推导、网络架构设计、损失函数优化及采样算法改进,通过实验证明其在拟合精度、场景多样性与稳定性方面优于传统生成模型,为电力系统在高比例新能源接入下的规划、调度与风险评估提供了可靠的场景输入支持。; 适合人群:具备一定Python编程能力和机器学习基础,从事新能源发电预测、电力系统分析、智能优化、场景生成等方向研究的科研人员、高校研究生及工程技术人员。; 使用场景及目标:①用于高海拔地区风电、光伏出力的不确定性建模与多场景生成;②支撑含高渗透率新能源的电力系统随机优化调度、鲁棒决策与风险评估;③为相关学术研究、论文复现与算法改进提供可运行的技术方案与代码基础; 阅读建议:建议读者结合所提供的完整资源(代码、数据集、说明文档)进行实践操作,重点关注扩散模型的前向噪与反向去噪过程的设计细节,以及如何将其适配于新能源时序数据的生成任务,通过参数调优与对比实验深入理解模型的生成机制与性能边界。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值