-
-
Save rubenwardy/a503aaaee25f02566dc98654809d55cb to your computer and use it in GitHub Desktop.
License: Apache-2.0
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.example.app | |
import android.content.Context | |
import android.text.Html | |
import android.text.SpannableString | |
import android.text.Spanned | |
import android.text.style.URLSpan | |
import android.text.util.Linkify | |
import android.util.AttributeSet | |
import org.sufficientlysecure.htmltextview.* | |
import java.lang.reflect.Field | |
import java.lang.reflect.Method | |
import android.util.Log | |
import android.view.View | |
// Waiting on https://github.com/PrivacyApps/html-textview/issues/87 | |
// (I'd rather not fork the library, or include it in the project) | |
class MyHtmlTextView @JvmOverloads constructor( | |
context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0 | |
) : HtmlTextView(context, attrs, defStyleAttr) { | |
// Callback | |
var onLinkClicked: ((String) -> Boolean)? = null | |
// | |
// Expose private members and methods :( | |
// | |
companion object { | |
private val clickableTableSpanField: Field = HtmlTextView::class.java.getDeclaredField("clickableTableSpan") | |
private val drawTableLinkSpanField: Field = HtmlTextView::class.java.getDeclaredField("drawTableLinkSpan") | |
private val removeFromHtmlSpaceField: Field = HtmlTextView::class.java.getDeclaredField("removeFromHtmlSpace") | |
private val removeHtmlBottomPaddingMethod: Method = HtmlTextView::class.java.getDeclaredMethod("removeHtmlBottomPadding", CharSequence::class.java) | |
} | |
init { | |
clickableTableSpanField.isAccessible = true | |
drawTableLinkSpanField.isAccessible = true | |
removeFromHtmlSpaceField.isAccessible = true | |
removeHtmlBottomPaddingMethod.isAccessible = true | |
} | |
private val clickableTableSpan | |
get() = clickableTableSpanField.get(this) as ClickableTableSpan? | |
private val drawTableLinkSpan | |
get() = drawTableLinkSpanField.get(this) as DrawTableLinkSpan? | |
private val removeFromHtmlSpace | |
get() = removeFromHtmlSpaceField.get(this) as Boolean | |
private fun removeHtmlBottomPadding(text: CharSequence?): CharSequence? = | |
removeHtmlBottomPaddingMethod.invoke(null, text) as CharSequence? | |
private fun callOverrideTagsMethod(htmlTagHandler: HtmlTagHandler, html: String): String { | |
val overrideTagsMethod = htmlTagHandler::class.java.getDeclaredMethod("overrideTags", String::class.java) | |
overrideTagsMethod.isAccessible = true | |
return overrideTagsMethod.invoke(htmlTagHandler, html) as String | |
} | |
// | |
// Override function | |
// | |
override fun setHtml(html: String, imageGetter: Html.ImageGetter?) { | |
val htmlTagHandler = HtmlTagHandler(paint) | |
htmlTagHandler.setClickableTableSpan(clickableTableSpan) | |
htmlTagHandler.setDrawTableLinkSpan(drawTableLinkSpan) | |
val htmlCorrected = callOverrideTagsMethod(htmlTagHandler, html) | |
val spans = | |
if (removeFromHtmlSpace) { | |
removeHtmlBottomPadding(Html.fromHtml(htmlCorrected, imageGetter, htmlTagHandler)) as Spanned | |
} else { | |
Html.fromHtml(htmlCorrected, imageGetter, htmlTagHandler) | |
} | |
text = addLinkCallbacksToSpanned(spans) | |
// make links work | |
movementMethod = LocalLinkMovementMethod.getInstance() | |
} | |
private fun addLinkCallbacksToSpanned(text: Spanned): Spanned { | |
val buffer = SpannableString(text) | |
Linkify.addLinks(buffer, Linkify.WEB_URLS) | |
val spans = text.getSpans(0, text.length, URLSpan::class.java) as Array<URLSpan> | |
for (us in spans) { | |
val url = us.url | |
val end = text.getSpanEnd(us) //Getting the spans position | |
val start = text.getSpanStart(us) | |
buffer.setSpan(object : URLSpan(us.url) { // A new span with the same URL | |
override fun onClick(widget: View) { | |
if (onLinkClicked?.invoke(url) != true) { | |
super.onClick(widget) | |
} | |
} | |
}, start, end, 0) //Overwriting the old span | |
} | |
return buffer | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment