<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:base="en">
	<title>Donovan LaDuke - Developer</title>
	<subtitle>Helpful articles and tips for building well architected Android applications</subtitle>
	<link href="https://dladukedev.com/feed/feed.xml" rel="self"/>
	<link href="https://dladukedev.com/"/>
	<updated>2024-10-17T00:00:00Z</updated>
	<id>https://dladukedev.com/</id>
	<author>
		<name>Donovan LaDuke</name>
		<email>dladukedev@gmail.com</email>
	</author>
	
	<entry>
		<title>Reusable Styles in Compose</title>
		<link href="https://dladukedev.com/articles/046_reusable_styles_in_compose/"/>
		<updated>2024-10-17T00:00:00Z</updated>
		<id>https://dladukedev.com/articles/046_reusable_styles_in_compose/</id>
    <summary>Leverage Modifier chains to create reusable styles in Compose</summary>
		<content type="html">&lt;p&gt;Sharing code helps reduce the complexity of making changes in a codebase by ensuring that the code that changes together, stays together. This can be accomplished through classes, functions, or even constants depending on the situation. In Jetpack Compose this is often accomplished by creating reusable composables. Another way to share UI logic is by leveraging shared modifier chains.&lt;/p&gt;
&lt;h3 id=&quot;modifier-chains&quot; tabindex=&quot;-1&quot;&gt;Modifier chains &lt;a class=&quot;header-anchor&quot; href=&quot;https://dladukedev.com/articles/046_reusable_styles_in_compose/&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Due to the way that modifiers are applied we can treat Modifiers as reusable building blocks. A new modifier function can be created by making an extension function off &lt;code&gt;Modifier&lt;/code&gt; that returns a &lt;code&gt;Modifier&lt;/code&gt;. The basic syntax looks like this.&lt;/p&gt;
&lt;pre class=&quot;language-kotlin&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-kotlin&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;fun&lt;/span&gt; Modifier&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;paddedBorder&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Modifier &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;border&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;dp&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; Color&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Black&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;padding&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;dp&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This example creates a reusable &lt;code&gt;Modifier&lt;/code&gt; that applies a padding around the element and a border around that padding. While this example is simple, it illustrates the flexibility of this idea.&lt;/p&gt;
&lt;h3 id=&quot;use-cases&quot; tabindex=&quot;-1&quot;&gt;Use Cases &lt;a class=&quot;header-anchor&quot; href=&quot;https://dladukedev.com/articles/046_reusable_styles_in_compose/&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;This structure can be used to create shared styles that can be reused, remixed, and expanded upon. Additionally, it can create shared styling that can be applied to all kinds of layout components. For example this approach can be used to create a &lt;code&gt;cardStyle()&lt;/code&gt; modifier which would allow adding card styling to any layout composable (e.g. &lt;code&gt;Row&lt;/code&gt;, &lt;code&gt;Column&lt;/code&gt;, etc).&lt;/p&gt;
&lt;pre class=&quot;language-kotlin&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-kotlin&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;fun&lt;/span&gt; Modifier&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;cardStyle&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Modifier &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;val&lt;/span&gt; shape &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;RoundedCornerShape&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;dp&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;shadow&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;dp&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; shape&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;background&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Color&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;White&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;word-of-warning&quot; tabindex=&quot;-1&quot;&gt;Word of Warning &lt;a class=&quot;header-anchor&quot; href=&quot;https://dladukedev.com/articles/046_reusable_styles_in_compose/&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Using modifiers this way can result in tying the codebase in knots if not used carefully, as is often the case with poorly executed styling in CSS. Here is a good list to consider when using this approach.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Avoid creating a deep nested &amp;quot;inheritance&amp;quot; of modifiers that makes them difficult to change/fix&lt;/li&gt;
&lt;li&gt;Use this approach only for truly global &amp;quot;styles&amp;quot; or styles internal to a file/module&lt;/li&gt;
&lt;li&gt;Don&#39;t use this approach for every modifier, the &amp;quot;atomic&amp;quot; nature of modifiers is beneficial for reuse and maintenance&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;conclusion&quot; tabindex=&quot;-1&quot;&gt;Conclusion &lt;a class=&quot;header-anchor&quot; href=&quot;https://dladukedev.com/articles/046_reusable_styles_in_compose/&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;As always, view new approaches as a tool in the toolbox. Leverage this particular tool when a set of modifiers need grouped for a particular reason to improve reusability. Until next time, thanks!&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Hidden Gems of the Kotlin Standard Library - List</title>
		<link href="https://dladukedev.com/articles/045_hidden_gems_kotlin_standard_lib/"/>
		<updated>2024-10-03T00:00:00Z</updated>
		<id>https://dladukedev.com/articles/045_hidden_gems_kotlin_standard_lib/</id>
    <summary>An overview of several hidden gem List Functions in the Kotlin Standard Library</summary>
		<content type="html">&lt;p&gt;One of the greatest things about working in Kotlin is access to the Kotlin Standard Library. This extensive catalogue of types and helper functions assist in writing streamlined and efficient code. All this while not relying on excessive external dependencies or requiring each codebase to reimplement the same functionality over and over again. This is an overview of five hidden gems in the Standard Library.&lt;/p&gt;
&lt;h3 id=&quot;orempty&quot; tabindex=&quot;-1&quot;&gt;orEmpty &lt;a class=&quot;header-anchor&quot; href=&quot;https://dladukedev.com/articles/045_hidden_gems_kotlin_standard_lib/&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Dealing with nullable list can be a pain as calling functions on it requires a null traversal call for each function.&lt;/p&gt;
&lt;pre class=&quot;language-kotlin&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-kotlin&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;printDoubleStrings&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
  strings&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; List&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;String&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  strings
    &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;map&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token string-literal singleline&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;token expression&quot;&gt;it&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt; &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;token expression&quot;&gt;it&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;forEach&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;it&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;By using the &lt;code&gt;orEmpty&lt;/code&gt; function to covert a nullable list to an empty list, that can all be avoided.&lt;/p&gt;
&lt;pre class=&quot;language-kotlin&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-kotlin&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;printDoubleStrings&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
  strings&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; List&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;String&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  strings
    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;orEmpty&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;map&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token string-literal singleline&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;token expression&quot;&gt;it&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt; &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;token expression&quot;&gt;it&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;forEach&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;it&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href=&quot;https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.collections/or-empty.html&quot;&gt;Check out the docs here&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&quot;filterisinstance&quot; tabindex=&quot;-1&quot;&gt;filterIsInstance &lt;a class=&quot;header-anchor&quot; href=&quot;https://dladukedev.com/articles/045_hidden_gems_kotlin_standard_lib/&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;When leveraging a list of items that is of a interface or sealed class type, filtering by the type can be an effective way to work with the list.&lt;/p&gt;
&lt;pre class=&quot;language-kotlin&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-kotlin&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;sealed&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; Result &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;Success&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;val&lt;/span&gt; content&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Float
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;Result&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;Failure&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;val&lt;/span&gt; message&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; String
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;Result&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;logErrors&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;results&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; List&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Result&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;val&lt;/span&gt; failures &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; results&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;filter&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    it &lt;span class=&quot;token keyword&quot;&gt;is&lt;/span&gt; Result&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Failure
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token function&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-literal singleline&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Failure Messages&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  failures&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;forEach&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;it &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; Result&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Failure&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;message
    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This code can be streamlined by using &lt;code&gt;filterIsInstance&lt;/code&gt; to only get objects of a specific type from the list. This also changes the type of the list downstream to the filtered type, removing unnecessary casting and type checking.&lt;/p&gt;
