Skip to content

Commit

Permalink
1. I added onUriClick. onUriClick returns url. When onUriClick is nul…
Browse files Browse the repository at this point in the history
…l, the existing code is executed. (uriHandler.openUri(url)) (#12)

2. I added ReturnLink() and ReturnLinks() functions to MainActivity.
  • Loading branch information
ovso authored Sep 7, 2023
1 parent 542842a commit ec92707
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 40 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package de.charlex.compose.htmltext.example

import android.os.Bundle
import android.widget.Toast
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.background
Expand All @@ -10,6 +11,7 @@ import androidx.compose.material.Surface
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.tooling.preview.Preview
import de.charlex.compose.HtmlText
import de.charlex.compose.htmltext.example.ui.theme.HtmlTextTheme
Expand All @@ -27,6 +29,9 @@ class MainActivity : ComponentActivity() {
ColorTextByFont()
ColorTextWithColorMapping()
MultipleLinks()
MultipleLinks()
ReturnLink()
ReturnLinks()
}
}
}
Expand All @@ -39,12 +44,12 @@ fun Greeting() {
}

@Composable
fun StringGreeting(){
fun StringGreeting() {
HtmlText(text = "Hello <b>World</b>. This <i><strike>text</strike>sentence</i> is form<b>att<u>ed</u></b> in simple html. <a href=\"https://github.com/ch4rl3x/HtmlText\">HtmlText</a>")
}

@Composable
fun MultipleLinks(){
fun MultipleLinks() {
HtmlText(text = "<a href=\"https://github.com/ch4rl3x/HtmlText\">HtmlText</a> by <a href=\"https://github.com/ch4rl3x\">ch4rl3x</a>")
}

Expand Down Expand Up @@ -92,4 +97,26 @@ fun DefaultPreview() {
StringGreeting()
}
}
}
}

@Composable
fun ReturnLink() {
val context = LocalContext.current
HtmlText(
text = "Hello <b>World</b>. This <i><strike>text</strike>sentence</i> is form<b>att<u>ed</u></b> in simple html. <a href=\"https://github.com/ch4rl3x/HtmlText\">HtmlText</a>",
onUriClick = {
Toast.makeText(context, it, Toast.LENGTH_SHORT).show()
}
)
}

@Composable
fun ReturnLinks() {
val context = LocalContext.current
HtmlText(
text = "<a href=\"https://github.com/ch4rl3x/HtmlText\">HtmlText</a> by <a href=\"https://github.com/ch4rl3x\">ch4rl3x</a>",
onUriClick = {
Toast.makeText(context, it, Toast.LENGTH_SHORT).show()
}
)
}
95 changes: 58 additions & 37 deletions html-text/src/main/java/de/charlex/compose/HtmlText.kt
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,8 @@ fun HtmlText(
@StringRes textId: Int,
urlSpanStyle: SpanStyle = SpanStyle(
color = MaterialTheme.colors.secondary,
textDecoration = TextDecoration.Underline),
textDecoration = TextDecoration.Underline
),
colorMapping: Map<Color, Color> = emptyMap(),
color: Color = Color.Unspecified,
fontSize: TextUnit = TextUnit.Unspecified,
Expand All @@ -82,7 +83,8 @@ fun HtmlText(
maxLines: Int = Int.MAX_VALUE,
inlineContent: Map<String, InlineTextContent> = mapOf(),
onTextLayout: (TextLayoutResult) -> Unit = {},
style: TextStyle = LocalTextStyle.current
style: TextStyle = LocalTextStyle.current,
onUriClick: ((String) -> Unit)? = null,
) {
val context = LocalContext.current
val annotatedString = context.resources.getText(textId).toAnnotatedString(urlSpanStyle, colorMapping)
Expand All @@ -104,7 +106,8 @@ fun HtmlText(
maxLines = maxLines,
inlineContent = inlineContent,
onTextLayout = onTextLayout,
style = style
style = style,
onUriClick = onUriClick
)
}

