最近在做项目研发过程中有这样一个需求:ListView的Item里的子控件TextView要设置超链接、指定文字高亮显示,然后点击超链接后跳转到指定URL的网页。实现超链接的跳转这很容易,只要通过对TextView设置SpannableString对象即可,即如下代码:
TextView tv = (TextView)findViewById(R.id.tv); SpannableString sp = new SpannableString("此处为tv里显示的内容"); sp.setSpan( new URLSpan( "http://www.baidu.com" ), 3 , 8 , Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); tv.setText(sp); tv.setMovementMethod(LinkMovementMethod.getInstance());
通过这样的设置后已经能够实现对超链接点击跳转到指定URL的网页了,可麻烦又来了,你会发现点击ListView里的Item时没有任何反应,这是什么原因呢?还记得上面在设置超链接的时候有这样一条语句:tv.setMovementMethod(LinkMovementMethod.getInstance());我们现在把这条语句注释掉看看……run App,结果点击Item的时候能够响应了,可惜超链接又失效了,任你点击也没有响应了,哎,真可谓是“鱼和熊掌不可兼得”。现在已经断定Item失效的原因何在了,那为什么这条语句就会导致Item点击失效呢?源码往往是揭开程序中各种奇芭问题的尖锐利器,让我们跟踪下源码吧……打开TextView的源码文件,截取的关键代码片段如下:
该代码片段是TextView源码的第1421行(Android4.2.2版本),我们发现不能通过重写此方法来解决我们所面临的问题,再继续跟踪LinkMovementMethod这个类吧,关键源码如下:
@Override public boolean onTouchEvent(TextView widget, Spannable buffer, MotionEvent event) { int action = event.getAction(); if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_DOWN) { int x = (int) event.getX(); int y = (int) event.getY(); x -= widget.getTotalPaddingLeft(); y -= widget.getTotalPaddingTop(); x += widget.getScrollX(); y += widget.getScrollY(); Layout layout = widget.getLayout(); int line = layout.getLineForVertical(y); int off = layout.getOffsetForHorizontal(line, x); //获取textview里的超链接对象,并用ClickableSpan数组盛装 ClickableSpan[] link = buffer.getSpans(off, off, ClickableSpan.class); if (link.length != 0) { //此处是对超链接点击事件进行处理…… if (action == MotionEvent.ACTION_UP) { link[0].onClick(widget); } else if (action == MotionEvent.ACTION_DOWN) { Selection.setSelection(buffer, buffer.getSpanStart(link[0]), buffer.getSpanEnd(link[0])); } return true; //处理结束后返回true,这里一定要注意:当返回值为true时则表示点击事件已经被,就再也不会继续传递了 } else { Selection.removeSelection(buffer); } } return super.onTouchEvent(widget, buffer, event); }
上述源码为LinkMovementMethod类的第188行。发现了Item点击失效的原因是因为onTouch方法总是返回true而并没有根据不同的情况来作处理,此时大家可能会想直接对这个方法重写就能解决问题了。我和大家想的也一样,对该方法重写,并根据情况返回true或false,遗憾的是还是没有效果,并且在重写的方法里看不到输出的日志信息,暂时不明其中原因,请高手赐教!眼看就要看到光明了,可还是被打击了……不要灰心,面包总是会有的,如果你不放弃的话,哈哈。换个keywords google一下,终于找到国外的一个网站,上面的文章标题是:
此时此刻的心情真是如获至宝呀……接着看下去……发现有高人是这样解决的:
发现这位高人本质思路是我们开始分析的本质思路一样,只不过他把要处理的代码放在了TextView的onTouch方法里,然后根据不同的情况返回true或false.在getView()方法里对相应的TextView进行设置吧,Run app……见证奇迹的时刻到了……哈哈,结果真的能行了,耶哦!
原文链接:http://stackoverflow.com/questions/8558732/listview-textview-with-linkmovementmethod-makes-list-item-unclickable
经过此劫,我发现了为什么国外的技术总是比国内要先进得多了,我在此并不是贬低同僚,不支持国产,而是在国内的技术普遍都是你抄我,我抄你的,有的甚至连原文链接都不放……大家可以看看国外这个技术网站人家是怎么解决问题的,真是按部就班,循序渐进的,不仅让你知其然还知其所以然。
欢迎加入QQ讨论群:285077071
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。