{"id":23158,"date":"2022-12-13T19:21:58","date_gmt":"2022-12-13T19:21:58","guid":{"rendered":"https:\/\/mailinvest.blog\/index.php\/2022\/12\/13\/highlighting-text-input-with-jetpack-compose\/"},"modified":"2022-12-13T19:21:58","modified_gmt":"2022-12-13T19:21:58","slug":"highlighting-text-input-with-jetpack-compose","status":"publish","type":"post","link":"https:\/\/mailinvest.blog\/index.php\/2022\/12\/13\/highlighting-text-input-with-jetpack-compose\/","title":{"rendered":"Highlighting Text Input with Jetpack Compose"},"content":{"rendered":"<p> <a href=\"https:\/\/go.fiverr.com\/visit\/?bta=1052423&nci=17043\" Target=\"_Top\"><img loading=\"lazy\" decoding=\"async\" border=\"0\" src=\"https:\/\/fiverr.ck-cdn.com\/tn\/serve\/?cid=40081059\" loading=\"lazy\"  width=\"601\" height=\"201\"><\/a>\n<\/p>\n<div>\n<p>We recently launched a new feature at Buffer, called <a href=\"https:\/\/buffer.com\/ideas\" rel=\"noreferrer nofollow noopener\">Ideas<\/a>. With Ideas, you can store all your best ideas, tweak them until they\u2019re ready, and drop them straight into your Buffer queue. Now that Ideas has launched in our web and mobile apps, we have some time to share some learnings from the development of this feature. In this blog post, we\u2019ll dive into how we added support for URL highlighting to the Ideas Composer on Android, using Jetpack Compose.<\/p>\n<hr\/>\n<p>We started adopting Jetpack Compose into our app in 2021 &#8211; using it as standard to build all our new features, while gradually adopting it into existing parts of our application. We built the whole of the Ideas feature using Jetpack Compose &#8211; so alongside faster feature development and greater predictability within the state of our UI, we had plenty of opportunities to further explore Compose and learn more about how to achieve certain requirements in our app.<\/p>\n<p>Within the Ideas composer, we support dynamic link highlighting. This means that if you type a URL into the text area, then the link will be highlighted &#8211; tapping on this link will then show an \u201cOpen link\u201d pop-up, which will launch the link in the browser when clicked.<\/p>\n<figure class=\"kg-card kg-image-card\"><img decoding=\"async\" src=\"https:\/\/paper-attachments.dropboxusercontent.com\/s_70CDC5BFE3F8A083A9AA9227345C1F454192F224108DA4223901379386BD986B_1670334086472_ezgif-1-1b6718525f.gif\" loading=\"lazy\" class=\"kg-image\" alt=\"\" loading=\"lazy\"\/><\/figure>\n<p>In this blog post, we\u2019re going to focus on the link highlighting implementation and how this can be achieved in Jetpack Compose using the <code>TextField<\/code> composable.<\/p>\n<hr\/>\n<p>For the Ideas composer, we\u2019re utilising the <code>TextField<\/code> composable to support text entry. This composable contains an argument, <code>visualTransformation<\/code>, which is used to apply visual changes to the entered text.<\/p>\n<pre><code>TextField(\n    ...\n    visualTransformation = ...\n)<\/code><\/pre>\n<p>This argument requires a <code>VisualTransformation<\/code> implementation which is used to apply the visual transformation to the entered text. If we look at the source code for this interface, we\u2019ll notice a filter function which takes the content of the TextField and returns a <code>TransformedText<\/code> reference that contains the modified text.<\/p>\n<pre><code>@Immutable\nfun interface VisualTransformation {\n    fun filter(text: AnnotatedString): TransformedText\n}<\/code><\/pre>\n<p>When it comes to this modified text, we are required to provide the implementation that creates a new <code>AnnotatedString<\/code> reference with our applied changes. This changed content then gets bundled in the <code>TransformedText<\/code> type and returned back to the <code>TextField<\/code> for composition.<\/p>\n<p>So that we can define and apply transformations to the content of our <code>TextField<\/code>, we need to start by creating a new implementation of the <code>VisualTransformation<\/code> interface for which we\u2019ll create a new class, <code>UrlTransformation<\/code>. This class will implement the <code>VisualTransformation<\/code> argument, along with taking a single argument in the form of a <code>Color<\/code>. We define this argument so that we can pass a theme color reference to be applied within our logic, as we are going to be outside of composable scope and won\u2019t have access to our composable theme.<\/p>\n<pre><code>class UrlTransformation(\n    val color: Color\n) : VisualTransformation {\n\n}<\/code><\/pre>\n<p>With this class defined, we now need to implement the filter function from the <code>VisualTransformation<\/code> interface. Within this function we\u2019re going to return an instance of the <code>TransformedText<\/code> class &#8211; we can jump into the source code for this class and see that there are two properties required when instantiating this class.<\/p>\n<pre><code>\/**\n * The transformed text with offset offset mapping\n *\/\nclass TransformedText(\n    \/**\n     * The transformed text\n     *\/\n    val text: AnnotatedString,\n\n    \/**\n     * The map used for bidirectional offset mapping from original to transformed text.\n     *\/\n    val offsetMapping: OffsetMapping\n)<\/code><\/pre>\n<p>Both of these arguments are required, so we\u2019re going to need to provide a value for each when instantiating the <code>TransformedText<\/code> class.<\/p>\n<ul>\n<li><strong>text<\/strong> &#8211; this will be the modified version of the text that is provided to the filter function<\/li>\n<li><strong>offsetMapping<\/strong> &#8211; as per the documentation, this is the map used for bidirectional offset mapping from original to transformed text<\/li>\n<\/ul>\n<pre><code>class UrlTransformation(\n    val color: Color\n) : VisualTransformation {\n    override fun filter(text: AnnotatedString): TransformedText {\n        return TransformedText(\n            ...,\n            OffsetMapping.Identity\n        )\n    }\n}<\/code><\/pre>\n<p>For the <code>offsetMapping<\/code> argument, we simply pass the <code>OffsetMapping.Identity<\/code> value &#8211; this is the predefined default value used for the <code>OffsetMapping<\/code> interface, used for when that can be used for the text transformation that does not change the character count. When it comes to the text argument we\u2019ll need to write some logic that will take the current content, apply the highlighting and return it as a new <code>AnnotatedString<\/code> reference to be passed into our <code>TransformedText<\/code> reference. For this logic, we\u2019re going to create a new function, <code>buildAnnotatedStringWithUrlHighlighting<\/code>. This is going to take two arguments &#8211; the text that is to be highlighted, along with the color to be used for the highlighting.<\/p>\n<pre><code>fun buildAnnotatedStringWithUrlHighlighting(\n    text: String, \n    color: Color\n): AnnotatedString {\n    \n}<\/code><\/pre>\n<p>From this function, we need to return an <code>AnnotatedString<\/code> reference, which we\u2019ll create using <code>buildAnnotatedString<\/code>. Within this function, we\u2019ll start by using the append operation to set the textual content of the <code>AnnotatedString<\/code>.<\/p>\n<pre><code>fun buildAnnotatedStringWithUrlHighlighting(\n    text: String, \n    color: Color\n): AnnotatedString {\n    return buildAnnotatedString {\n        append(text)\n    }\n}<\/code><\/pre>\n<p>Next, we\u2019ll need to take the contents of our string and apply highlighting to any URLs that are present. Before we can do this, we need to identify the URLs in the string. URL detection might vary depending on the use case, so to keep things simple let\u2019s write some example code that will find the URLs in a given piece of text. This code will take the given string and filter the URLs, providing a list of URL strings as the result.<\/p>\n<pre><code>text?.split(\"\\\\s+\".toRegex())?.filter { word -&gt;\n    Patterns.WEB_URL.matcher(word).matches()\n}<\/code><\/pre>\n<p>Now that we know what URLs are in the string, we\u2019re going to need to apply highlighting to them. This is going to be in the form of an annotated string style, which is applied using the addStyle operation.<\/p>\n<pre><code>fun addStyle(style: SpanStyle, start: Int, end: Int)<\/code><\/pre>\n<p>When calling this function, we need to pass the <code>SpanStyle<\/code> that we wish to apply, along with the start and end index that this styling should be applied to. We\u2019re going to start by calculating this start and end index \u00a0&#8211; to keep things simple, we\u2019re going to assume there are only unique URLs in our string.<\/p>\n<pre><code>text?.split(\"\\\\s+\".toRegex())?.filter { word -&gt;\n    Patterns.WEB_URL.matcher(word).matches()\n}.forEach {\n    val startIndex = text.indexOf(it)\n    val endIndex = startIndex + it.length\n}<\/code><\/pre>\n<p>Here we locate the start index by using the <code>indexOf<\/code> function, which will give us the starting index of the given URL. We\u2019ll then use this start index and the length of the URL to calculate the end index. We can then pass these values to the corresponding arguments for the <code>addStyle<\/code> function.<\/p>\n<pre><code>text?.split(\"\\\\s+\".toRegex())?.filter { word -&gt;\n    Patterns.WEB_URL.matcher(word).matches()\n}.forEach {\n    val startIndex = text.indexOf(it)\n    val endIndex = startIndex + it.length\n    addStyle(\n        start = startIndex, \n        end = endIndex\n    )\n}<\/code><\/pre>\n<p>Next, we need to provide the <code>SpanStyle<\/code> that we want to be applied to the given index range. Here we want to simply highlight the text using the provided color, so we\u2019ll pass the color value from our function arguments as the color argument for the <code>SpanStyle<\/code> function.<\/p>\n<p><!--kg-card-begin: markdown--><\/p>\n<pre><code>text?.split(\"\\\\s+\".toRegex())?.filter { word -&gt;\n    Patterns.WEB_URL.matcher(word).matches()\n}.forEach {\n    val startIndex = text.indexOf(it)\n    val endIndex = startIndex + it.length\n    addStyle(\n        style = SpanStyle(\n            color = color\n        ),\n        start = startIndex, \n        end = endIndex\n    )\n}\n<\/code><\/pre>\n<p><!--kg-card-end: markdown--><\/p>\n<p>With this in place, we now have a complete function that will take the provided text and highlight any URLs using the provided <code>Color<\/code> reference.<\/p>\n<pre><code class=\"language-kotlin\">fun buildAnnotatedStringWithUrlHighlighting(\n    text: String, \n    color: Color\n): AnnotatedString {\n    return buildAnnotatedString {\n        append(text)\n        text?.split(\"\\\\s+\".toRegex())?.filter { word -&gt;\n            Patterns.WEB_URL.matcher(word).matches()\n        }.forEach {\n            val startIndex = text.indexOf(it)\n            val endIndex = startIndex + it.length\n            addStyle(\n                style = SpanStyle(\n                    color = color,\n                    textDecoration = TextDecoration.None\n                ),\n                start = startIndex, end = endIndex\n            )\n        }\n    }\n}<\/code><\/pre>\n<p>We\u2019ll then need to hop back into our <code>UrlTransformation<\/code> class and pass the result of the <code>buildAnnotatedStringWithUrlHighlighting<\/code> function call for the <code>TransformedText<\/code> argument.<\/p>\n<pre><code>class UrlTransformation(\n    val color: Color\n) : VisualTransformation {\n    override fun filter(text: AnnotatedString): TransformedText {\n        return TransformedText(\n            buildAnnotatedStringWithUrlHighlighting(text, color),\n            OffsetMapping.Identity\n        )\n    }\n}<\/code><\/pre>\n<p>Now that our <code>UrlTransformation<\/code> implementation is complete, we can instantiate this and pass the reference for the <code>visualTransformation<\/code> \u00a0argument of the <code>TextField<\/code> composable. Here we are using the desired color from our <code>MaterialTheme<\/code> reference, which will be used when highlighting the URLs in our <code>TextField<\/code> content.<\/p>\n<pre><code>TextField(\n    ...\n    visualTransformation = UrlTransformation(\n        MaterialTheme.colors.secondary)\n)<\/code><\/pre>\n<hr\/>\n<p>With the above in place, we now have dynamic URL highlighting support within our <code>TextField<\/code> composable. This means that now whenever the user inserts a URL into the composer for an Idea, we identify this as a URL by highlighting it using a the secondary color from our theme.<\/p>\n<figure class=\"kg-card kg-image-card\"><img decoding=\"async\" src=\"https:\/\/paper-attachments.dropboxusercontent.com\/s_70CDC5BFE3F8A083A9AA9227345C1F454192F224108DA4223901379386BD986B_1670334086472_ezgif-1-1b6718525f.gif\" loading=\"lazy\" class=\"kg-image\" alt=\"\" loading=\"lazy\" width=\"600\" height=\"259\"\/><\/figure>\n<p>In this post, we\u2019ve learnt how we can apply dynamic URL highlighting to the contents of a <code>TextField<\/code> composable. In the next post, we\u2019ll explore how we added the \u201cOpen link\u201d pop-up when a URL is tapped within the composer input area.<\/p>\n<aside class=\"bf-sharebar\">\n<\/aside><\/div>\n<iframe data-lazy=\"true\" data-src=\"https:\/\/www.fiverr.com\/gig_widgets?id=U2FsdGVkX18x7XQvttUTrv1oEqmGNGTgvvCUiUoJ\/AP4z\/UyMz8lXGOLpu15jIMxBbTR0gmD5uBoFvhC4KWeALQRp3h\/X\/AwcVD0K8Wj9H\/ZzYKzcCNHosB9oS4SCJJFWiN85P9ICAc4OgCoE\/wHKIY7CDkf2\/DQ1vqGvk4smVe5cRDEmrLPCWi4FC8p40VUhSmWQ5udCm0zoJtorgWv3vbDQw0kKYkwn39ozAnQXDe+YvWMxkLFWA+O3TFwkJvdkIK+\/AUSnRssPKt5WHY0FhNOxnSPcLslEL4G4\/RfP95ve99U+kRnDy3X+KtzdQLY+u935ghON\/o3UE4IMv9oN6JX9RnxzL\/LRcOgnHigxStSGPKsZYtnz8RWNVT\/rOLAibqiWJadC5MYHRbekF3eg6FOGrQGkXYbsn0+a5aovnlLCbLwIqY9fcS17UX8J235iQ6cdmHNbrPeS84CMm34RA==&affiliate_id=1052423&strip_google_tagmanager=true\" loading=\"lazy\" data-with-title=\"true\" class=\"fiverr_nga_frame\" frameborder=\"0\" height=\"350\" width=\"100%\" referrerpolicy=\"no-referrer-when-downgrade\" data-mode=\"random_gigs\" onload=\" var frame = this; var script = document.createElement('script'); script.addEventListener('load', function() { window.FW_SDK.register(frame); }); script.setAttribute('src', 'https:\/\/www.fiverr.com\/gig_widgets\/sdk'); document.body.appendChild(script); \" ><\/iframe>\n<br \/><a href=\"https:\/\/buffer.com\/resources\/highlighting-text-input-with-jetpack-compose\/\">Source link <\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>We recently launched a new feature at Buffer, called Ideas. With Ideas, you can store all your best ideas, tweak them until they\u2019re ready, and&#8230;<\/p>\n","protected":false},"author":1,"featured_media":23159,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[7],"tags":[],"class_list":["post-23158","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-tech-universe"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v28.1 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Highlighting Text Input with Jetpack Compose - mailinvest.blog<\/title>\n<meta name=\"description\" content=\"Technology is forever changing, and there are always new pieces of technology to replace obsolete ones. Tons of people enjoy reading tech blogs on a daily basis.mailinvest.blog tracks all the latest consumer technology breakthroughs and shows you what&#039;s new, what matters and how technology can enrich your life. mailinvest.blog also provides the information, tools, and advice that helps when deciding what to buy.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/mailinvest.blog\/index.php\/2022\/12\/13\/highlighting-text-input-with-jetpack-compose\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Highlighting Text Input with Jetpack Compose - mailinvest.blog\" \/>\n<meta property=\"og:description\" content=\"Technology is forever changing, and there are always new pieces of technology to replace obsolete ones. Tons of people enjoy reading tech blogs on a daily basis.mailinvest.blog tracks all the latest consumer technology breakthroughs and shows you what&#039;s new, what matters and how technology can enrich your life. mailinvest.blog also provides the information, tools, and advice that helps when deciding what to buy.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/mailinvest.blog\/index.php\/2022\/12\/13\/highlighting-text-input-with-jetpack-compose\/\" \/>\n<meta property=\"og:site_name\" content=\"mailinvest.blog\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/freelanceracademic\/\" \/>\n<meta property=\"article:published_time\" content=\"2022-12-13T19:21:58+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/mailinvest.blog\/wp-content\/uploads\/2022\/12\/aaron-burden-Hzi7U2SZ2GE-unsplash.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"2000\" \/>\n\t<meta property=\"og:image:height\" content=\"1502\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"admin@mailinvest.blog\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"admin@mailinvest.blog\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"7 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/mailinvest.blog\\\/index.php\\\/2022\\\/12\\\/13\\\/highlighting-text-input-with-jetpack-compose\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/mailinvest.blog\\\/index.php\\\/2022\\\/12\\\/13\\\/highlighting-text-input-with-jetpack-compose\\\/\"},\"author\":{\"name\":\"admin@mailinvest.blog\",\"@id\":\"https:\\\/\\\/mailinvest.blog\\\/#\\\/schema\\\/person\\\/012701c4c204d4e4ebd34f926cfd31a4\"},\"headline\":\"Highlighting Text Input with Jetpack Compose\",\"datePublished\":\"2022-12-13T19:21:58+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/mailinvest.blog\\\/index.php\\\/2022\\\/12\\\/13\\\/highlighting-text-input-with-jetpack-compose\\\/\"},\"wordCount\":1160,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/mailinvest.blog\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/mailinvest.blog\\\/index.php\\\/2022\\\/12\\\/13\\\/highlighting-text-input-with-jetpack-compose\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/mailinvest.blog\\\/wp-content\\\/uploads\\\/2022\\\/12\\\/aaron-burden-Hzi7U2SZ2GE-unsplash.jpg\",\"articleSection\":[\"Tech Universe\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/mailinvest.blog\\\/index.php\\\/2022\\\/12\\\/13\\\/highlighting-text-input-with-jetpack-compose\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/mailinvest.blog\\\/index.php\\\/2022\\\/12\\\/13\\\/highlighting-text-input-with-jetpack-compose\\\/\",\"url\":\"https:\\\/\\\/mailinvest.blog\\\/index.php\\\/2022\\\/12\\\/13\\\/highlighting-text-input-with-jetpack-compose\\\/\",\"name\":\"Highlighting Text Input with Jetpack Compose - mailinvest.blog\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/mailinvest.blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/mailinvest.blog\\\/index.php\\\/2022\\\/12\\\/13\\\/highlighting-text-input-with-jetpack-compose\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/mailinvest.blog\\\/index.php\\\/2022\\\/12\\\/13\\\/highlighting-text-input-with-jetpack-compose\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/mailinvest.blog\\\/wp-content\\\/uploads\\\/2022\\\/12\\\/aaron-burden-Hzi7U2SZ2GE-unsplash.jpg\",\"datePublished\":\"2022-12-13T19:21:58+00:00\",\"description\":\"Technology is forever changing, and there are always new pieces of technology to replace obsolete ones. Tons of people enjoy reading tech blogs on a daily basis.mailinvest.blog tracks all the latest consumer technology breakthroughs and shows you what's new, what matters and how technology can enrich your life. mailinvest.blog also provides the information, tools, and advice that helps when deciding what to buy.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/mailinvest.blog\\\/index.php\\\/2022\\\/12\\\/13\\\/highlighting-text-input-with-jetpack-compose\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/mailinvest.blog\\\/index.php\\\/2022\\\/12\\\/13\\\/highlighting-text-input-with-jetpack-compose\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/mailinvest.blog\\\/index.php\\\/2022\\\/12\\\/13\\\/highlighting-text-input-with-jetpack-compose\\\/#primaryimage\",\"url\":\"https:\\\/\\\/mailinvest.blog\\\/wp-content\\\/uploads\\\/2022\\\/12\\\/aaron-burden-Hzi7U2SZ2GE-unsplash.jpg\",\"contentUrl\":\"https:\\\/\\\/mailinvest.blog\\\/wp-content\\\/uploads\\\/2022\\\/12\\\/aaron-burden-Hzi7U2SZ2GE-unsplash.jpg\",\"width\":2000,\"height\":1502},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/mailinvest.blog\\\/index.php\\\/2022\\\/12\\\/13\\\/highlighting-text-input-with-jetpack-compose\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/mailinvest.blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Highlighting Text Input with Jetpack Compose\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/mailinvest.blog\\\/#website\",\"url\":\"https:\\\/\\\/mailinvest.blog\\\/\",\"name\":\"mailinvest.blog\",\"description\":\"Technology is forever changing, and there are always new pieces of technology to replace obsolete ones. Tons of people enjoy reading tech blogs on a daily basis. mailinvest.blog tracks all the latest consumer technology breakthroughs and shows you what&#039;s new, what matters and how technology can enrich your life. mailinvest.blog also provides the information, tools, and advice that helps when deciding what to buy.\",\"publisher\":{\"@id\":\"https:\\\/\\\/mailinvest.blog\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/mailinvest.blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/mailinvest.blog\\\/#organization\",\"name\":\"mailinvest\",\"url\":\"https:\\\/\\\/mailinvest.blog\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/mailinvest.blog\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/mailinvest.blog\\\/wp-content\\\/uploads\\\/2022\\\/01\\\/default.png\",\"contentUrl\":\"https:\\\/\\\/mailinvest.blog\\\/wp-content\\\/uploads\\\/2022\\\/01\\\/default.png\",\"width\":1000,\"height\":1000,\"caption\":\"mailinvest\"},\"image\":{\"@id\":\"https:\\\/\\\/mailinvest.blog\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/www.facebook.com\\\/freelanceracademic\\\/\"]},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/mailinvest.blog\\\/#\\\/schema\\\/person\\\/012701c4c204d4e4ebd34f926cfd31a4\",\"name\":\"admin@mailinvest.blog\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/98ed217bd0f3d6a6dcae2d9b0c76e305b049a07275e315e1407e19ec8b08e139?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/98ed217bd0f3d6a6dcae2d9b0c76e305b049a07275e315e1407e19ec8b08e139?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/98ed217bd0f3d6a6dcae2d9b0c76e305b049a07275e315e1407e19ec8b08e139?s=96&d=mm&r=g\",\"caption\":\"admin@mailinvest.blog\"},\"sameAs\":[\"https:\\\/\\\/mailinvest.blog\",\"admin@mailinvest.blog\"],\"url\":\"https:\\\/\\\/mailinvest.blog\\\/index.php\\\/author\\\/adminmailinvest-blog\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Highlighting Text Input with Jetpack Compose - mailinvest.blog","description":"Technology is forever changing, and there are always new pieces of technology to replace obsolete ones. Tons of people enjoy reading tech blogs on a daily basis.mailinvest.blog tracks all the latest consumer technology breakthroughs and shows you what's new, what matters and how technology can enrich your life. mailinvest.blog also provides the information, tools, and advice that helps when deciding what to buy.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/mailinvest.blog\/index.php\/2022\/12\/13\/highlighting-text-input-with-jetpack-compose\/","og_locale":"en_US","og_type":"article","og_title":"Highlighting Text Input with Jetpack Compose - mailinvest.blog","og_description":"Technology is forever changing, and there are always new pieces of technology to replace obsolete ones. Tons of people enjoy reading tech blogs on a daily basis.mailinvest.blog tracks all the latest consumer technology breakthroughs and shows you what's new, what matters and how technology can enrich your life. mailinvest.blog also provides the information, tools, and advice that helps when deciding what to buy.","og_url":"https:\/\/mailinvest.blog\/index.php\/2022\/12\/13\/highlighting-text-input-with-jetpack-compose\/","og_site_name":"mailinvest.blog","article_publisher":"https:\/\/www.facebook.com\/freelanceracademic\/","article_published_time":"2022-12-13T19:21:58+00:00","og_image":[{"width":2000,"height":1502,"url":"https:\/\/mailinvest.blog\/wp-content\/uploads\/2022\/12\/aaron-burden-Hzi7U2SZ2GE-unsplash.jpg","type":"image\/jpeg"}],"author":"admin@mailinvest.blog","twitter_card":"summary_large_image","twitter_misc":{"Written by":"admin@mailinvest.blog","Est. reading time":"7 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/mailinvest.blog\/index.php\/2022\/12\/13\/highlighting-text-input-with-jetpack-compose\/#article","isPartOf":{"@id":"https:\/\/mailinvest.blog\/index.php\/2022\/12\/13\/highlighting-text-input-with-jetpack-compose\/"},"author":{"name":"admin@mailinvest.blog","@id":"https:\/\/mailinvest.blog\/#\/schema\/person\/012701c4c204d4e4ebd34f926cfd31a4"},"headline":"Highlighting Text Input with Jetpack Compose","datePublished":"2022-12-13T19:21:58+00:00","mainEntityOfPage":{"@id":"https:\/\/mailinvest.blog\/index.php\/2022\/12\/13\/highlighting-text-input-with-jetpack-compose\/"},"wordCount":1160,"commentCount":0,"publisher":{"@id":"https:\/\/mailinvest.blog\/#organization"},"image":{"@id":"https:\/\/mailinvest.blog\/index.php\/2022\/12\/13\/highlighting-text-input-with-jetpack-compose\/#primaryimage"},"thumbnailUrl":"https:\/\/mailinvest.blog\/wp-content\/uploads\/2022\/12\/aaron-burden-Hzi7U2SZ2GE-unsplash.jpg","articleSection":["Tech Universe"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/mailinvest.blog\/index.php\/2022\/12\/13\/highlighting-text-input-with-jetpack-compose\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/mailinvest.blog\/index.php\/2022\/12\/13\/highlighting-text-input-with-jetpack-compose\/","url":"https:\/\/mailinvest.blog\/index.php\/2022\/12\/13\/highlighting-text-input-with-jetpack-compose\/","name":"Highlighting Text Input with Jetpack Compose - mailinvest.blog","isPartOf":{"@id":"https:\/\/mailinvest.blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/mailinvest.blog\/index.php\/2022\/12\/13\/highlighting-text-input-with-jetpack-compose\/#primaryimage"},"image":{"@id":"https:\/\/mailinvest.blog\/index.php\/2022\/12\/13\/highlighting-text-input-with-jetpack-compose\/#primaryimage"},"thumbnailUrl":"https:\/\/mailinvest.blog\/wp-content\/uploads\/2022\/12\/aaron-burden-Hzi7U2SZ2GE-unsplash.jpg","datePublished":"2022-12-13T19:21:58+00:00","description":"Technology is forever changing, and there are always new pieces of technology to replace obsolete ones. Tons of people enjoy reading tech blogs on a daily basis.mailinvest.blog tracks all the latest consumer technology breakthroughs and shows you what's new, what matters and how technology can enrich your life. mailinvest.blog also provides the information, tools, and advice that helps when deciding what to buy.","breadcrumb":{"@id":"https:\/\/mailinvest.blog\/index.php\/2022\/12\/13\/highlighting-text-input-with-jetpack-compose\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/mailinvest.blog\/index.php\/2022\/12\/13\/highlighting-text-input-with-jetpack-compose\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/mailinvest.blog\/index.php\/2022\/12\/13\/highlighting-text-input-with-jetpack-compose\/#primaryimage","url":"https:\/\/mailinvest.blog\/wp-content\/uploads\/2022\/12\/aaron-burden-Hzi7U2SZ2GE-unsplash.jpg","contentUrl":"https:\/\/mailinvest.blog\/wp-content\/uploads\/2022\/12\/aaron-burden-Hzi7U2SZ2GE-unsplash.jpg","width":2000,"height":1502},{"@type":"BreadcrumbList","@id":"https:\/\/mailinvest.blog\/index.php\/2022\/12\/13\/highlighting-text-input-with-jetpack-compose\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/mailinvest.blog\/"},{"@type":"ListItem","position":2,"name":"Highlighting Text Input with Jetpack Compose"}]},{"@type":"WebSite","@id":"https:\/\/mailinvest.blog\/#website","url":"https:\/\/mailinvest.blog\/","name":"mailinvest.blog","description":"Technology is forever changing, and there are always new pieces of technology to replace obsolete ones. Tons of people enjoy reading tech blogs on a daily basis. mailinvest.blog tracks all the latest consumer technology breakthroughs and shows you what&#039;s new, what matters and how technology can enrich your life. mailinvest.blog also provides the information, tools, and advice that helps when deciding what to buy.","publisher":{"@id":"https:\/\/mailinvest.blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/mailinvest.blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/mailinvest.blog\/#organization","name":"mailinvest","url":"https:\/\/mailinvest.blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/mailinvest.blog\/#\/schema\/logo\/image\/","url":"https:\/\/mailinvest.blog\/wp-content\/uploads\/2022\/01\/default.png","contentUrl":"https:\/\/mailinvest.blog\/wp-content\/uploads\/2022\/01\/default.png","width":1000,"height":1000,"caption":"mailinvest"},"image":{"@id":"https:\/\/mailinvest.blog\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/freelanceracademic\/"]},{"@type":"Person","@id":"https:\/\/mailinvest.blog\/#\/schema\/person\/012701c4c204d4e4ebd34f926cfd31a4","name":"admin@mailinvest.blog","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/98ed217bd0f3d6a6dcae2d9b0c76e305b049a07275e315e1407e19ec8b08e139?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/98ed217bd0f3d6a6dcae2d9b0c76e305b049a07275e315e1407e19ec8b08e139?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/98ed217bd0f3d6a6dcae2d9b0c76e305b049a07275e315e1407e19ec8b08e139?s=96&d=mm&r=g","caption":"admin@mailinvest.blog"},"sameAs":["https:\/\/mailinvest.blog","admin@mailinvest.blog"],"url":"https:\/\/mailinvest.blog\/index.php\/author\/adminmailinvest-blog\/"}]}},"_links":{"self":[{"href":"https:\/\/mailinvest.blog\/index.php\/wp-json\/wp\/v2\/posts\/23158","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/mailinvest.blog\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/mailinvest.blog\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/mailinvest.blog\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/mailinvest.blog\/index.php\/wp-json\/wp\/v2\/comments?post=23158"}],"version-history":[{"count":0,"href":"https:\/\/mailinvest.blog\/index.php\/wp-json\/wp\/v2\/posts\/23158\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/mailinvest.blog\/index.php\/wp-json\/wp\/v2\/media\/23159"}],"wp:attachment":[{"href":"https:\/\/mailinvest.blog\/index.php\/wp-json\/wp\/v2\/media?parent=23158"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mailinvest.blog\/index.php\/wp-json\/wp\/v2\/categories?post=23158"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mailinvest.blog\/index.php\/wp-json\/wp\/v2\/tags?post=23158"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}