Android Linkify.addLinks() 适用于一个 textview 而不是另一个
Posted
技术标签:
【中文标题】Android Linkify.addLinks() 适用于一个 textview 而不是另一个【英文标题】:Android Linkify.addLinks() works for one textview and not the other one 【发布时间】:2020-04-18 15:16:01 【问题描述】:我有一个聊天实现,类似于我的应用中的 whatsapp。
在聊天中,我有一个接收者状态和一个发送者状态。
我面临的问题是,在发件人状态下,我发送的链接根本不可点击,尽管我对它们都执行了完全相同的代码。
这是我对待发件人视图持有者的方式 -
private void handleMessageForSender(Message item, TxtViewHolder txtViewHolder, String time, String msg)
txtViewHolder.getViewSender().setVisibility(View.VISIBLE);
txtViewHolder.getTxtChatTime().setText(time);
txtViewHolder.getTxtChatTime().setTextColor(context.getResources()
.getColor(R.color.color_black));
txtViewHolder.getTxtChatTime().setVisibility(View.VISIBLE);
txtViewHolder.getTxtChatSender().setTextColor(context.getResources()
.getColor(R.color.color_black));
boolean oneRowWithLink = false;
Matcher matcher = android.util.Patterns.WEB_URL.matcher(messageDetail.getMessage() != null && (item.getRecall() == null || !item.getRecall()) && messageDetail.getMessage().contains("http") ? messageDetail.getMessage() : "");
if (matcher.find())
oneRowWithLink = true;
String urlMessage = matcher.group(1);
LinkPreviewModel linkPreviewModel = linkPreviewModelHashMap.get(urlMessage);
if (linkPreviewModel != null)
txtViewHolder.getViewSender().setPadding(0, 0, 0, 4);
txtViewHolder.getLinkSentLayout().setVisibility(View.VISIBLE);
txtViewHolder.getLinkTitle().setText(linkPreviewModel.getTitle());
txtViewHolder.getLinkTitle().setTypeface(null, Typeface.BOLD);
txtViewHolder.getLinkMainUrl().setText(linkPreviewModel.getLinkMainUrl());
if (linkPreviewModel.getImageUrl() != null && linkPreviewModel.getImageUrl().length() > 0)
linkPreviewModelPositionsMap.put(item.getMid(), linkPreviewModel.getImageUrl());
MediaUtils.loadImageWithGlide(context, linkPreviewModel.getImageUrl(),
txtViewHolder.getLinkImageUrl(), R.drawable.ic_image_placeholder);
else
txtViewHolder.getLinkImageUrl().setVisibility(View.GONE);
if (linkPreviewModel.getDescription() != null && linkPreviewModel.getDescription().length() > 0)
txtViewHolder.getLinkDescription().setVisibility(View.VISIBLE);
txtViewHolder.getLinkDescription().setText(linkPreviewModel.getDescription());
else
txtViewHolder.getLinkDescription().setVisibility(View.GONE);
else
txtViewHolder.getLinkSentLayout().setVisibility(View.GONE);
parseLink(urlMessage);
else
txtViewHolder.getLinkSentLayout().setVisibility(View.GONE);
txtViewHolder.getViewSender().setPadding(4, 4, 4, 4);
if (item.getRecall() != null && item.getRecall())
displayRecallInfo(item, txtViewHolder);
else
txtViewHolder.getImgChatStatus().setVisibility(View.VISIBLE);
txtViewHolder.getSentRecallImage().setVisibility(View.GONE);
txtViewHolder.getTxtChatSender().setTypeface(Typeface.DEFAULT, Typeface.NORMAL);
txtViewHolder.getTxtChatSender().setTextKeepState(gethtmlChatMessageText(msg));
Linkify.addLinks(txtViewHolder.getTxtChatReceiver(), Linkify.WEB_URLS | Linkify.EMAIL_ADDRESSES | Linkify.PHONE_NUMBERS);
chatMessageUtils.setRecentChatStatus(txtViewHolder.getImgChatStatus(), item.getStatus());
new TextReplyViewUtils().showSenderReplyWindow(txtViewHolder, item, context);
txtViewHolder.getTxtChatSender().measure(0, 0);
if (!oneRowWithLink && txtViewHolder.getTxtChatSender().getMeasuredWidth() < (SCREEN_WIDTH * 70) / 100 && txtViewHolder.getTxtChatSender().getLineCount() == 1 && TextUtils.isEmpty(item.getReplyTo()))
//set time layout new parameters
txtViewHolder.getSenderTimeLayout().measure(FrameLayout.LayoutParams.WRAP_CONTENT, FrameLayout.LayoutParams.WRAP_CONTENT);
txtViewHolder.getImageStar().measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
if (defaultViewSendTimeWidth == -1)
defaultViewSendTimeWidth = txtViewHolder.getSenderTimeLayout().getMeasuredWidth();
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT, FrameLayout.LayoutParams.WRAP_CONTENT);
params.gravity = Gravity.BOTTOM | Gravity.END;
params.topMargin = isHighResolutionHeight ? 25 : 15;
txtViewHolder.getSenderTimeLayout().setLayoutParams(params);
int fixedWidth = (item.getFavourite() != null && item.getFavourite()) ? txtViewHolder.getSenderTimeLayout().getMeasuredWidth() : defaultViewSendTimeWidth - 20;
LinearLayout.LayoutParams params1 = new LinearLayout.LayoutParams(txtViewHolder.getTxtChatSender().getMeasuredWidth() + fixedWidth,
LinearLayout.LayoutParams.WRAP_CONTENT);
txtViewHolder.getTxtChatSender().setLayoutParams(params1);
// if one row, set always in left
txtViewHolder.getTxtChatSender().setGravity(Gravity.LEFT);
//reduce margin bottom to txt view(because space..)
FrameLayout.LayoutParams params2 = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT,
FrameLayout.LayoutParams.WRAP_CONTENT);
params2.bottomMargin = isHighResolutionHeight ? -60 : -30;
txtViewHolder.getViewSendLayout().setLayoutParams(params2);
else
// need this code because it is view holder that reuse layouts
//return time layout to basic parameters
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT, FrameLayout.LayoutParams.WRAP_CONTENT);
params.gravity = Gravity.BOTTOM | Gravity.END;
txtViewHolder.getSenderTimeLayout().setLayoutParams(params);
//return chat text view to basic parameters
LinearLayout.LayoutParams params1 = new LinearLayout.LayoutParams(TextUtils.isEmpty(item.getReplyTo()) ? LinearLayout.LayoutParams.WRAP_CONTENT :
LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
txtViewHolder.getTxtChatSender().setLayoutParams(params1);
if (checkRtl(txtViewHolder.getTxtChatSender().getText().toString()))
txtViewHolder.getTxtChatSender().setGravity(Gravity.RIGHT);
else
txtViewHolder.getTxtChatSender().setGravity(Gravity.LEFT);
//return view receive to basic parameters
FrameLayout.LayoutParams params2 = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT,
FrameLayout.LayoutParams.WRAP_CONTENT);
txtViewHolder.getViewSendLayout().setLayoutParams(params2);
if (forwardUtils.isSendForwardUtils(userJID, messageDetail.getCreatedBy(), item.getGroupChatSender() != null && item.getGroupChatSender().length() > 0
? item.getGroupChatSender() : item.getChatUser()))
txtViewHolder.getForwardSendLayout().setVisibility(View.VISIBLE);
else
txtViewHolder.getForwardSendLayout().setVisibility(View.GONE);
这是我对待接收者状态的方式 -
private void handleMessageForReceiver(Message item, TxtViewHolder txtViewHolder, String time, String msg)
txtViewHolder.getViewReceiver().setVisibility(View.VISIBLE);
txtViewHolder.getTxtChatRevTime().setText(time);
txtViewHolder.getTxtChatRevTime().setVisibility(View.VISIBLE);
txtViewHolder.getTxtChatReceiver().setTextColor(context.getResources()
.getColor(R.color.color_black));
boolean oneRowWithLink = false;
if (forwardUtils.isReceiveForwardUtils(userJID, messageDetail.getCreatedBy(), item.getGroupChatSender() != null && item.getGroupChatSender().length() > 0
? item.getGroupChatSender() : item.getChatUser()))
txtViewHolder.getForwardReceiveLayout().setVisibility(View.VISIBLE);
else
txtViewHolder.getForwardReceiveLayout().setVisibility(View.GONE);
Matcher matcher1 = android.util.Patterns.WEB_URL.matcher(messageDetail.getMessage() != null && (item.getRecall() == null || !item.getRecall()) && messageDetail.getMessage().contains("http") ? messageDetail.getMessage() : "");
if (matcher1.find())
oneRowWithLink = true;
String urlMessage = matcher1.group(1);
LinkPreviewModel linkPreviewModel = linkPreviewModelHashMap.get(urlMessage);
if (linkPreviewModel != null)
// txtViewHolder.getFullReceiveLayout().setPadding(0,0,0,4);
txtViewHolder.getLinkRecLayout().setVisibility(View.VISIBLE);
txtViewHolder.getLinkTitleReceive().setText(linkPreviewModel.getTitle());
txtViewHolder.getLinkTitleReceive().setTypeface(null, Typeface.BOLD);
txtViewHolder.getLinkMainUrlReceive().setText(linkPreviewModel.getLinkMainUrl());
if (linkPreviewModel.getImageUrl() != null && linkPreviewModel.getImageUrl().length() > 0)
linkPreviewModelPositionsMap.put(item.getMid(), linkPreviewModel.getImageUrl());
MediaUtils.loadImageWithGlide(context, linkPreviewModel.getImageUrl(),
txtViewHolder.getLinkImageUrlReceive(), R.drawable.ic_image_placeholder);
else
txtViewHolder.getLinkImageUrlReceive().setVisibility(View.GONE);
if (linkPreviewModel.getDescription() != null && linkPreviewModel.getDescription().length() > 0)
txtViewHolder.getLinkDescriptionReceive().setVisibility(View.VISIBLE);
txtViewHolder.getLinkDescriptionReceive().setText(linkPreviewModel.getDescription());
else
txtViewHolder.getLinkDescriptionReceive().setVisibility(View.GONE);
else
txtViewHolder.getLinkRecLayout().setVisibility(View.GONE);
parseLink(urlMessage);
else
txtViewHolder.getLinkRecLayout().setVisibility(View.GONE);
// txtViewHolder.getFullReceiveLayout().setPadding(6,6,6,6);
if (item.getRecall() != null && item.getRecall())
displayRecallInfo(item, txtViewHolder);
else
txtViewHolder.getReceivedRecallImage().setVisibility(View.GONE);
txtViewHolder.getTxtChatReceiver().setTypeface(Typeface.DEFAULT,
Typeface.NORMAL);
txtViewHolder.getTxtChatReceiver().setTextKeepState(getHtmlChatMessageText
(msg));
Linkify.addLinks(txtViewHolder.getTxtChatReceiver(), Linkify.WEB_URLS | Linkify.EMAIL_ADDRESSES | Linkify.PHONE_NUMBERS);
chatMessageUtils.setRecentChatStatus(txtViewHolder.getImgChatStatus(),
item.getStatus());
new TextReplyViewUtils().showReceiverReplyWindow(txtViewHolder, item, context);
txtViewHolder.getTxtChatReceiver().measure(0, 0);
if (!oneRowWithLink && txtViewHolder.getTxtChatReceiver().getMeasuredWidth() < (SCREEN_WIDTH * 70) / 100 && txtViewHolder.getTxtChatReceiver().getLineCount() == 1 && TextUtils.isEmpty(item.getReplyTo()))
txtViewHolder.getReceiverTimeLayout().measure(FrameLayout.LayoutParams.WRAP_CONTENT, FrameLayout.LayoutParams.WRAP_CONTENT);
txtViewHolder.getImgReceivedStar().measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
if (defaultViewRecTimeWidth == -1)
defaultViewRecTimeWidth = txtViewHolder.getReceiverTimeLayout().getMeasuredWidth();
//set time layout new parameters
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT, FrameLayout.LayoutParams.WRAP_CONTENT);
params.gravity = Gravity.BOTTOM | Gravity.END;
params.topMargin = isHighResolutionHeight ? 40 : 25;
txtViewHolder.getReceiverTimeLayout().setLayoutParams(params);
//set new width to txt view(because time layout go up..)
int fixedWidth = (item.getFavourite() != null && item.getFavourite()) ? txtViewHolder.getReceiverTimeLayout().getMeasuredWidth() : defaultViewRecTimeWidth - 10;
LinearLayout.LayoutParams params1 = new LinearLayout.LayoutParams(txtViewHolder.getTxtChatReceiver().getMeasuredWidth() + fixedWidth,
LinearLayout.LayoutParams.WRAP_CONTENT);
txtViewHolder.getTxtChatReceiver().setLayoutParams(params1);
// if one row, set always in left
txtViewHolder.getTxtChatReceiver().setGravity(Gravity.LEFT);
//reduce margin bottom to txt view(because space..)
FrameLayout.LayoutParams params2 = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT,
FrameLayout.LayoutParams.WRAP_CONTENT);
params2.bottomMargin = isHighResolutionHeight ? -60 : -30;
txtViewHolder.getViewReceiveLayout().setLayoutParams(params2);
// need this code because it is view holder that reuse layouts
else
//return time layout to basic parameters
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT, FrameLayout.LayoutParams.WRAP_CONTENT);
params.gravity = Gravity.BOTTOM | Gravity.END;
txtViewHolder.getReceiverTimeLayout().setLayoutParams(params);
//return chat text view to basic parameters
LinearLayout.LayoutParams params1 = new LinearLayout.LayoutParams(TextUtils.isEmpty(item.getReplyTo()) ? LinearLayout.LayoutParams.WRAP_CONTENT :
LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
txtViewHolder.getTxtChatReceiver().setLayoutParams(params1);
// check if is trl language
if (checkRtl(txtViewHolder.getTxtChatReceiver().getText().toString()))
txtViewHolder.getTxtChatReceiver().setGravity(Gravity.RIGHT);
else
txtViewHolder.getTxtChatReceiver().setGravity(Gravity.LEFT);
//return view receive to basic parameters
FrameLayout.LayoutParams params2 = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT,
FrameLayout.LayoutParams.WRAP_CONTENT);
txtViewHolder.getViewReceiveLayout().setLayoutParams(params2);
我发现可能帮助我找到解决方案的线索是以下行 -
Linkify.addLinks(txtViewHolder.getTxtChatReceiver(), Linkify.WEB_URLS | Linkify.EMAIL_ADDRESSES | Linkify.PHONE_NUMBERS);
作为接收者,我在这条线上得到了正确的结果,而作为发送者,我得到了错误的结果——这意味着它不能将我的字符串作为 URL。
我在这里缺少什么吗?
【问题讨论】:
【参考方案1】:已修复 - 我两次致电 getTxtChatReceiver
,作为发送方和接收方
【讨论】:
以上是关于Android Linkify.addLinks() 适用于一个 textview 而不是另一个的主要内容,如果未能解决你的问题,请参考以下文章
使用 Linkify.addLinks 与 Html.fromHtml 结合
Android TextView,Linkify 每种语言的美国电话号码
Android Linkify 电话号码 - 如何指定要链接的号码和不链接的号码