use of android.text.style.URLSpan in project SmartMesh_Android by SmartMeshFoundation.
the class CustomLinkMovementMethod method onTouchEvent.
public boolean onTouchEvent(android.widget.TextView widget, android.text.Spannable buffer, android.view.MotionEvent event) {
int action = event.getAction();
if (isChattingLongClick && action == MotionEvent.ACTION_UP) {
// Long time not to enter
isChattingLongClick = false;
return false;
}
if (action == MotionEvent.ACTION_UP) {
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);
URLSpan[] link = buffer.getSpans(off, off, URLSpan.class);
if (link.length != 0) {
String url = link[0].getURL();
if (url.contains("https") || url.contains("http") || url.contains("www")) {
Utils.clickUrl(url, movementContext);
} else if (url.contains("tel")) {
try {
if (!TextUtils.isEmpty(url)) {
Intent intent = new Intent(Intent.ACTION_DIAL, Uri.parse(url));
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
movementContext.startActivity(intent);
}
} catch (Exception e) {
e.printStackTrace();
}
} else if (url.contains("mailto")) {
try {
if (!TextUtils.isEmpty(url)) {
Intent data = new Intent(Intent.ACTION_SENDTO);
data.setData(Uri.parse(url));
movementContext.startActivity(data);
}
} catch (Exception e) {
e.printStackTrace();
}
}
isClickLink = true;
return true;
}
}
return super.onTouchEvent(widget, buffer, event);
}
use of android.text.style.URLSpan in project Tusky by tuskyapp.
the class StatusDetailedViewHolder method setApplication.
private void setApplication(@Nullable Status.Application app) {
if (app != null) {
timestampInfo.append(" • ");
if (app.getWebsite() != null) {
URLSpan span = new CustomURLSpan(app.getWebsite());
SpannableStringBuilder text = new SpannableStringBuilder(app.getName());
text.setSpan(span, 0, app.getName().length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
timestampInfo.append(text);
timestampInfo.setMovementMethod(LinkMovementMethod.getInstance());
} else {
timestampInfo.append(app.getName());
}
}
}
use of android.text.style.URLSpan in project Tusky by tuskyapp.
the class LinkHelper method setClickableText.
/**
* Finds links, mentions, and hashtags in a piece of text and makes them clickable, associating
* them with callbacks to notify when they're clicked.
*
* @param view the returned text will be put in
* @param content containing text with mentions, links, or hashtags
* @param mentions any '@' mentions which are known to be in the content
* @param listener to notify about particular spans that are clicked
*/
public static void setClickableText(TextView view, Spanned content, @Nullable Status.Mention[] mentions, final LinkListener listener) {
SpannableStringBuilder builder = new SpannableStringBuilder(content);
URLSpan[] urlSpans = content.getSpans(0, content.length(), URLSpan.class);
for (URLSpan span : urlSpans) {
int start = builder.getSpanStart(span);
int end = builder.getSpanEnd(span);
int flags = builder.getSpanFlags(span);
CharSequence text = builder.subSequence(start, end);
if (text.charAt(0) == '#') {
final String tag = text.subSequence(1, text.length()).toString();
ClickableSpan newSpan = new ClickableSpan() {
@Override
public void onClick(View widget) {
listener.onViewTag(tag);
}
@Override
public void updateDrawState(TextPaint ds) {
super.updateDrawState(ds);
ds.setUnderlineText(false);
}
};
builder.removeSpan(span);
builder.setSpan(newSpan, start, end, flags);
} else if (text.charAt(0) == '@' && mentions != null && mentions.length > 0) {
String accountUsername = text.subSequence(1, text.length()).toString();
/* There may be multiple matches for users on different instances with the same
* username. If a match has the same domain we know it's for sure the same, but if
* that can't be found then just go with whichever one matched last. */
String id = null;
for (Status.Mention mention : mentions) {
if (mention.getLocalUsername().equalsIgnoreCase(accountUsername)) {
id = mention.getId();
if (mention.getUrl().contains(getDomain(span.getURL()))) {
break;
}
}
}
if (id != null) {
final String accountId = id;
ClickableSpan newSpan = new ClickableSpan() {
@Override
public void onClick(View widget) {
listener.onViewAccount(accountId);
}
@Override
public void updateDrawState(TextPaint ds) {
super.updateDrawState(ds);
ds.setUnderlineText(false);
}
};
builder.removeSpan(span);
builder.setSpan(newSpan, start, end, flags);
} else {
ClickableSpan newSpan = new CustomURLSpan(span.getURL());
builder.removeSpan(span);
builder.setSpan(newSpan, start, end, flags);
}
} else {
ClickableSpan newSpan = new CustomURLSpan(span.getURL());
builder.removeSpan(span);
builder.setSpan(newSpan, start, end, flags);
}
}
view.setText(builder);
view.setLinksClickable(true);
view.setMovementMethod(LinkMovementMethod.getInstance());
}
use of android.text.style.URLSpan in project Sprog-App by PaulKlinger.
the class Bypass method recurseElement.
// The 'numberOfSiblings' parameters refers to the number of siblings within the parent, including
// the 'element' parameter, as in "How many siblings are you?" rather than "How many siblings do
// you have?".
private CharSequence recurseElement(Element element, int indexWithinParent, int numberOfSiblings, ImageGetter imageGetter) {
Type type = element.getType();
boolean isOrderedList = false;
if (type == Type.LIST) {
String flagsStr = element.getAttribute("flags");
if (flagsStr != null) {
int flags = Integer.parseInt(flagsStr);
isOrderedList = (flags & Element.F_LIST_ORDERED) != 0;
if (isOrderedList) {
mOrderedListNumber.put(element, 1);
}
}
}
int size = element.size();
CharSequence[] spans = new CharSequence[size];
for (int i = 0; i < size; i++) {
spans[i] = recurseElement(element.children[i], i, size, imageGetter);
}
// Clean up after we're done
if (isOrderedList) {
mOrderedListNumber.remove(this);
}
CharSequence concat = TextUtils.concat(spans);
SpannableStringBuilder builder = new ReverseSpannableStringBuilder();
// MODIFIED
String text = substituteBackUnderscores(element.getText());
if (element.size() == 0 && element.getParent() != null && element.getParent().getType() != Type.BLOCK_CODE) {
text = text.replace('\n', ' ');
}
// Retrieve the image now so we know whether we're going to have something to display later
// If we don't, then show the alt text instead (if available).
Drawable imageDrawable = null;
if (type == Type.IMAGE && imageGetter != null && !TextUtils.isEmpty(element.getAttribute("link"))) {
imageDrawable = imageGetter.getDrawable(element.getAttribute("link"));
}
switch(type) {
case LIST:
if (element.getParent() != null && element.getParent().getType() == Type.LIST_ITEM) {
builder.append("\n");
}
break;
case LINEBREAK:
builder.append("\n");
break;
case LIST_ITEM:
builder.append(" ");
if (mOrderedListNumber.containsKey(element.getParent())) {
int number = mOrderedListNumber.get(element.getParent());
builder.append(Integer.toString(number) + ".");
mOrderedListNumber.put(element.getParent(), number + 1);
} else {
builder.append(mOptions.mUnorderedListItem);
}
builder.append(" ");
break;
case AUTOLINK:
builder.append(element.getAttribute("link"));
break;
case HRULE:
// This ultimately gets drawn over by the line span, but
// we need something here or the span isn't even drawn.
builder.append("-");
break;
case IMAGE:
// Display alt text (or title text) if there is no image
if (imageDrawable == null) {
String show = element.getAttribute("alt");
if (TextUtils.isEmpty(show)) {
show = element.getAttribute("title");
}
if (!TextUtils.isEmpty(show)) {
show = "[" + show + "]";
builder.append(show);
}
} else {
// Character to be replaced
builder.append("\uFFFC");
}
break;
}
builder.append(text);
builder.append(concat);
// of the last child within the parent.
if (element.getParent() != null || indexWithinParent < (numberOfSiblings - 1)) {
if (type == Type.LIST_ITEM) {
if (element.size() == 0 || !element.children[element.size() - 1].isBlockElement()) {
builder.append("\n");
}
} else if (element.isBlockElement() && type != Type.BLOCK_QUOTE) {
if (type == Type.LIST) {
// If this is a nested list, don't include newlines
if (element.getParent() == null || element.getParent().getType() != Type.LIST_ITEM) {
builder.append("\n");
}
} else if (element.getParent() != null && element.getParent().getType() == Type.LIST_ITEM) {
// List items should never double-space their entries
builder.append("\n");
} else {
builder.append("\n\n");
}
}
}
switch(type) {
case HEADER:
String levelStr = element.getAttribute("level");
int level = Integer.parseInt(levelStr);
setSpan(builder, new RelativeSizeSpan(mOptions.mHeaderSizes[level - 1]));
setSpan(builder, new StyleSpan(Typeface.BOLD));
break;
case LIST:
setBlockSpan(builder, new LeadingMarginSpan.Standard(mListItemIndent));
break;
case EMPHASIS:
setSpan(builder, new StyleSpan(Typeface.ITALIC));
break;
case DOUBLE_EMPHASIS:
setSpan(builder, new StyleSpan(Typeface.BOLD));
break;
case TRIPLE_EMPHASIS:
setSpan(builder, new StyleSpan(Typeface.BOLD_ITALIC));
break;
case BLOCK_CODE:
setSpan(builder, new LeadingMarginSpan.Standard(mCodeBlockIndent));
setSpan(builder, new TypefaceSpan("monospace"));
break;
case CODE_SPAN:
setSpan(builder, new TypefaceSpan("monospace"));
break;
case LINK:
case AUTOLINK:
// MODIFIED
String link = substituteBackUnderscores(element.getAttribute("link"));
// --
if (!TextUtils.isEmpty(link) && Patterns.EMAIL_ADDRESS.matcher(link).matches()) {
link = "mailto:" + link;
}
setSpan(builder, new URLSpan(link));
break;
case BLOCK_QUOTE:
// We add two leading margin spans so that when the order is reversed,
// the QuoteSpan will always be in the same spot.
setBlockSpan(builder, new LeadingMarginSpan.Standard(mBlockQuoteIndent));
setBlockSpan(builder, new QuoteSpan(mOptions.mBlockQuoteColor));
setBlockSpan(builder, new LeadingMarginSpan.Standard(mBlockQuoteIndent));
setBlockSpan(builder, new StyleSpan(Typeface.ITALIC));
break;
case STRIKETHROUGH:
setSpan(builder, new StrikethroughSpan());
break;
case HRULE:
setSpan(builder, new HorizontalLineSpan(mOptions.mHruleColor, mHruleSize, mHruleTopBottomPadding));
break;
case IMAGE:
if (imageDrawable != null) {
setSpan(builder, new ImageSpan(imageDrawable));
}
break;
}
return builder;
}
use of android.text.style.URLSpan in project EasyPlayer-RTMP-Android by EasyDSS.
the class AboutActivity method onCreate.
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = DataBindingUtil.setContentView(this, R.layout.activity_about);
setSupportActionBar(binding.toolbar);
binding.title.setText("EasyPlayer RTMP播放器:");
binding.desc.setText("EasyPlayer RTMP是由EasyDarwin开源团队开发 者开发和维护的一个RTMP播放器项目,目前 支持Windows/Android/iOS,视频支持 H.264/H.265/MPEG4/MJPEG,音频支持 G711A/G711U/G726/AAC,支持硬解码,是一套极佳的 RTMP播放组件!项目地址:");
binding.desc.setMovementMethod(LinkMovementMethod.getInstance());
SpannableString spannableString = new SpannableString("https://github.com/EasyDarwin/EasyPlayer");
// 设置下划线文字
spannableString.setSpan(new URLSpan("https://github.com/EasyDarwin/EasyPlayer"), 0, spannableString.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
// 设置文字的前景色
spannableString.setSpan(new ForegroundColorSpan(Color.RED), 0, spannableString.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
binding.desc.append(spannableString);
binding.desc.append("\n您也可以升级到我们的EasyPlayer Pro全功能版 本,支持HTTP/RTSP/RTMP/HLS等多种流媒 体协议!");
spannableString = new SpannableString("戳我");
// 设置下划线文字
spannableString.setSpan(new URLSpan("https://fir.im/EasyPlayerPro"), 0, spannableString.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
// 设置文字的前景色
spannableString.setSpan(new ForegroundColorSpan(Color.RED), 0, spannableString.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
binding.desc.append(spannableString);
binding.desc.append("或者扫描下载:");
binding.imageView.setImageResource(R.drawable.qrcode_pro);
}
Aggregations