18
18
19
19
package com.example.compose.snippets.text
20
20
21
- import android.util.Log
21
+ import androidx.compose.foundation.BorderStroke
22
+ import androidx.compose.foundation.background
23
+ import androidx.compose.foundation.basicMarquee
24
+ import androidx.compose.foundation.border
25
+ import androidx.compose.foundation.layout.Arrangement
26
+ import androidx.compose.foundation.layout.Box
22
27
import androidx.compose.foundation.layout.Column
28
+ import androidx.compose.foundation.layout.Row
29
+ import androidx.compose.foundation.layout.fillMaxWidth
23
30
import androidx.compose.foundation.layout.padding
24
31
import androidx.compose.foundation.layout.width
25
- import androidx.compose.foundation.text.ClickableText
26
32
import androidx.compose.foundation.text.KeyboardOptions
27
33
import androidx.compose.foundation.text.selection.DisableSelection
28
34
import androidx.compose.foundation.text.selection.SelectionContainer
29
35
import androidx.compose.material3.LocalTextStyle
36
+ import androidx.compose.material3.MaterialTheme
30
37
import androidx.compose.material3.OutlinedTextField
31
38
import androidx.compose.material3.Text
32
39
import androidx.compose.material3.TextField
@@ -36,6 +43,7 @@ import androidx.compose.runtime.mutableStateOf
36
43
import androidx.compose.runtime.remember
37
44
import androidx.compose.runtime.saveable.rememberSaveable
38
45
import androidx.compose.runtime.setValue
46
+ import androidx.compose.ui.Alignment
39
47
import androidx.compose.ui.Modifier
40
48
import androidx.compose.ui.geometry.Offset
41
49
import androidx.compose.ui.graphics.Brush
@@ -44,7 +52,6 @@ import androidx.compose.ui.graphics.Color.Companion.Cyan
44
52
import androidx.compose.ui.graphics.Shadow
45
53
import androidx.compose.ui.platform.LocalUriHandler
46
54
import androidx.compose.ui.res.stringResource
47
- import androidx.compose.ui.text.AnnotatedString
48
55
import androidx.compose.ui.text.LinkAnnotation
49
56
import androidx.compose.ui.text.ParagraphStyle
50
57
import androidx.compose.ui.text.PlatformTextStyle
@@ -58,11 +65,14 @@ import androidx.compose.ui.text.font.FontStyle
58
65
import androidx.compose.ui.text.font.FontWeight
59
66
import androidx.compose.ui.text.input.KeyboardType
60
67
import androidx.compose.ui.text.input.PasswordVisualTransformation
68
+ import androidx.compose.ui.text.style.Hyphens
69
+ import androidx.compose.ui.text.style.LineBreak
61
70
import androidx.compose.ui.text.style.LineHeightStyle
62
71
import androidx.compose.ui.text.style.TextAlign
63
72
import androidx.compose.ui.text.style.TextOverflow
64
73
import androidx.compose.ui.text.withLink
65
74
import androidx.compose.ui.text.withStyle
75
+ import androidx.compose.ui.tooling.preview.Preview
66
76
import androidx.compose.ui.unit.dp
67
77
import androidx.compose.ui.unit.em
68
78
import androidx.compose.ui.unit.sp
@@ -407,54 +417,6 @@ private object TextPartiallySelectableSnippet {
407
417
// [END android_compose_text_partial_selection]
408
418
}
409
419
410
- private object TextClickableSnippet {
411
- // [START android_compose_text_clickable]
412
- @Composable
413
- fun SimpleClickableText () {
414
- ClickableText (text = AnnotatedString (" Click Me" ), onClick = { offset ->
415
- Log .d(" ClickableText" , " $offset -th character is clicked." )
416
- })
417
- }
418
- // [END android_compose_text_clickable]
419
- }
420
-
421
- private object TextClickableAnnotatedSnippet {
422
- // [START android_compose_text_clickable_annotated]
423
- @Composable
424
- fun AnnotatedClickableText () {
425
- val annotatedText = buildAnnotatedString {
426
- append(" Click " )
427
-
428
- // We attach this *URL* annotation to the following content
429
- // until `pop()` is called
430
- pushStringAnnotation(
431
- tag = " URL" , annotation = " https://developer.android.com"
432
- )
433
- withStyle(
434
- style = SpanStyle (
435
- color = Color .Blue , fontWeight = FontWeight .Bold
436
- )
437
- ) {
438
- append(" here" )
439
- }
440
-
441
- pop()
442
- }
443
-
444
- ClickableText (text = annotatedText, onClick = { offset ->
445
- // We check if there is an *URL* annotation attached to the text
446
- // at the clicked position
447
- annotatedText.getStringAnnotations(
448
- tag = " URL" , start = offset, end = offset
449
- ).firstOrNull()?.let { annotation ->
450
- // If yes, we log its value
451
- Log .d(" Clicked URL" , annotation.item)
452
- }
453
- })
454
- }
455
- // [END android_compose_text_clickable_annotated]
456
- }
457
-
458
420
private object TextTextFieldSnippet {
459
421
// [START android_compose_text_textfield_filled]
460
422
@Composable
@@ -625,6 +587,184 @@ fun AnnotatedStringWithListenerSample() {
625
587
}
626
588
// [END android_compose_text_link_2]
627
589
590
+ @Composable
591
+ private fun TextSample (samples : Map <String , @Composable ()- >Unit >) {
592
+ MaterialTheme {
593
+ Box (
594
+ Modifier
595
+ .background(MaterialTheme .colorScheme.background)
596
+ .fillMaxWidth()
597
+ ) {
598
+ Column (
599
+ verticalArrangement = Arrangement .spacedBy(10 .dp),
600
+ modifier = Modifier .padding(10 .dp)
601
+ ) {
602
+ samples.forEach { (title, content) ->
603
+ Row (Modifier .fillMaxWidth()) {
604
+ content()
605
+ Text (
606
+ text = title,
607
+ textAlign = TextAlign .Center ,
608
+ style = MaterialTheme .typography.titleLarge,
609
+ modifier = Modifier
610
+ .fillMaxWidth()
611
+ .align(Alignment .CenterVertically )
612
+ )
613
+ }
614
+ }
615
+ }
616
+ }
617
+ }
618
+ }
619
+
620
+ private const val SAMPLE_LONG_TEXT =
621
+ " Jetpack Compose is Android’s modern toolkit for building native UI. " +
622
+ " It simplifies and accelerates UI development on Android bringing your apps " +
623
+ " to life with less code, powerful tools, and intuitive Kotlin APIs. " +
624
+ " It makes building Android UI faster and easier."
625
+ @Composable
626
+ @Preview
627
+ fun LineBreakSample () {
628
+ // [START android_compose_text_line_break]
629
+ TextSample (
630
+ samples = mapOf (
631
+ " Simple" to {
632
+ Text (
633
+ text = SAMPLE_LONG_TEXT ,
634
+ modifier = Modifier
635
+ .width(130 .dp)
636
+ .border(BorderStroke (1 .dp, Color .Gray )),
637
+ fontSize = 14 .sp,
638
+ style = TextStyle .Default .copy(
639
+ lineBreak = LineBreak .Simple
640
+ )
641
+ )
642
+ },
643
+ " Paragraph" to {
644
+ Text (
645
+ text = SAMPLE_LONG_TEXT ,
646
+ modifier = Modifier
647
+ .width(130 .dp)
648
+ .border(BorderStroke (1 .dp, Color .Gray )),
649
+ fontSize = 14 .sp,
650
+ style = TextStyle .Default .copy(
651
+ lineBreak = LineBreak .Paragraph
652
+ )
653
+ )
654
+ }
655
+ )
656
+ )
657
+ // [END android_compose_text_line_break]
658
+ }
659
+
660
+ @Preview
661
+ @Composable
662
+ fun SmallScreenTextSnippet () {
663
+ // [START android_compose_text_paragraph]
664
+ TextSample (
665
+ samples = mapOf (
666
+ " Balanced" to {
667
+ val smallScreenAdaptedParagraph =
668
+ LineBreak .Paragraph .copy(strategy = LineBreak .Strategy .Balanced )
669
+ Text (
670
+ text = SAMPLE_LONG_TEXT ,
671
+ modifier = Modifier
672
+ .width(200 .dp)
673
+ .border(BorderStroke (1 .dp, Color .Gray )),
674
+ fontSize = 14 .sp,
675
+ style = TextStyle .Default .copy(
676
+ lineBreak = smallScreenAdaptedParagraph
677
+ )
678
+ )
679
+ },
680
+ " Default" to {
681
+ Text (
682
+ text = SAMPLE_LONG_TEXT ,
683
+ modifier = Modifier
684
+ .width(200 .dp)
685
+ .border(BorderStroke (1 .dp, Color .Gray )),
686
+ fontSize = 14 .sp,
687
+ style = TextStyle .Default
688
+ )
689
+ }
690
+ )
691
+ )
692
+ // [END android_compose_text_paragraph]
693
+ }
694
+
695
+ private object CJKTextSnippet {
696
+ @Composable
697
+ fun CJKSample () {
698
+ // [START android_compose_text_cjk]
699
+ val customTitleLineBreak = LineBreak (
700
+ strategy = LineBreak .Strategy .HighQuality ,
701
+ strictness = LineBreak .Strictness .Strict ,
702
+ wordBreak = LineBreak .WordBreak .Phrase
703
+ )
704
+ Text (
705
+ text = " あなたに寄り添う最先端のテクノロジー。" ,
706
+ modifier = Modifier .width(250 .dp),
707
+ fontSize = 14 .sp,
708
+ style = TextStyle .Default .copy(
709
+ lineBreak = customTitleLineBreak
710
+ )
711
+ )
712
+ // [END android_compose_text_cjk]
713
+ }
714
+ }
715
+
716
+ @Preview
717
+ @Composable
718
+ fun HyphenateTextSnippet () {
719
+ // [START android_compose_text_hyphen]
720
+ TextSample (
721
+ samples = mapOf (
722
+ " Hyphens - None" to {
723
+ Text (
724
+ text = SAMPLE_LONG_TEXT ,
725
+ modifier = Modifier
726
+ .width(130 .dp)
727
+ .border(BorderStroke (1 .dp, Color .Gray )),
728
+ fontSize = 14 .sp,
729
+ style = TextStyle .Default .copy(
730
+ lineBreak = LineBreak .Paragraph ,
731
+ hyphens = Hyphens .None
732
+ )
733
+ )
734
+ },
735
+ " Hyphens - Auto" to {
736
+ Text (
737
+ text = SAMPLE_LONG_TEXT ,
738
+ modifier = Modifier
739
+ .width(130 .dp)
740
+ .border(BorderStroke (1 .dp, Color .Gray )),
741
+ fontSize = 14 .sp,
742
+ style = TextStyle .Default .copy(
743
+ lineBreak = LineBreak .Paragraph ,
744
+ hyphens = Hyphens .Auto
745
+ )
746
+ )
747
+ }
748
+ )
749
+ )
750
+ // [END android_compose_text_hyphen]
751
+ }
752
+
753
+ @Preview(showBackground = true )
754
+ // [START android_compose_text_marquee]
755
+ @Composable
756
+ fun BasicMarqueeSample () {
757
+ // Marquee only animates when the content doesn't fit in the max width.
758
+ Column (Modifier .width(400 .dp)) {
759
+ Text (
760
+ " Learn about why it's great to use Jetpack Compose" ,
761
+ modifier = Modifier .basicMarquee(),
762
+ fontSize = 50 .sp
763
+ )
764
+ }
765
+ }
766
+ // [END android_compose_text_marquee]
767
+
628
768
private val firaSansFamily = FontFamily ()
629
769
630
770
val LightBlue = Color (0xFF0066FF )
0 commit comments