&lt;pre class=&quot;language-kotlin&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-kotlin&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;sealed&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; Result &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;Success&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;val&lt;/span&gt; content&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Float
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;Result&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;Failure&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;val&lt;/span&gt; message&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; String
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;Result&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;logErrors&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;results&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; List&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Result&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;val&lt;/span&gt; failures &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; results
    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;filterIsInstance&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Result&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Failure&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

  &lt;span class=&quot;token function&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-literal singleline&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Failure Messages&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  failures&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;forEach&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;it&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;message&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href=&quot;https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.collections/filter-is-instance.html&quot;&gt;Check out the docs here&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&quot;distictby&quot; tabindex=&quot;-1&quot;&gt;distictBy &lt;a class=&quot;header-anchor&quot; href=&quot;https://dladukedev.com/articles/045_hidden_gems_kotlin_standard_lib/&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;If a list should only have unique elements inside, using &lt;code&gt;distinct&lt;/code&gt; will remove duplicates. But if the logic is not that simple, then the &lt;code&gt;distinctBy&lt;/code&gt; function can be used.&lt;/p&gt;
&lt;pre class=&quot;language-kotlin&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-kotlin&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;Message&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;val&lt;/span&gt; id&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Int&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;val&lt;/span&gt; content&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; String&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;distinctMessages&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
  messages&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; List&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Message&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; List&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Message&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; messages
    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;distinctBy&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; it&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;id &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href=&quot;https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.collections/distinct-by.html&quot;&gt;Check out the docs here&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&quot;chunked&quot; tabindex=&quot;-1&quot;&gt;chunked &lt;a class=&quot;header-anchor&quot; href=&quot;https://dladukedev.com/articles/045_hidden_gems_kotlin_standard_lib/&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;If a list needs broken up into smaller lists of a given size, the &lt;code&gt;chunked&lt;/code&gt; function can be used. This is helpful for creating a paged list if, for example, no more than a certain number of elements should be shown at a given time. As an additional note, if the list is not evenly divisible, the final list will contain the remaining elements.&lt;/p&gt;
&lt;pre class=&quot;language-kotlin&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-kotlin&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;pagedNumbers&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
  range&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; IntRange
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; List&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;List&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Int&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; range
    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toList&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;chunked&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href=&quot;https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.collections/chunked.html&quot;&gt;Check out the docs here&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&quot;random&quot; tabindex=&quot;-1&quot;&gt;random &lt;a class=&quot;header-anchor&quot; href=&quot;https://dladukedev.com/articles/045_hidden_gems_kotlin_standard_lib/&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;This is just a fun helper that selects a random element from the list.&lt;/p&gt;
&lt;pre class=&quot;language-kotlin&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-kotlin&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;greetUser&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;val&lt;/span&gt; greetings &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;listOf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token string-literal singleline&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Hello!&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string-literal singleline&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Hey!&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string-literal singleline&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Hola!&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string-literal singleline&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Salut!&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  
  &lt;span class=&quot;token function&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;greetings&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href=&quot;https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.collections/random.html&quot;&gt;Check out the docs here&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&quot;conclusion&quot; tabindex=&quot;-1&quot;&gt;Conclusion &lt;a class=&quot;header-anchor&quot; href=&quot;https://dladukedev.com/articles/045_hidden_gems_kotlin_standard_lib/&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The Kotlin Standard Library is full of gems like this. Hopefully this has brought inspiration to look for more interesting functionality available through the Standard Library. Until next time, thanks!&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Spacing Concepts in Jetpack Compose - An Overview</title>
		<link href="https://dladukedev.com/articles/044_spacing_concepts_compose/"/>
		<updated>2024-09-19T00:00:00Z</updated>
		<id>https://dladukedev.com/articles/044_spacing_concepts_compose/</id>
    <summary>A short guide to thinking about the concepts of spacing in Jetpack Compose including Spacers, padding, and Arrangement</summary>
		<content type="html">&lt;p&gt;When learning to create a UI in Jetpack Compose, it can become overwhelming to decide how best to create visual spacing in a UI. Spacing can be applied using a &lt;code&gt;Spacer&lt;/code&gt; composable or the &lt;code&gt;padding&lt;/code&gt; modifier or even using &lt;code&gt;Arrangement&lt;/code&gt;. These can all create the same end effect, so how can one choose the &amp;quot;correct&amp;quot; solution? This article will lay out a mental model for choosing the right approach for fixed spacing situations that make the intent clear while improving long term maintainability.&lt;/p&gt;