Expand All @@ -131,7 +134,8 @@ fun HtmlText(
text: String,
urlSpanStyle: SpanStyle = SpanStyle(
color = MaterialTheme.colors.secondary,
textDecoration = TextDecoration.Underline),
textDecoration = TextDecoration.Underline
),
colorMapping: Map<Color, Color> = emptyMap(),
color: Color = Color.Unspecified,
fontSize: TextUnit = TextUnit.Unspecified,
Expand All @@ -147,9 +151,10 @@ fun HtmlText(
maxLines: Int = Int.MAX_VALUE,
inlineContent: Map<String, InlineTextContent> = mapOf(),
onTextLayout: (TextLayoutResult) -> Unit = {},
style: TextStyle = LocalTextStyle.current
style: TextStyle = LocalTextStyle.current,
onUriClick: ((String) -> Unit)? = null,
) {
val annotatedString = if (SDK_INT <24) {
val annotatedString = if (SDK_INT < 24) {
Html.fromHtml(text)
} else {
Html.fromHtml(text, Html.FROM_HTML_MODE_LEGACY)
Expand All @@ -172,7 +177,8 @@ fun HtmlText(
maxLines = maxLines,
inlineContent = inlineContent,
onTextLayout = onTextLayout,
style = style
style = style,
onUriClick = onUriClick
)
}

Expand Down Expand Up @@ -211,7 +217,8 @@ fun HtmlText(
maxLines: Int = Int.MAX_VALUE,
inlineContent: Map<String, InlineTextContent> = mapOf(),
onTextLayout: (TextLayoutResult) -> Unit = {},
style: TextStyle = LocalTextStyle.current
style: TextStyle = LocalTextStyle.current,
onUriClick: ((String) -> Unit)? = null,
) {
val clickable =
annotatedString.getStringAnnotations(0, annotatedString.length - 1).any { it.tag == "url" }
Expand All @@ -224,35 +231,41 @@ fun HtmlText(
}

Text(
modifier = modifier.then(if (clickable) Modifier.pointerInput(Unit) {
detectTapGestures(onTap = { pos ->
layoutResult.value?.let { layoutResult ->
val position = layoutResult.getOffsetForPosition(pos)
annotatedString.getStringAnnotations(position, position)
.firstOrNull()
?.let { sa ->
if (sa.tag == "url") { // NON-NLS
uriHandler.openUri(sa.item)
modifier = modifier.then(if (clickable) Modifier
.pointerInput(Unit) {
detectTapGestures(onTap = { pos ->
layoutResult.value?.let { layoutResult ->
val position = layoutResult.getOffsetForPosition(pos)
annotatedString
.getStringAnnotations(position, position)
.firstOrNull()
?.let { sa ->
if (sa.tag == "url") { // NON-NLS
val url = sa.item
onUriClick?.let { it(url) } ?: uriHandler.openUri(url)
}
}
}
}
})
}.semantics {
if (urls.size == 1) {
role = Role.Button
onClick("Link (${annotatedString.substring(urls[0].start, urls[0].end)}") {
uriHandler.openUri(urls[0].item)
true
}
} else {
customActions = urls.map {
CustomAccessibilityAction("Link (${annotatedString.substring(it.start, it.end)})") {
uriHandler.openUri(it.item)
}
})
}
.semantics {
if (urls.size == 1) {
role = Role.Button
onClick("Link (${annotatedString.substring(urls[0].start, urls[0].end)}") {
val url = urls[0].item
onUriClick?.let { it(url) } ?: uriHandler.openUri(url)
true
}
} else {
customActions = urls.map {
CustomAccessibilityAction("Link (${annotatedString.substring(it.start, it.end)})") {
val url = it.item
onUriClick?.let { it(url) } ?: uriHandler.openUri(url)
true
}
}
}
}
} else Modifier),
} else Modifier),
text = annotatedString,
color = color,
fontSize = fontSize,
Expand Down Expand Up @@ -280,7 +293,7 @@ fun CharSequence.toAnnotatedString(
color = Color.Blue,
textDecoration = TextDecoration.Underline
),
colorMapping: Map<Color, Color> = emptyMap()
colorMapping: Map<Color, Color> = emptyMap(),
): AnnotatedString {
return if (this is Spanned) {
this.toAnnotatedString(urlSpanStyle, colorMapping)
Expand All @@ -296,7 +309,7 @@ fun Spanned.toAnnotatedString(
color = Color.Blue,
textDecoration = TextDecoration.Underline
),
colorMapping: Map<Color, Color> = emptyMap()
colorMapping: Map<Color, Color> = emptyMap(),
): AnnotatedString {
return buildAnnotatedString {
append(this@toAnnotatedString.toString())
Expand All @@ -314,15 +327,23 @@ fun Spanned.toAnnotatedString(
colorSpans.forEach { colorSpan ->
val start = getSpanStart(colorSpan)
val end = getSpanEnd(colorSpan)
addStyle(SpanStyle(color = colorMapping.getOrElse(Color(colorSpan.foregroundColor)) { Color(colorSpan.foregroundColor) }), start, end)
addStyle(
SpanStyle(color = colorMapping.getOrElse(Color(colorSpan.foregroundColor)) { Color(colorSpan.foregroundColor) }),
start,
end
)
}
styleSpans.forEach { styleSpan ->
val start = getSpanStart(styleSpan)
val end = getSpanEnd(styleSpan)
when (styleSpan.style) {
Typeface.BOLD -> addStyle(SpanStyle(fontWeight = FontWeight.Bold), start, end)
Typeface.ITALIC -> addStyle(SpanStyle(fontStyle = FontStyle.Italic), start, end)
Typeface.BOLD_ITALIC -> addStyle(SpanStyle(fontWeight = FontWeight.Bold, fontStyle = FontStyle.Italic), start, end)
Typeface.BOLD_ITALIC -> addStyle(
SpanStyle(fontWeight = FontWeight.Bold, fontStyle = FontStyle.Italic),
start,
end
)
}
}
underlineSpans.forEach { underlineSpan ->
Expand Down

0 comments on commit ec92707

Please sign in to comment.