Skip to content

Commit

Permalink
feat: add CustomAccessibilityActions for each url
Browse files Browse the repository at this point in the history
  • Loading branch information
ch4rl3x committed Jan 2, 2023
1 parent de9a139 commit 6fcf335
Show file tree
Hide file tree
Showing 3 changed files with 102 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ class MainActivity : ComponentActivity() {
ColorTextBySpan()
ColorTextByFont()
ColorTextWithColorMapping()
MultipleLinks()
}
}
}
Expand All @@ -42,6 +43,11 @@ 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(){
HtmlText(text = "<a href=\"https://github.com/ch4rl3x/HtmlText\">HtmlText</a> by <a href=\"https://github.com/ch4rl3x\">ch4rl3x</a>")
}

@Composable
fun ColorTextBySpan() {
HtmlText(text = "Hello <span style=\"color: #0000FF\">blue</span> world")
Expand Down
2 changes: 1 addition & 1 deletion html-text/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ apply from: '../buildCompose.gradle'

ext {
PUBLISH_GROUP_ID = 'de.charlex.compose'
PUBLISH_VERSION = '1.3.1'
PUBLISH_VERSION = '1.4.0'
PUBLISH_ARTIFACT_ID = 'html-text'
}

Expand Down
122 changes: 95 additions & 27 deletions html-text/src/main/java/de/charlex/compose/HtmlText.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ import android.graphics.Typeface
import android.os.Build.VERSION.SDK_INT
import android.text.Html
import android.text.Spanned
import android.text.style.ForegroundColorSpan
import android.text.style.StrikethroughSpan
import android.text.style.StyleSpan
import android.text.style.URLSpan
import android.text.style.UnderlineSpan
import android.text.style.ForegroundColorSpan
import androidx.annotation.StringRes
import androidx.compose.foundation.gestures.detectTapGestures
import androidx.compose.foundation.text.InlineTextContent
Expand All @@ -23,7 +23,17 @@ import androidx.compose.ui.graphics.Color
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalUriHandler
import androidx.compose.ui.text.*
import androidx.compose.ui.semantics.CustomAccessibilityAction
import androidx.compose.ui.semantics.Role
import androidx.compose.ui.semantics.customActions
import androidx.compose.ui.semantics.onClick
import androidx.compose.ui.semantics.role
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.TextLayoutResult
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.font.FontStyle
import androidx.compose.ui.text.font.FontWeight
Expand Down Expand Up @@ -76,27 +86,10 @@ fun HtmlText(
) {
val context = LocalContext.current
val annotatedString = context.resources.getText(textId).toAnnotatedString(urlSpanStyle, colorMapping)
val clickable = annotatedString.getStringAnnotations(0, annotatedString.length - 1).any { it.tag == "url" }

val uriHandler = LocalUriHandler.current
val layoutResult = remember { mutableStateOf<TextLayoutResult?>(null) }

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)
}
}
}
})
} else Modifier),
text = annotatedString,
HtmlText(
modifier = modifier,
annotatedString = annotatedString,
color = color,
fontSize = fontSize,
fontStyle = fontStyle,
Expand All @@ -110,10 +103,7 @@ fun HtmlText(
softWrap = softWrap,
maxLines = maxLines,
inlineContent = inlineContent,
onTextLayout = {
layoutResult.value = it
onTextLayout(it)
},
onTextLayout = onTextLayout,
style = style
)
}
Expand Down Expand Up @@ -165,11 +155,74 @@ fun HtmlText(
Html.fromHtml(text, Html.FROM_HTML_MODE_LEGACY)
}.toAnnotatedString(urlSpanStyle, colorMapping)

val clickable = annotatedString.getStringAnnotations(0, annotatedString.length - 1).any { it.tag == "url" }
HtmlText(
modifier = modifier,
annotatedString = annotatedString,
color = color,
fontSize = fontSize,
fontStyle = fontStyle,
fontWeight = fontWeight,
fontFamily = fontFamily,
letterSpacing = letterSpacing,
textDecoration = textDecoration,
textAlign = textAlign,
lineHeight = lineHeight,
overflow = overflow,
softWrap = softWrap,
maxLines = maxLines,
inlineContent = inlineContent,
onTextLayout = onTextLayout,
style = style
)
}

/**
* Simple Text composable to show the text with html styling from a String.
* Supported are:
*
* &lt;b>Bold&lt;/b>
*
* &lt;i>Italic&lt;/i>
*
* &lt;u>Underlined&lt;/u>
*
* &lt;strike>Strikethrough&lt;/strike>
*
* &lt;a href="https://google.de">Link&lt;/a>
*
* @see androidx.compose.material.Text
*
*/
@Composable
fun HtmlText(
modifier: Modifier,
annotatedString: AnnotatedString,
color: Color,
fontSize: TextUnit,
fontStyle: FontStyle?,
fontWeight: FontWeight?,
fontFamily: FontFamily?,
letterSpacing: TextUnit,
textDecoration: TextDecoration?,
textAlign: TextAlign?,
lineHeight: TextUnit,
overflow: TextOverflow,
softWrap: Boolean,
maxLines: Int,
inlineContent: Map<String, InlineTextContent>,
onTextLayout: (TextLayoutResult) -> Unit,
style: TextStyle
) {
val clickable =
annotatedString.getStringAnnotations(0, annotatedString.length - 1).any { it.tag == "url" }

val uriHandler = LocalUriHandler.current
val layoutResult = remember { mutableStateOf<TextLayoutResult?>(null) }

val urls = remember(layoutResult, annotatedString) {
annotatedString.getStringAnnotations("url", 0, annotatedString.lastIndex)
}

Text(
modifier = modifier.then(if (clickable) Modifier.pointerInput(Unit) {
detectTapGestures(onTap = { pos ->
Expand All @@ -184,6 +237,21 @@ fun HtmlText(
}
}
})
}.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)
true
}
}
}
} else Modifier),
text = annotatedString,
color = color,
Expand Down

0 comments on commit 6fcf335

Please sign in to comment.