&lt;h3 id=&quot;creating-a-mental-model-of-space-in-a-ui&quot; tabindex=&quot;-1&quot;&gt;Creating a Mental Model of Space in a UI &lt;a class=&quot;header-anchor&quot; href=&quot;https://dladukedev.com/articles/044_spacing_concepts_compose/&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;When thinking of spacing it is important to consider the relationship between the components. The first relationship components can be in a &amp;quot;Parent-Child&amp;quot; relationship, i.e. one component is nested inside of the other. The other relationship is a &amp;quot;Sibling&amp;quot; relationship, i.e. the components are nested in the same wrapping (Parent) component. Now it is possible to outline approaches for each scenario.&lt;/p&gt;
&lt;h3 id=&quot;parent-child-spacing&quot; tabindex=&quot;-1&quot;&gt;Parent-Child Spacing &lt;a class=&quot;header-anchor&quot; href=&quot;https://dladukedev.com/articles/044_spacing_concepts_compose/&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;In a Parent-Child relationship the most important consideration is who &amp;quot;owns&amp;quot; the spacing. It is best practice to have the parent own the spacing and not the child. This means that if there should be space between the parent and the child, then the modifier should be applied to the parent. In general most spacing between a parent and child are done with the &lt;code&gt;padding&lt;/code&gt; modifier applied to the parent.&lt;/p&gt;
&lt;h3 id=&quot;sibling-spacing&quot; tabindex=&quot;-1&quot;&gt;Sibling Spacing &lt;a class=&quot;header-anchor&quot; href=&quot;https://dladukedev.com/articles/044_spacing_concepts_compose/&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;In a Sibling relationship, there are more valid options for creating spacing as there is not a clear-cut &amp;quot;owner&amp;quot; of the spacing. If the siblings are in a directional layout (i.e. a &lt;code&gt;Column&lt;/code&gt; or &lt;code&gt;Row&lt;/code&gt;) it is appropriate to use &lt;code&gt;Arrangement.spaceBy&lt;/code&gt; and/or &lt;code&gt;Spacer&lt;/code&gt; components. Use &lt;code&gt;Arrangement.spaceBy&lt;/code&gt; on the parent layout if the siblings have equal space between each other. Use a &lt;code&gt;Spacer&lt;/code&gt; composable if the spacing is irregular. &lt;code&gt;Spacer&lt;/code&gt; can also be used in conjunction with &lt;code&gt;Arrangement.spacedBy&lt;/code&gt; as a one-off inside an otherwise uniformly spaced layout.&lt;/p&gt;
&lt;p&gt;When using the &lt;code&gt;Spacer&lt;/code&gt; composable, adding the appropriate &lt;code&gt;height&lt;/code&gt; or &lt;code&gt;width&lt;/code&gt; modifier will create the expected spacing. It can be beneficial to create &lt;code&gt;Spacer&lt;/code&gt; overloads that accept a height or width directly to simplify their use. Compare the existing &lt;code&gt;Spacer(modifier = Modifier.height(8.dp)&lt;/code&gt; with the streamlined &lt;code&gt;Spacer(height = 8.dp)&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Here is this idea in code and can be copied for use in any project.&lt;/p&gt;
&lt;pre class=&quot;language-kotlin&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-kotlin&quot;&gt;&lt;span class=&quot;token annotation builtin&quot;&gt;@Composable&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;Spacer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
  modifier&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Modifier &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Modifier&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  height&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Dp &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;dp&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  width&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Dp &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;dp&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  androidx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;compose&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;foundation&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;layout&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Spacer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    modifier &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; modifier&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;width&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; height&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;touch-targets-and-indicators&quot; tabindex=&quot;-1&quot;&gt;Touch Targets and Indicators &lt;a class=&quot;header-anchor&quot; href=&quot;https://dladukedev.com/articles/044_spacing_concepts_compose/&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;One situation to be aware of where fixed spacing can get more complicated is when interactive elements need touch indicators. A common occurrence of this scenario is a list of elements that &amp;quot;appear&amp;quot; to have padding applied from the parent component. However if the padding is applied in that way, when the list items are clicked, the indicator will stop short of the screen edge. In this case, the end result requires moving the padding from the parent to the child. While this could seem in contradiction with the previous statement on ownership, it is important to consider that the touch indicator is owned by the child. This implies that the additional space does in-fact belong to the child and not the parent.&lt;/p&gt;
&lt;h3 id=&quot;conclusion&quot; tabindex=&quot;-1&quot;&gt;Conclusion &lt;a class=&quot;header-anchor&quot; href=&quot;https://dladukedev.com/articles/044_spacing_concepts_compose/&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Creating readable and consistent layouts in Jetpack Compose can be complex and no approach will be comprehensive. However, this framework makes it easier to think through what spacing approaches to apply and where. The result will be layouts that are more consistent and maintainable. Until next time, thank you!&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Improve Compose UI with Spacing Constants</title>
		<link href="https://dladukedev.com/articles/043_spacing_constants_compose_ui/"/>
		<updated>2024-09-05T00:00:00Z</updated>
		<id>https://dladukedev.com/articles/043_spacing_constants_compose_ui/</id>
    <summary>Create better developer ergonomics and a more cohesive design language by exposing a set of string constants</summary>
		<content type="html">&lt;p&gt;A standard approach to laying out UI is to adhere to an &lt;a href=&quot;https://spec.fm/specifics/8-pt-grid&quot;&gt;8pt grid system&lt;/a&gt;. This system ensures consistency in the look and feel of an application&#39;s UI and a smooth layout on a variety of screen sizes. But perhaps even more importantly, it gives a consistent language to be shared between developers and designers. This can result in better collaboration and less discrepancies between design and implementation. Once the team adopts this mindset, the next step is to set up the project to use this approach. Below is outlined an implementation using Jetpack Compose.&lt;/p&gt;
&lt;h3 id=&quot;approach&quot; tabindex=&quot;-1&quot;&gt;Approach &lt;a class=&quot;header-anchor&quot; href=&quot;https://dladukedev.com/articles/043_spacing_constants_compose_ui/&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The simplest way to implement this approach is to use an enum or sealed class in Kotlin and create new overloads for the assorted spacing modifiers and/or composables (e.g. &lt;code&gt;padding&lt;/code&gt; and &lt;code&gt;Spacer&lt;/code&gt;). Then utilize the new methods instead of the existing methods. Here is a simplified example as an overview of the approach.&lt;/p&gt;
&lt;h3 id=&quot;example&quot; tabindex=&quot;-1&quot;&gt;Example &lt;a class=&quot;header-anchor&quot; href=&quot;https://dladukedev.com/articles/043_spacing_constants_compose_ui/&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;First, set up the sealed class and wrap the underlying dp values so they can be easily accessed.&lt;/p&gt;
&lt;pre class=&quot;language-kotlin&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-kotlin&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;sealed&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;Dimen&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;val&lt;/span&gt; dp&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Dp&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;object&lt;/span&gt; Space0&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;Dimen&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;dp&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;object&lt;/span&gt; Space1&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;Dimen&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;dp&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;object&lt;/span&gt; Space2&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;Dimen&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;dp&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then, create new overloads for the relevant spacing modifiers and/or composables.&lt;/p&gt;
&lt;pre class=&quot;language-kotlin&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-kotlin&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;fun&lt;/span&gt; Modifier&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;padding&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;all&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Dimen&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Modifier 
  &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;padding&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;all &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; all&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;dp&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;PaddingValues&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
  all&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Dimen &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Space0
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; PaddingValues &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;PaddingValues&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;all &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; all&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;dp&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token annotation builtin&quot;&gt;@Composable&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;DimenSpacer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
  height&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Dimen &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Space0&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  width&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Dimen &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Space0&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  modifier&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Modifier &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Modifier&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token function&quot;&gt;Spacer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    modifier &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; modifier&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
      height &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; height&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;dp&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      width &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; width&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;dp&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Finally, replace existing uses of hard-coded spacing values with the new components.&lt;/p&gt;
&lt;pre class=&quot;language-kotlin&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-kotlin&quot;&gt;&lt;span class=&quot;token annotation builtin&quot;&gt;@Composable&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;TestComposable&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
  modifier&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Modifier &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Modifier&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token function&quot;&gt;Row&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;modifier &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; modifier&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;text &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string-literal singleline&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Hello&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; 
    &lt;span class=&quot;token function&quot;&gt;Spacer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;height &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Space1&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
      text &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string-literal singleline&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;World&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      modifier &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Modifier
        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;padding&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;all &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Space2&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That&#39;s all it takes to start adopting a formal set of spacing constants.&lt;/p&gt;
&lt;h3 id=&quot;the-why&quot; tabindex=&quot;-1&quot;&gt;The Why &lt;a class=&quot;header-anchor&quot; href=&quot;https://dladukedev.com/articles/043_spacing_constants_compose_ui/&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The immediate question is why bother? It may seem like a lot of overhead and &lt;code&gt;Modifier.padding(all = 8.dp)&lt;/code&gt; looks pretty similar to &lt;code&gt;Modifier.padding(all = Spacing1)&lt;/code&gt;? The short answer is that the version with a hard-coded constant &lt;code&gt;8.dp&lt;/code&gt; could easily become &lt;code&gt;7.dp&lt;/code&gt; and it wouldn&#39;t stand out. By constraining the valid values there is a pit of success that ensures consistency from both developers and designers. For designers, they get immediate feedback from developers if a value doesn&#39;t conform to the 8-pt grid and any deviation becomes an intentional choice. On the developers side, it becomes obvious in code review if an invalid size is used, ensuring consistent and correct values.&lt;/p&gt;
&lt;h3 id=&quot;conclusion&quot; tabindex=&quot;-1&quot;&gt;Conclusion &lt;a class=&quot;header-anchor&quot; href=&quot;https://dladukedev.com/articles/043_spacing_constants_compose_ui/&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Adopting spacing constants can be a benefit to both the project and the team by creating a consistent language of design. Consider trying this in a project to see how it works and as always tweak as necessary. Until next time, thanks!&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Replace Useless Cases with Interfaces</title>
		<link href="https://dladukedev.com/articles/042_avoid_useless_cases_part_2/"/>
		<updated>2024-08-15T00:00:00Z</updated>
		<id>https://dladukedev.com/articles/042_avoid_useless_cases_part_2/</id>
    <summary>An alternative approach to avoiding Useless Cases by making Use Case interfaces without dedicated Use Case classes</summary>
		<content type="html">&lt;p&gt;A &lt;a href=&quot;https://dladukedev.com/articles/030_avoid_useless_cases&quot;&gt;previous blog post&lt;/a&gt; discussing the value in removing useless cases, encouraged interacting with the repository layer directly instead of creating use case classes that acted as mere pass throughs for the repository layer. This is a great approach, but might not work in all scenarios. For example a team might want to always have a use case either for consistency sake or for separation of concerns. This post offers a different solution to keep the architectural benefits of use cases without the bloat of pass through classes.&lt;/p&gt;
&lt;h3 id=&quot;the-approach&quot; tabindex=&quot;-1&quot;&gt;The Approach &lt;a class=&quot;header-anchor&quot; href=&quot;https://dladukedev.com/articles/042_avoid_useless_cases_part_2/&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The biggest issue with creating pass through use cases, is the existence of a bunch of useless code that does nothing valuable. However, there might be reasons a given project chooses to adopt an &amp;quot;always have a use case&amp;quot; philosophy. What that approach does not imply is that a class must exist for each use case. By leveraging an interface, the use case can be implemented by the repository class instead of a dedicated class. This keeps the architecture while removing the bloat.&lt;/p&gt;
&lt;h3 id=&quot;example&quot; tabindex=&quot;-1&quot;&gt;Example &lt;a class=&quot;header-anchor&quot; href=&quot;https://dladukedev.com/articles/042_avoid_useless_cases_part_2/&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;This example shows a basic implementation of a counter using this pattern.&lt;/p&gt;
&lt;p&gt;First, start with a basic repository.&lt;/p&gt;
&lt;pre class=&quot;language-kotlin&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-kotlin&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; CounterRepository &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;val&lt;/span&gt; _value &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;StateFlow&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;val&lt;/span&gt; value&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Flow&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Int&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; _value

  &lt;span class=&quot;token keyword&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;addOne&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; _value&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;update&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; it &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;subOne&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; _value&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;update&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; it &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then add a set of use case interfaces like this.&lt;/p&gt;
&lt;pre class=&quot;language-kotlin&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-kotlin&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;interface&lt;/span&gt; AddUseCase &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;addOne&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;interface&lt;/span&gt; SubUseCase &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;subOne&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;interface&lt;/span&gt; GetValueUseCase &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; 
    &lt;span class=&quot;token keyword&quot;&gt;val&lt;/span&gt; value&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Flow&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Int&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; 
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now the repository can implement these interfaces.&lt;/p&gt;
&lt;pre class=&quot;language-kotlin&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-kotlin&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; CounterRepository&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; 
  AddUseCase&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 
  SubUseCase&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 
  GetValueUseCase &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;val&lt;/span&gt; value&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Flow&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Int&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;addOne&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;subOne&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Finally, the use cases can be used in the code like usual.&lt;/p&gt;
&lt;pre class=&quot;language-kotlin&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-kotlin&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;CountingViewModel&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;val&lt;/span&gt; addOne&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; AddOneUseCase&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;val&lt;/span&gt; subOne&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; SubUseCase&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;val&lt;/span&gt; getValue&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; GetValueUseCase&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;ViewModel&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token operator&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To complete the work, fulfill the dependencies using the repository for the use cases. This will be dependent on the dependency framework used in the project.&lt;/p&gt;
&lt;h3 id=&quot;aside-leveraging-the-invoke-operator&quot; tabindex=&quot;-1&quot;&gt;Aside: Leveraging the invoke operator &lt;a class=&quot;header-anchor&quot; href=&quot;https://dladukedev.com/articles/042_avoid_useless_cases_part_2/&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;A common pattern with use cases is to expose the invoke operator. With this approach that isn&#39;t possible in the interface due to the overloading of the invoke operator by the repository from multiple use cases. A work around is to add an invoke operator extension on each use case interfaces which avoids both the conflicting function names and the need for the repository to implement the function with the trade-off that now the use case exposes two functions.&lt;/p&gt;
&lt;pre class=&quot;language-kotlin&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-kotlin&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;interface&lt;/span&gt; AddUseCase &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;addOne&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;operator&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;fun&lt;/span&gt; AddUseCase&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;invoke&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; 
    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;addOne&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; 
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;While this approach adds a small layer of pass through, it is a single function that is easily updated if the time comes to add more functionality to the use case.&lt;/p&gt;
&lt;h3 id=&quot;conclusion&quot; tabindex=&quot;-1&quot;&gt;Conclusion &lt;a class=&quot;header-anchor&quot; href=&quot;https://dladukedev.com/articles/042_avoid_useless_cases_part_2/&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;With those small changes, the use cases now serve an architectural purpose without introducing additional unnecessary bloat. To see a more fleshed out example using Hilt, check out &lt;a href=&quot;https://gist.github.com/dladukedev/2cbb9969c275c1c402ef8703c175883d&quot;&gt;this gist&lt;/a&gt;. Until next time, thanks!&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>How to Add an aiexclude File</title>
		<link href="https://dladukedev.com/articles/041_android_studio_ai_ignore/"/>
		<updated>2024-08-01T00:00:00Z</updated>
		<id>https://dladukedev.com/articles/041_android_studio_ai_ignore/</id>
    <summary>Avoid Accidentally Sharing Code with AI for training by using an aiexclude file in Android Studio</summary>
		<content type="html">&lt;p&gt;At Google I/O 2024, Google announced support for a code generation tool powered by their Gemini LLM in Android Studio. While this feature can be a useful tool in some cases, there are likely parts of a code base that shouldn&#39;t be shared with a third party such as business critical or proprietary code. This oversharing can be avoided by adding an &lt;code&gt;.aiexclude&lt;/code&gt; file to your project.&lt;/p&gt;
&lt;h3 id=&quot;formatting-an-aiexclude-file&quot; tabindex=&quot;-1&quot;&gt;Formatting an .aiexclude File &lt;a class=&quot;header-anchor&quot; href=&quot;https://dladukedev.com/articles/041_android_studio_ai_ignore/&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Opting out files from Gemini is as simple as adding an &lt;code&gt;.aiexclude&lt;/code&gt; file in the root of the project or in the specific subfolder that should be excluded. To ignore all file, just leave the file blank or add the single &lt;code&gt;*&lt;/code&gt; selector. If specific files should be matched, the syntax is similar to a &lt;code&gt;.gitignore&lt;/code&gt; file with some notable exceptions. See the &lt;a href=&quot;https://developer.android.com/studio/preview/gemini/aiexclude&quot;&gt;documentation page&lt;/a&gt; for all the specifics. And just like that, the code that should be private won&#39;t be sent to Google.&lt;/p&gt;
&lt;h3 id=&quot;conclusion&quot; tabindex=&quot;-1&quot;&gt;Conclusion &lt;a class=&quot;header-anchor&quot; href=&quot;https://dladukedev.com/articles/041_android_studio_ai_ignore/&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;One quick note as a wrap up, any files covered by the &lt;code&gt;.aiexclude&lt;/code&gt; file will not get Gemini powered autocomplete, so it is a trade-off between privacy and productivity. Now the project team can leverage AI enabled autocomplete if that is desired while protecting the specific code that shouldn&#39;t be shared. Until next time, thanks!&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Cross-Document View Transitions</title>
		<link href="https://dladukedev.com/articles/040_crossdocument_view_transitions/"/>
		<updated>2024-07-18T00:00:00Z</updated>
		<id>https://dladukedev.com/articles/040_crossdocument_view_transitions/</id>
    <summary>Make Multi-Page applications feel more seamless with built in navigation transition animations in the latest version of Chrome as announced at Google I/O</summary>
		<content type="html">&lt;p&gt;Websites with full page reloads can often result in users perceiving a website as slow. This, amongst many other reasons, has driven developers to choose Single Page Application (SPA) frameworks like React, Vue, and Angular. This can be a great choice for many web apps, but other sites would benefit from choosing a traditional multi-page approach. For example this blog is &lt;a href=&quot;https://www.11ty.dev/&quot;&gt;built using 11ty&lt;/a&gt; a JS based static site generator which means each page will show a loading transition between loads. Now however with Cross-Document View Transitions, as shown off at Google I/O this year, the perception of quick, integrated, page loading is possible with multi-page sites.&lt;/p&gt;
&lt;h3 id=&quot;adding-multi-page-application-navigation-transitions&quot; tabindex=&quot;-1&quot;&gt;Adding Multi-Page Application Navigation Transitions &lt;a class=&quot;header-anchor&quot; href=&quot;https://dladukedev.com/articles/040_crossdocument_view_transitions/&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;To add support to a website, add the following snippet CSS block to your CSS file to turn navigation transitions on. Just by adding this block, the website will now perform a subtle fade between screens.&lt;/p&gt;
&lt;pre class=&quot;language-css&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;token atrule&quot;&gt;&lt;span class=&quot;token rule&quot;&gt;@view-transition&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;navigation&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; auto&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Note, a preview version of the API required adding a &lt;code&gt;view-transition&lt;/code&gt; meta tag to your &lt;code&gt;head&lt;/code&gt; block, this is no longer required and is instead replaced with the above CSS solution.&lt;/p&gt;
&lt;h3 id=&quot;adding-multi-page-application-element-transitions&quot; tabindex=&quot;-1&quot;&gt;Adding Multi-Page Application Element Transitions &lt;a class=&quot;header-anchor&quot; href=&quot;https://dladukedev.com/articles/040_crossdocument_view_transitions/&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;If there are shared elements that should animate between pages to show continuity, this can be accomplished with the &lt;code&gt;view-transition-name&lt;/code&gt; CSS property. By applying &lt;code&gt;view-transition-name&lt;/code&gt; to the elements the browser will identify the element as being shared and generate the transition animation. The &lt;code&gt;view-transition-name&lt;/code&gt; needs to be applied to elements on both screens in order for the animation to work, otherwise it will be ignored.&lt;/p&gt;
&lt;pre class=&quot;language-html&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;&amp;lt;!-- Page 1 --&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;a&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;href&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;/page2&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token special-attr&quot;&gt;&lt;span class=&quot;token attr-name&quot;&gt;style&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token value css language-css&quot;&gt;&lt;span class=&quot;token property&quot;&gt;view-transition-name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; page-2-title&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Page 2 Title&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;a&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;&amp;lt;!-- Page 2 --&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;h1&lt;/span&gt; &lt;span class=&quot;token special-attr&quot;&gt;&lt;span class=&quot;token attr-name&quot;&gt;style&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token value css language-css&quot;&gt;&lt;span class=&quot;token property&quot;&gt;view-transition-name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; page-2-title&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Page 2 Title&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;h1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now when a user navigates between &amp;quot;Page 1&amp;quot; and &amp;quot;Page 2&amp;quot; in the above example, the &lt;code&gt;page-2-title&lt;/code&gt; element will animate by moving and resizing to show continuity. This animation works both forward and backwards, so there is no additional work required to support the user pressing the back or forward button.&lt;/p&gt;
&lt;h3 id=&quot;browser-support&quot; tabindex=&quot;-1&quot;&gt;Browser Support &lt;a class=&quot;header-anchor&quot; href=&quot;https://dladukedev.com/articles/040_crossdocument_view_transitions/&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;As of writing this article this feature is only available in Chrome and Microsoft Edge. However, there is no current plans for support in FireFox or Safari so users of those browsers will retain the existing experience. See &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/CSS/@view-transition#browser_compatibility&quot;&gt;this MDN article&lt;/a&gt; for more details and up to date support.&lt;/p&gt;
&lt;h3 id=&quot;quick-notes&quot; tabindex=&quot;-1&quot;&gt;Quick Notes &lt;a class=&quot;header-anchor&quot; href=&quot;https://dladukedev.com/articles/040_crossdocument_view_transitions/&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Progressive Enhancement&lt;/strong&gt; - This feature is a great example of progressive enhancement, giving users of old or non-supporting browsers the existing experience, while giving users of more modern browsers an upgraded experience.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Unique Ids&lt;/strong&gt; - The &lt;code&gt;view-transition-name&lt;/code&gt; variables must be unique per page or the animations will fail to play. This means if there are multiple links in a list/detail view, every element will need a uniquely generated id.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Custom Animations&lt;/strong&gt; - If the default animation is not what is desired, the animations for entering and exiting can be overridden with the &lt;code&gt;::view-transition-new&lt;/code&gt; and &lt;code&gt;::view-transition-old&lt;/code&gt; pseudo-element selectors.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Accessibility Motion Support&lt;/strong&gt; - If the animation played results in a lot of motion, strongly consider using the &lt;code&gt;prefers-reduced-motion&lt;/code&gt; media query to disable the animations.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ensuring Elements Exist&lt;/strong&gt; - If the other page will take a moment to load before rendering, consider adding a blocking render link like this &lt;code&gt;&amp;lt;link rel=&amp;quot;expect&amp;quot; blocking=&amp;quot;render&amp;quot; href=&amp;quot;#my-id&amp;quot;&amp;gt;&lt;/code&gt; to ensure the animation plays smoothly.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cross-Document, Same-Domain&lt;/strong&gt; - While the elements exist on different pages, they must exist in the same domain. So transitions between &lt;code&gt;www.example.com&lt;/code&gt; and &lt;code&gt;www.example.com/page2&lt;/code&gt; will work but not &lt;code&gt;www.example.com&lt;/code&gt; and &lt;code&gt;page2.example.com&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;conclusion&quot; tabindex=&quot;-1&quot;&gt;Conclusion &lt;a class=&quot;header-anchor&quot; href=&quot;https://dladukedev.com/articles/040_crossdocument_view_transitions/&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Want to see this in action? If you navigated to this article from somewhere else on this site and are using Chrome, then the animation probably already played. When navigating between pages, the pages softly fade between one another and the post header information animates seamlessly between lists and posts. Feel free to navigate around to experience the animation and consider adding support for this new enhancement to give users an even better experience while traversing the web. Until next time, thanks!&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Improving Perceived Performance with Delayed Visibility</title>
		<link href="https://dladukedev.com/articles/039_delayed_visibility_modifier/"/>
		<updated>2024-07-04T00:00:00Z</updated>
		<id>https://dladukedev.com/articles/039_delayed_visibility_modifier/</id>
    <summary>Improve percieved performance for users by delaying showing loading elements until needed</summary>
		<content type="html">&lt;p&gt;While improving performance is an important metric, an equally important metric is perceived performance. Users will often care less about how fast a piece of software is as compared to how fast the software feels. While there are many approaches to accomplishing this, the one this article will show is preventing unnecessary loading spinners.&lt;/p&gt;
&lt;h3 id=&quot;delayed-visibility&quot; tabindex=&quot;-1&quot;&gt;Delayed Visibility &lt;a class=&quot;header-anchor&quot; href=&quot;https://dladukedev.com/articles/039_delayed_visibility_modifier/&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;When loading data, the UI is unlikely to know if the data will be loaded from a fast source (like an in-memory cache) or a slow source (like a network request). In this case the naive solution is to just always show a loading indicator. This will work just fine in the &amp;quot;slow source&amp;quot; scenario, but for &amp;quot;fast sources&amp;quot; this will lead to a flickering effect where the indicator is shown briefly before disappearing.&lt;/p&gt;
&lt;p&gt;To avoid this flicker, a brief rendering delay can be added to the loading indicator. By choosing a short delay before rendering (like 100ms), the loading spinner will show quick enough to let the user know a &amp;quot;slow source&amp;quot; is loading, but will hide quick enough that the indicator won&#39;t render for a &amp;quot;fast source&amp;quot;.&lt;/p&gt;
&lt;p&gt;There are likely several ways of accomplishing this, but here is an example inspired by &lt;a href=&quot;https://stackoverflow.com/a/76008048&quot;&gt;this Stack Overflow post on a visibility modifier&lt;/a&gt; and &lt;a href=&quot;https://jetc.dev/slack/2021-06-26-delaying-progress-indicator.html&quot;&gt;this summary on delaying a composable&#39;s visibility&lt;/a&gt;.&lt;/p&gt;
&lt;pre class=&quot;language-kotlin&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-kotlin&quot;&gt;&lt;span class=&quot;token annotation builtin&quot;&gt;@Composable&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;fun&lt;/span&gt; Modifier&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;delayedVisibility&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;delay&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Duration&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Modifier &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; show &lt;span class=&quot;token keyword&quot;&gt;by&lt;/span&gt; remember &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;mutableStateOf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token function&quot;&gt;LaunchedEffect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Unit&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    launch &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token function&quot;&gt;delay&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;delay&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
      show &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; layout &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; measurable&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; constraints &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;val&lt;/span&gt; placeable &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; measurable&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;measure&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;constraints&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;token function&quot;&gt;layout&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;placeable&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;width&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; placeable&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;height&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;show&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        placeable&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;placeRelative&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then in practice, the modifier is used as follows.&lt;/p&gt;
&lt;pre class=&quot;language-kotlin&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-kotlin&quot;&gt;&lt;span class=&quot;token annotation builtin&quot;&gt;@Composable&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;ExampleComposable&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;isLoading&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Boolean&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;isLoading&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;CircularProgressIndicator&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
      modifier &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Modifier&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;delayedVisibility&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
        delay &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;milliseconds&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// TODO Content&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This usage could be further refined by incorporating an &lt;code&gt;AnimatedVisibility&lt;/code&gt; or other animations to improve the transition between states, giving an even more seamless illusion for the end user.&lt;/p&gt;
&lt;h3 id=&quot;conclusion&quot; tabindex=&quot;-1&quot;&gt;Conclusion &lt;a class=&quot;header-anchor&quot; href=&quot;https://dladukedev.com/articles/039_delayed_visibility_modifier/&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;While the best thing to do for users is actually improve performance, that isn&#39;t always feasible and has limits. Improving perceived performance is a great way to smooth over the rough edges that naturally occur when developing apps for mobile devices. Consider using delayed visibility to give users the perception of a faster app experience. Until next time, thanks!&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Using Lists in Compose Previews</title>
		<link href="https://dladukedev.com/articles/038_compose_collectionpreviewparameterprovider/"/>
		<updated>2024-06-20T00:00:00Z</updated>
		<id>https://dladukedev.com/articles/038_compose_collectionpreviewparameterprovider/</id>
    <summary>The Android developer documentation shows how to use a sequence to build multiple Compose Previews, but a List can also be used with the CollectionPreviewParameterProvider</summary>
		<content type="html">&lt;p&gt;When making a Compose component there are scenarios where it is helpful to preview several variations of the component. At the start, just creating separate preview functions for each can work just fine, but as the number of previews grows this becomes unmaintainable. A solution for this is presented in the documentation using &lt;code&gt;PreviewParameterProvider&lt;/code&gt; &lt;a href=&quot;https://developer.android.com/develop/ui/compose/tooling/previews#preview-data&quot;&gt;which can be found here&lt;/a&gt;. This solution works, but using a &lt;code&gt;List&lt;/code&gt; is far more common than using a &lt;code&gt;Sequence&lt;/code&gt;. Thankfully there is a built-in implementation for this that doesn&#39;t require calling &lt;code&gt;asSequence&lt;/code&gt; on the &lt;code&gt;List&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id=&quot;enter-collectionpreviewparameterprovider&quot; tabindex=&quot;-1&quot;&gt;Enter CollectionPreviewParameterProvider &lt;a class=&quot;header-anchor&quot; href=&quot;https://dladukedev.com/articles/038_compose_collectionpreviewparameterprovider/&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The &lt;code&gt;CollectionPreviewParameterProvider&lt;/code&gt; implementation of &lt;code&gt;PreviewParameterProvider&lt;/code&gt; is a class that takes a single parameter of &lt;code&gt;Collection&amp;lt;T&amp;gt;&lt;/code&gt; which is a supertype of &lt;code&gt;List&lt;/code&gt;, this means the list can be passed directly in, no conversion necessary. Then inside the class is converted to a &lt;code&gt;Sequence&lt;/code&gt; without the implementer ever having to think about it. Here is the example from the documentation updated to use a &lt;code&gt;CollectionPreviewParameterProvider&lt;/code&gt;.&lt;/p&gt;
&lt;pre class=&quot;language-kotlin&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-kotlin&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; UserPreviewParameterProvider 
  &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; CollectionPreviewParameterProvider&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;User&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
  collection &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;listOf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;User&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-literal singleline&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Elise&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;User&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-literal singleline&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Frank&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;User&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-literal singleline&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Julia&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token annotation builtin&quot;&gt;@Preview&lt;/span&gt;
&lt;span class=&quot;token annotation builtin&quot;&gt;@Composable&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;UserProfilePreview&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
  &lt;span class=&quot;token annotation builtin&quot;&gt;@PreviewParameter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;UserPreviewParameterProvider&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; 
  user&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; User
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token function&quot;&gt;UserProfile&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;user&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;conclusion&quot; tabindex=&quot;-1&quot;&gt;Conclusion &lt;a class=&quot;header-anchor&quot; href=&quot;https://dladukedev.com/articles/038_compose_collectionpreviewparameterprovider/&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;With this simple change using an existing list of dummy data becomes trivial and will work the same as &lt;code&gt;PreviewParameterProvider&lt;/code&gt; in most cases. To learn more about approaches to previewing composables &lt;a href=&quot;https://dladukedev.com/articles/036_compose_preview_parameter_data&quot;&gt;check out my article here&lt;/a&gt;. Until next time, thanks!&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Dynamic Layouts with ContextualFlowRow and ContextualFlowColumn</title>
		<link href="https://dladukedev.com/articles/037_dynamic_rows_with_contextual_flow_row/"/>
		<updated>2024-06-06T00:00:00Z</updated>
		<id>https://dladukedev.com/articles/037_dynamic_rows_with_contextual_flow_row/</id>
    <summary>Check out ContextualFlowRow and ContextualFlowColumn a new way to layout items in a row or column with a dynamic number of items that accounts for dynamic screen sizes automagically</summary>
		<content type="html">&lt;p&gt;At Google I/O 2024, a new layout component for Compose was announced, the &amp;quot;Contextual Flow Layout&amp;quot;, including both a &lt;code&gt;ContextualFlowRow&lt;/code&gt; and &lt;code&gt;ContextualFlowColumn&lt;/code&gt;. These new components allow for layouts that show a fixed number or rows or columns respectively while filling the allocated space. This has major advantages for creating consistent layouts for dynamic lists without a ton of work, but also makes screens better adapt to large form factor devices like tablets and foldables.&lt;/p&gt;
&lt;h3 id=&quot;a-note-on-flowrow-and-flowcolumn&quot; tabindex=&quot;-1&quot;&gt;A Note on FlowRow and FlowColumn &lt;a class=&quot;header-anchor&quot; href=&quot;https://dladukedev.com/articles/037_dynamic_rows_with_contextual_flow_row/&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;FlowRow&lt;/code&gt; and &lt;code&gt;FlowColumn&lt;/code&gt; also received updates with similar parameters including &lt;code&gt;maxLines&lt;/code&gt; and &lt;code&gt;overflow&lt;/code&gt;, however there are some key differences. For one the contextual layouts provide an index and other scoped values for rendering elements for the content parameter that are not available to the base flow layouts. Additionally, there are stricter requirements around when you access counts in the overflow context. More importantly, unlike the contextual flow layouts, they are not lazy layouts. For this article, the focus will remain on the contextual flow layouts and the examples may not be transferable to use with &lt;code&gt;FlowRow&lt;/code&gt; or &lt;code&gt;FlowColumn&lt;/code&gt; even if the parameters are similar.&lt;/p&gt;
&lt;h3 id=&quot;contextualflowrow-and-contextualflowcolumn&quot; tabindex=&quot;-1&quot;&gt;ContextualFlowRow &amp;amp; ContextualFlowColumn &lt;a class=&quot;header-anchor&quot; href=&quot;https://dladukedev.com/articles/037_dynamic_rows_with_contextual_flow_row/&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The API for &lt;code&gt;ContextualFlowRow&lt;/code&gt; and &lt;code&gt;ContextualFlowColumn&lt;/code&gt; are generally the, same so going forward the examples will show &lt;code&gt;ContextualFlowRow&lt;/code&gt; unless there is something to highlight specifically with &lt;code&gt;ContextualFlowColumn&lt;/code&gt;. To begin, here is a simple usage of a &lt;code&gt;ContextualFlowRow&lt;/code&gt;.&lt;/p&gt;
&lt;pre class=&quot;language-kotlin&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-kotlin&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Values Provided as Example&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;val&lt;/span&gt; items &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; Random&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;nextFloat&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token function&quot;&gt;ContextualFlowRow&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
  itemCount &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; items&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;size&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  maxLines &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  maxItemsInEachRow &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Int&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;MAX_VALUE&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  horizontalArrangement &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Arrangement&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Start&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  verticalArrangement &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Arrangement&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Top&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  overflow &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; ContextualFlowRowOverflow&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Clip&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  modifier &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Modifier&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; index &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;
  &lt;span class=&quot;token function&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;text &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; items&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;index&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toString&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;parameters&quot; tabindex=&quot;-1&quot;&gt;Parameters &lt;a class=&quot;header-anchor&quot; href=&quot;https://dladukedev.com/articles/037_dynamic_rows_with_contextual_flow_row/&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;First is &lt;code&gt;itemCount: Int&lt;/code&gt; which is the only required parameter besides &lt;code&gt;content&lt;/code&gt;. This parameter tells the layout how many items are in the list which allows the component to know if there are more items to layout and enables lazily laying out the elements.&lt;/p&gt;
&lt;p&gt;Next is &lt;code&gt;maxLines: Int&lt;/code&gt; which tells the component how many rows to layout before applying the overflow policy (more on that soon). By default the value is &lt;code&gt;Int.MAX_VALUE&lt;/code&gt; which would effectively mean never apply the overflow policy. This parameter is the same in &lt;code&gt;ContextualFlowColumn&lt;/code&gt; but applies to the number of columns instead of rows. This parameter is unaware of the size of the line and will keep laying out components so long as it has space. If the specific number of elements in a line should be restricted, use the &lt;code&gt;maxItemsInEachRow: Int&lt;/code&gt; to do so. This parameter is defaulted to &lt;code&gt;Int.MAX_VALUE&lt;/code&gt;, which is effectively no limit.&lt;/p&gt;
&lt;p&gt;There are two parameters for arranging components within the Contextual Flow Layout, &lt;code&gt;horizontalArrangement: Arrangement&lt;/code&gt; and &lt;code&gt;verticalArrangement: Arrangement&lt;/code&gt;. These work similar to &lt;code&gt;Column&lt;/code&gt; and &lt;code&gt;Row&lt;/code&gt; arrangement parameters. For both &lt;code&gt;ContextualFlowRow&lt;/code&gt; and &lt;code&gt;ContextualFlowColumn&lt;/code&gt; the default values are &lt;code&gt;Arrangement.Start&lt;/code&gt; for &lt;code&gt;horizontalArrangement&lt;/code&gt; and &lt;code&gt;Arrangement.Top&lt;/code&gt; for &lt;code&gt;verticalArrangement&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The last three parameters are the standard &lt;code&gt;modifier: Modifier&lt;/code&gt; parameter, the &lt;code&gt;overflow: ContextualFlowRowOverflow&lt;/code&gt; which applies an overflow policy (&lt;code&gt;overflow: ContextualFlowColumnOverflow&lt;/code&gt; for &lt;code&gt;ContextualFlowColumn&lt;/code&gt;), and the &lt;code&gt;content: @Composable ContextualFlowRowScope.(index: Int) -&amp;gt; Unit&lt;/code&gt; block (&lt;code&gt;content: @Composable ContextualFlowColumnScope.(index: Int) -&amp;gt; Unit&lt;/code&gt; for &lt;code&gt;ContextualFlowColumn&lt;/code&gt;). The Content Block and Overflow Policy are the bread and butter of the contextual flow layouts and will be covered in their own sections below.&lt;/p&gt;
&lt;h3 id=&quot;content-block&quot; tabindex=&quot;-1&quot;&gt;Content Block &lt;a class=&quot;header-anchor&quot; href=&quot;https://dladukedev.com/articles/037_dynamic_rows_with_contextual_flow_row/&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Contextual flow layouts are lazy layouts so elements not visible are not in the composition. To assist in this, the &lt;code&gt;content&lt;/code&gt; block of the contextual flow layouts provides an &lt;code&gt;index&lt;/code&gt; which can be used to look up the current item and then render a composable for the current item. The content is also in a &lt;code&gt;ContextualFlowRowScope&lt;/code&gt; which gives access to a few more values that can be helpful in more complex layouts.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;maxHeight&lt;/strong&gt; - The maximum vertical space allowed for the element in the given row (&lt;code&gt;maxWidth&lt;/code&gt; in &lt;code&gt;ContextualFlowColumn&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;maxWidthInLine&lt;/strong&gt; - The maximum horizontal space available for the element in the current row (&lt;code&gt;maxHeightInLine&lt;/code&gt; in &lt;code&gt;ContextualFlowColumn&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;lineIndex&lt;/strong&gt; - The index of the line the element is being placed in (e.g. 1 for the second row)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;indexInLine&lt;/strong&gt; - The index of the element in the line (e.g. 3 for the fourth element in the row)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Together, these can be used to create complex and dynamic layouts within the content block. Below is a simple example that displays values in a checkerboard style pattern.&lt;/p&gt;
&lt;pre class=&quot;language-kotlin&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-kotlin&quot;&gt;&lt;span class=&quot;token function&quot;&gt;ContextualFlowRow&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
  itemCount &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;64&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  maxItemsInEachRow &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  modifier &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Modifier&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;padding&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;innerPadding&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; index &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;val&lt;/span&gt; color &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;when&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;lineIndex &lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;indexInLine &lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      Color&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Black 
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; 
      Color&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Red
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;indexInLine &lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      Color&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Red 
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; 
      Color&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Black
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token function&quot;&gt;Box&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;modifier &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Modifier&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;48&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;dp&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;background&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;color&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;text &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; index&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toString&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; color &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Color&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;White&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;overflow-policy&quot; tabindex=&quot;-1&quot;&gt;Overflow Policy &lt;a class=&quot;header-anchor&quot; href=&quot;https://dladukedev.com/articles/037_dynamic_rows_with_contextual_flow_row/&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;There are four overflow policies provided to use and they are &lt;code&gt;Clip&lt;/code&gt;, &lt;code&gt;Visible&lt;/code&gt;, &lt;code&gt;expandIndicator&lt;/code&gt;, and &lt;code&gt;expandOrCollapseIndicator&lt;/code&gt;.&lt;/p&gt;
&lt;h4 id=&quot;clip&quot; tabindex=&quot;-1&quot;&gt;Clip &lt;a class=&quot;header-anchor&quot; href=&quot;https://dladukedev.com/articles/037_dynamic_rows_with_contextual_flow_row/&quot;&gt;#&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;This policy hides all elements that don&#39;t fit within the &lt;code&gt;maxLines&lt;/code&gt;. This is the default setting for &lt;code&gt;ContextualFlowRow&lt;/code&gt; and &lt;code&gt;ContextualFlowColumn&lt;/code&gt;.&lt;/p&gt;
&lt;pre class=&quot;language-kotlin&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-kotlin&quot;&gt;overflow &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; ContextualFlowRowOverflow&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Clip&lt;/code&gt;&lt;/pre&gt;
&lt;h4 id=&quot;visible&quot; tabindex=&quot;-1&quot;&gt;Visible &lt;a class=&quot;header-anchor&quot; href=&quot;https://dladukedev.com/articles/037_dynamic_rows_with_contextual_flow_row/&quot;&gt;#&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;This policy shows all elements, even those that don&#39;t fit within the &lt;code&gt;maxLines&lt;/code&gt;.&lt;/p&gt;
&lt;pre class=&quot;language-kotlin&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-kotlin&quot;&gt;overflow &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; ContextualFlowRowOverflow&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Visible&lt;/code&gt;&lt;/pre&gt;
&lt;h4 id=&quot;expandindicator&quot; tabindex=&quot;-1&quot;&gt;expandIndicator &lt;a class=&quot;header-anchor&quot; href=&quot;https://dladukedev.com/articles/037_dynamic_rows_with_contextual_flow_row/&quot;&gt;#&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;This policy hides all the elements and shows the provided &lt;code&gt;content&lt;/code&gt; if there are hidden elements. This &lt;code&gt;content&lt;/code&gt; block which is provided to the &lt;code&gt;expandIndicator&lt;/code&gt; is in the context of &lt;code&gt;ContextualFlowRowOverflowScope&lt;/code&gt;. This scope provides the &lt;code&gt;shownItemCount&lt;/code&gt; and &lt;code&gt;totalItemCount&lt;/code&gt;. These can be used to provide information to the user about the displayed elements including the number of hidden elements (&lt;code&gt;totalItemCount - shownItemCount&lt;/code&gt;). The &lt;code&gt;content&lt;/code&gt; block is a generic composable so it is up to the consumer to provide appropriate UI and functionality.&lt;/p&gt;
&lt;pre class=&quot;language-kotlin&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-kotlin&quot;&gt;overflow &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; ContextualFlowRowOverflow&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;expandIndicator&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;val&lt;/span&gt; hiddenCount &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; totalItemCount &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; shownItemCount
  &lt;span class=&quot;token function&quot;&gt;Button&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;onClick &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;/* TODO: Show Items */&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;text &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string-literal singleline&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Show &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;token expression&quot;&gt;hiddenCount&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt; Hidden Item(s)&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h4 id=&quot;expandorcollapseindicator&quot; tabindex=&quot;-1&quot;&gt;expandOrCollapseIndicator &lt;a class=&quot;header-anchor&quot; href=&quot;https://dladukedev.com/articles/037_dynamic_rows_with_contextual_flow_row/&quot;&gt;#&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;This policy build upon by the &lt;code&gt;expandIndicator&lt;/code&gt; policy by adding an additional parameter for a collapse indicator that shows when all elements are visible. Like the &lt;code&gt;expandIndicator&lt;/code&gt; policy, both the &lt;code&gt;expandIndicator&lt;/code&gt; and &lt;code&gt;collapseIndicator&lt;/code&gt; parameters are in the &lt;code&gt;ContextualFlowRowOverflowScope&lt;/code&gt;. In addition to the &lt;code&gt;expandIndicator&lt;/code&gt; and &lt;code&gt;collapseIndicator&lt;/code&gt; parameters, this policy also takes a &lt;code&gt;minRowsToShowCollapse&lt;/code&gt; for specifying the minimum visible lines before collapse is shown and &lt;code&gt;minHeightToShowCollapse&lt;/code&gt; for specifying a minimum space available before showing the &lt;code&gt;collapseIndicator&lt;/code&gt; (&lt;code&gt;minColumnsToShowCollapse&lt;/code&gt; and &lt;code&gt;minWidthToShowCollapse&lt;/code&gt; respectively for &lt;code&gt;ContextualFlowColumn&lt;/code&gt;) The intent of this is to allow expanding to show all, and collapsing back to the previous state. Again like the &lt;code&gt;expandIndicator&lt;/code&gt;, the&lt;/p&gt;
&lt;pre class=&quot;language-kotlin&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-kotlin&quot;&gt;overflow &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; ContextualFlowRowOverflow
  &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;expandOrCollapseIndicator&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    expandIndicator &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;val&lt;/span&gt; hiddenCount &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; totalItemCount &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; shownItemCount
      &lt;span class=&quot;token function&quot;&gt;Button&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;onClick &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;/* TODO: Show Items */&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token function&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;text &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string-literal singleline&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Show &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;token expression&quot;&gt;hiddenCount&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt; Hidden Item(s)&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    collapseIndicator &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token function&quot;&gt;Button&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;onClick &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;/* TODO: Show Less */&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token function&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;text &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string-literal singleline&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Show Less&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;conclusion&quot; tabindex=&quot;-1&quot;&gt;Conclusion &lt;a class=&quot;header-anchor&quot; href=&quot;https://dladukedev.com/articles/037_dynamic_rows_with_contextual_flow_row/&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;A demonstration app using the new components can be found &lt;a href=&quot;https://github.com/dladukedev/ContextualFlowLayoutExploration&quot;&gt;here on GitHub&lt;/a&gt; for exploration. Contextual flow layouts open up a whole new set of opportunities for developing dynamic layouts. Until next time, thanks!&lt;/p&gt;
</content>
	</entry>
</feed>
