CINXE.COM
FunkyMuse
<!doctype html><html lang="en" data-mode="dark"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><meta name="theme-color" media="(prefers-color-scheme: light)" content="#f7f7f7"><meta name="theme-color" media="(prefers-color-scheme: dark)" content="#1b1b1e"><meta name="mobile-web-app-capable" content="yes"><meta name="apple-mobile-web-app-status-bar-style" content="black-translucent"><meta name="viewport" content="width=device-width, user-scalable=no initial-scale=1, shrink-to-fit=no, viewport-fit=cover" ><meta name="generator" content="Jekyll v4.4.1" /><meta property="og:title" content="FunkyMuse" /><meta property="og:locale" content="en" /><meta name="description" content="Blog containing Kotlin and Android goodies." /><meta property="og:description" content="Blog containing Kotlin and Android goodies." /><link rel="canonical" href="https://funkymuse.github.io/" /><meta property="og:url" content="https://funkymuse.github.io/" /><meta property="og:site_name" content="FunkyMuse" /><meta property="og:type" content="website" /><link rel="next" href="https://funkymuse.github.io/page2" /><meta name="twitter:card" content="summary" /><meta property="twitter:title" content="FunkyMuse" /><meta name="twitter:site" content="@funky_muse" /> <script type="application/ld+json"> {"@context":"https://schema.org","@type":"WebSite","description":"Blog containing Kotlin and Android goodies.","headline":"FunkyMuse","name":"FunkyMuse","sameAs":["https://twitter.com/funky_muse","https://github.com/FunkyMuse"],"url":"https://funkymuse.github.io/"}</script><title>FunkyMuse</title><link rel="apple-touch-icon" sizes="180x180" href="/assets/img/favicons/apple-touch-icon.png"><link rel="icon" type="image/png" sizes="32x32" href="/assets/img/favicons/favicon-32x32.png"><link rel="icon" type="image/png" sizes="16x16" href="/assets/img/favicons/favicon-16x16.png"><link rel="manifest" href="/assets/img/favicons/site.webmanifest"><link rel="shortcut icon" href="/assets/img/favicons/favicon.ico"><meta name="apple-mobile-web-app-title" content="FunkyMuse"><meta name="application-name" content="FunkyMuse"><meta name="msapplication-TileColor" content="#da532c"><meta name="msapplication-config" content="/assets/img/favicons/browserconfig.xml"><meta name="theme-color" content="#ffffff"><link rel="preconnect" href="https://fonts.googleapis.com" ><link rel="dns-prefetch" href="https://fonts.googleapis.com" ><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin><link rel="dns-prefetch" href="https://fonts.gstatic.com" ><link rel="preconnect" href="https://cdn.jsdelivr.net" ><link rel="dns-prefetch" href="https://cdn.jsdelivr.net" ><link rel="stylesheet" href="/assets/css/jekyll-theme-chirpy.css"><link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Lato:wght@300;400&family=Source+Sans+Pro:wght@400;600;700;900&display=swap"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@6.7.1/css/all.min.css"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/loading-attribute-polyfill@2.1.1/dist/loading-attribute-polyfill.min.css"> <script src="/assets/js/dist/theme.min.js"></script> <script defer src="https://cdn.jsdelivr.net/combine/npm/simple-jekyll-search@1.10.0/dest/simple-jekyll-search.min.js,npm/loading-attribute-polyfill@2.1.1/dist/loading-attribute-polyfill.umd.min.js,npm/dayjs@1.11.13/dayjs.min.js,npm/dayjs@1.11.13/locale/en.js,npm/dayjs@1.11.13/plugin/relativeTime.js,npm/dayjs@1.11.13/plugin/localizedFormat.js"></script> <script defer src="/assets/js/dist/home.min.js"></script> <script defer src="/app.min.js?baseurl=®ister=true" ></script> <script defer src="https://www.googletagmanager.com/gtag/js?id=G-EYK589EJ5E"></script> <script> document.addEventListener('DOMContentLoaded', () => { window.dataLayer = window.dataLayer || []; function gtag() { dataLayer.push(arguments); } gtag('js', new Date()); gtag('config', 'G-EYK589EJ5E'); }); </script><body><aside aria-label="Sidebar" id="sidebar" class="d-flex flex-column align-items-end"><header class="profile-wrapper"> <a href="/" id="avatar" class="rounded-circle"><img src="/assets/img/avatar.jpg" width="112" height="112" alt="avatar" onerror="this.style.display='none'"></a> <a class="site-title d-block" href="/">FunkyMuse</a><p class="site-subtitle fst-italic mb-0">Anything which inspires everything</p></header><nav class="flex-column flex-grow-1 w-100 ps-0"><ul class="nav"><li class="nav-item active"> <a href="/" class="nav-link"> <i class="fa-fw fas fa-home"></i> <span>HOME</span> </a><li class="nav-item"> <a href="/categories/" class="nav-link"> <i class="fa-fw fas fa-stream"></i> <span>CATEGORIES</span> </a><li class="nav-item"> <a href="/tags/" class="nav-link"> <i class="fa-fw fas fa-tags"></i> <span>TAGS</span> </a><li class="nav-item"> <a href="/archives/" class="nav-link"> <i class="fa-fw fas fa-archive"></i> <span>ARCHIVES</span> </a><li class="nav-item"> <a href="/apps/" class="nav-link"> <i class="fa-fw fas fa-mobile"></i> <span>APPLICATIONS</span> </a><li class="nav-item"> <a href="/hire_me/" class="nav-link"> <i class="fa-fw fas fa-code"></i> <span>HIRE ME</span> </a><li class="nav-item"> <a href="/about/" class="nav-link"> <i class="fa-fw fas fa-info"></i> <span>ABOUT</span> </a></ul></nav><div class="sidebar-bottom d-flex flex-wrap align-items-center w-100"> <a href="https://github.com/FunkyMuse" aria-label="github" target="_blank" rel="noopener noreferrer" > <i class="fab fa-github"></i> </a> <a href="https://twitter.com/funky_muse" aria-label="twitter" target="_blank" rel="noopener noreferrer" > <i class="fa-brands fa-x-twitter"></i> </a> <a href="javascript:location.href = 'mailto:' + ['funkymuse','protonmail.com'].join('@')" aria-label="email" > <i class="fas fa-envelope"></i> </a> <a href="/feed.xml" aria-label="rss" > <i class="fas fa-rss"></i> </a></div></aside><div id="main-wrapper" class="d-flex justify-content-center"><div class="container d-flex flex-column px-xxl-5"><header id="topbar-wrapper" aria-label="Top Bar"><div id="topbar" class="d-flex align-items-center justify-content-between px-lg-3 h-100" ><nav id="breadcrumb" aria-label="Breadcrumb"> <span>Home</span></nav><button type="button" id="sidebar-trigger" class="btn btn-link"> <i class="fas fa-bars fa-fw"></i> </button><div id="topbar-title"> FunkyMuse</div><button type="button" id="search-trigger" class="btn btn-link"> <i class="fas fa-search fa-fw"></i> </button> <search id="search" class="align-items-center ms-3 ms-lg-0"> <i class="fas fa-search fa-fw"></i> <input class="form-control" id="search-input" type="search" aria-label="search" autocomplete="off" placeholder="Search..." > </search> <button type="button" class="btn btn-link text-decoration-none" id="search-cancel">Cancel</button></div></header><div class="row flex-grow-1"><main aria-label="Main Content" class="col-12 col-lg-11 col-xl-9 px-md-4"><div id="post-list" class="flex-grow-1 px-xl-1"><article class="card-wrapper card"> <a href="/posts/kmp-type-safe-nav-callback/" class="post-preview row g-0 flex-md-row-reverse"><div class="col-md-12"><div class="card-body d-flex flex-column"><h1 class="card-title my-2 mt-md-0">Achieving Type-safe Navigation Results in AndroidX Compose for KMP</h1><div class="card-text content mt-0 mb-3"><p>The Quest for Perfect Navigation in Compose Multiplatform Navigation in Kotlin Multiplatform (KMP) applications, especially those using Compose Multiplatform, presents an interesting challenge. ...</p></div><div class="post-meta flex-grow-1 d-flex align-items-end"><div class="me-auto"> <i class="far fa-calendar fa-fw me-1"></i> <time data-ts="1731906600" data-df="ll" > Nov 18, 2024 </time> <i class="far fa-folder-open fa-fw me-1"></i> <span class="categories"> Kotlin, KMP, Compose Multiplatform, Navigation </span></div></div></div></div></a></article><article class="card-wrapper card"> <a href="/posts/kmp-room-setup/" class="post-preview row g-0 flex-md-row-reverse"><div class="col-md-12"><div class="card-body d-flex flex-column"><h1 class="card-title my-2 mt-md-0">KMP (Kotlin Multiplatform) AndroidX Room setup and more</h1><div class="card-text content mt-0 mb-3"><p>Intro Kotlin Multiplatform (KMP) enables you to share code across various platforms such as Android, iOS, and JVM. Managing local data consistently across these platforms can be challenging. And...</p></div><div class="post-meta flex-grow-1 d-flex align-items-end"><div class="me-auto"> <i class="far fa-calendar fa-fw me-1"></i> <time data-ts="1726005660" data-df="ll" > Sep 11, 2024 </time> <i class="far fa-folder-open fa-fw me-1"></i> <span class="categories"> Kotlin, KMP </span></div></div></div></div></a></article><article class="card-wrapper card"> <a href="/posts/kmp-multi-module-resources/" class="post-preview row g-0 flex-md-row-reverse"><div class="col-md-12"><div class="card-body d-flex flex-column"><h1 class="card-title my-2 mt-md-0">KMP (Kotlin Multiplatform) multi module resources</h1><div class="card-text content mt-0 mb-3"><p>Intro Every mobile application today ships with static resources like localized strings, images, files, fonts, etc. Resource usage in the KMP (Kotlin Multiplatform) world has been somewhat limi...</p></div><div class="post-meta flex-grow-1 d-flex align-items-end"><div class="me-auto"> <i class="far fa-calendar fa-fw me-1"></i> <time data-ts="1715890800" data-df="ll" > May 16, 2024 </time> <i class="far fa-folder-open fa-fw me-1"></i> <span class="categories"> Kotlin, KMP </span></div></div></div></div></a></article><article class="card-wrapper card"> <a href="/posts/kmp-firebase/" class="post-preview row g-0 flex-md-row-reverse"><div class="col-md-12"><div class="card-body d-flex flex-column"><h1 class="card-title my-2 mt-md-0">KMP (Kotlin Multiplatform) Firebase setup</h1><div class="card-text content mt-0 mb-3"><p>Intro Nearly every mobile application nowadays utilizes Firebase in some capacity, whether it鈥檚 implementing CRUD operations through their NoSQL database, analyzing A/B tests, or detecting crash...</p></div><div class="post-meta flex-grow-1 d-flex align-items-end"><div class="me-auto"> <i class="far fa-calendar fa-fw me-1"></i> <time data-ts="1713435000" data-df="ll" > Apr 18, 2024 </time> <i class="far fa-folder-open fa-fw me-1"></i> <span class="categories"> Kotlin, Android, iOS, KMP, Firebase </span></div></div></div></div></a></article><article class="card-wrapper card"> <a href="/posts/sql-delight-kmp/" class="post-preview row g-0 flex-md-row-reverse"><div class="col-md-12"><div class="card-body d-flex flex-column"><h1 class="card-title my-2 mt-md-0">SQLDelight in Kotlin Multiplatform (KMP)</h1><div class="card-text content mt-0 mb-3"><p>One essential aspect of many applications is persistent data storage and SQLDelight is a popular library for managing database interactions in Kotlin projects. In this blog post, we鈥檒l walk throug...</p></div><div class="post-meta flex-grow-1 d-flex align-items-end"><div class="me-auto"> <i class="far fa-calendar fa-fw me-1"></i> <time data-ts="1707859200" data-df="ll" > Feb 13, 2024 </time> <i class="far fa-folder-open fa-fw me-1"></i> <span class="categories"> KMP, Kotlin, Multiplatform, AndroidX </span></div></div></div></div></a></article><article class="card-wrapper card"> <a href="/posts/create-data-store-kmp/" class="post-preview row g-0 flex-md-row-reverse"><div class="col-md-12"><div class="card-body d-flex flex-column"><h1 class="card-title my-2 mt-md-0">Jetpack Preferences DataStore in Kotlin Multiplatform (KMP)</h1><div class="card-text content mt-0 mb-3"><p>I decided to delve into Kotlin Multiplatform (KMP), and I quickly became hooked. That was a year ago, and I was initially hesitant due to the numerous build.gradle configurations that made my head...</p></div><div class="post-meta flex-grow-1 d-flex align-items-end"><div class="me-auto"> <i class="far fa-calendar fa-fw me-1"></i> <time data-ts="1702736100" data-df="ll" > Dec 16, 2023 </time> <i class="far fa-folder-open fa-fw me-1"></i> <span class="categories"> KMP, Kotlin, Multiplatform, AndroidX </span></div></div></div></div></a></article><article class="card-wrapper card"> <a href="/posts/nav-type-safe/" class="post-preview row g-0 flex-md-row-reverse"><div class="col-md-12"><div class="card-body d-flex flex-column"><h1 class="card-title my-2 mt-md-0">Oh no, another type safe Compose Navigation library for Android</h1><div class="card-text content mt-0 mb-3"><p>Intro We live in a society where another day brings out the most necessary thing for an Android developer, another Navigation library. But this isn鈥檛 one, or it kinda is, but with a twist, a type...</p></div><div class="post-meta flex-grow-1 d-flex align-items-end"><div class="me-auto"> <i class="far fa-calendar fa-fw me-1"></i> <time data-ts="1700695200" data-df="ll" > Nov 23, 2023 </time> <i class="far fa-folder-open fa-fw me-1"></i> <span class="categories"> Compose, Android, Navigation </span></div></div></div></div></a></article><article class="card-wrapper card"> <a href="/posts/nav-abstraction-part-3/" class="post-preview row g-0 flex-md-row-reverse"><div class="col-md-12"><div class="card-body d-flex flex-column"><h1 class="card-title my-2 mt-md-0">Abstract your Android Navigation for Compose, part 3</h1><div class="card-text content mt-0 mb-3"><p>Intro Welcome to the last part of the navigation abstraction in Compose using Google鈥檚 navigation component, in this blog post we鈥檒l actually see the implementation of the abstracted code from Pa...</p></div><div class="post-meta flex-grow-1 d-flex align-items-end"><div class="me-auto"> <i class="far fa-calendar fa-fw me-1"></i> <time data-ts="1684335720" data-df="ll" > May 17, 2023 </time> <i class="far fa-folder-open fa-fw me-1"></i> <span class="categories"> Hilt, Compose, Android, Navigation </span></div></div></div></div></a></article><article class="card-wrapper card"> <a href="/posts/nav-abstraction-part-2/" class="post-preview row g-0 flex-md-row-reverse"><div class="col-md-12"><div class="card-body d-flex flex-column"><h1 class="card-title my-2 mt-md-0">Abstract your Android Navigation for Compose, part 2</h1><div class="card-text content mt-0 mb-3"><p>Intro Welcome to the second part of the navigation abstraction in Compose using Google鈥檚 navigation component, in this blog post we鈥檒l see the abstraction in code. Abstraction In order to unde...</p></div><div class="post-meta flex-grow-1 d-flex align-items-end"><div class="me-auto"> <i class="far fa-calendar fa-fw me-1"></i> <time data-ts="1684335660" data-df="ll" > May 17, 2023 </time> <i class="far fa-folder-open fa-fw me-1"></i> <span class="categories"> Hilt, Compose, Android, Navigation </span></div></div></div></div></a></article><article class="card-wrapper card"> <a href="/posts/nav-abstraction-part-1/" class="post-preview row g-0 flex-md-row-reverse"><div class="col-md-12"><div class="card-body d-flex flex-column"><h1 class="card-title my-2 mt-md-0">Abstract your Android Navigation for Compose, part 1</h1><div class="card-text content mt-0 mb-3"><p>Intro Navigation in Compose is a touchy subject to many, there seems to be a new library about navigation the same way that JS frameworks are born, this article is not about creating a new naviga...</p></div><div class="post-meta flex-grow-1 d-flex align-items-end"><div class="me-auto"> <i class="far fa-calendar fa-fw me-1"></i> <time data-ts="1684335600" data-df="ll" > May 17, 2023 </time> <i class="far fa-folder-open fa-fw me-1"></i> <span class="categories"> Hilt, Compose, Android, Navigation </span></div></div></div></div></a></article></div><nav aria-label="Page Navigation"><ul class="pagination align-items-center mt-4 mb-0"><li class="page-item disabled"> <a class="page-link" href="#" aria-label="previous-page"> <i class="fas fa-angle-left"></i> </a><li class="page-item active"> <a class="page-link" href="/" >1</a><li class="page-item "> <a class="page-link" href="/page2" >2</a><li class="page-item "> <a class="page-link" href="/page3" >3</a><li class="page-item "> <a class="page-link" href="/page4" >4</a><li class="page-index align-middle"> <span>1</span> <span class="text-muted">/ 4</span><li class="page-item "> <a class="page-link" href="/page2" aria-label="next-page"> <i class="fas fa-angle-right"></i> </a></ul></nav></main><aside aria-label="Panel" id="panel-wrapper" class="col-xl-3 ps-2 text-muted"><div class="access"><section id="access-lastmod"><h2 class="panel-heading">Recently Updated</h2><ul class="content list-unstyled ps-0 pb-1 ms-1 mt-2"><li class="text-truncate lh-lg"> <a href="/posts/kmp-type-safe-nav-callback/">Achieving Type-safe Navigation Results in AndroidX Compose for KMP</a><li class="text-truncate lh-lg"> <a href="/posts/kmp-room-setup/">KMP (Kotlin Multiplatform) AndroidX Room setup and more</a><li class="text-truncate lh-lg"> <a href="/posts/kmp-multi-module-resources/">KMP (Kotlin Multiplatform) multi module resources</a><li class="text-truncate lh-lg"> <a href="/posts/kmp-firebase/">KMP (Kotlin Multiplatform) Firebase setup</a><li class="text-truncate lh-lg"> <a href="/posts/dagger-part-2/">Dagger2 is hard, but it can be easy, part 2</a></ul></section><section><h2 class="panel-heading">Trending Tags</h2><div class="d-flex flex-wrap mt-3 mb-1 me-3"> <a class="post-tag btn btn-outline-primary" href="/tags/android/">Android</a> <a class="post-tag btn btn-outline-primary" href="/tags/kotlin/">Kotlin</a> <a class="post-tag btn btn-outline-primary" href="/tags/dagger/">Dagger</a> <a class="post-tag btn btn-outline-primary" href="/tags/hilt/">Hilt</a> <a class="post-tag btn btn-outline-primary" href="/tags/compose/">Compose</a> <a class="post-tag btn btn-outline-primary" href="/tags/kmp/">KMP</a> <a class="post-tag btn btn-outline-primary" href="/tags/navigation/">Navigation</a> <a class="post-tag btn btn-outline-primary" href="/tags/gradle/">Gradle</a> <a class="post-tag btn btn-outline-primary" href="/tags/ios/">iOS</a> <a class="post-tag btn btn-outline-primary" href="/tags/androidx/">AndroidX</a></div></section></div></aside></div><div class="row"><div id="tail-wrapper" class="col-12 col-lg-11 col-xl-9 px-md-4"><footer aria-label="Site Info" class=" d-flex flex-column justify-content-center text-muted flex-lg-row justify-content-lg-between align-items-lg-center pb-lg-3 " ><p>漏 <time>2025</time> <a href="https://twitter.com/funky_muse">FunkyMuse</a>. <span data-bs-toggle="tooltip" data-bs-placement="top" title="Except where otherwise noted, the blog posts on this site are licensed under the Creative Commons Attribution 4.0 International (CC BY 4.0) License by the author." >Some rights reserved.</span></p><p>Using the <a data-bs-toggle="tooltip" data-bs-placement="top" title="v7.2.4" href="https://github.com/cotes2020/jekyll-theme-chirpy" target="_blank" rel="noopener" >Chirpy</a> theme for <a href="https://jekyllrb.com" target="_blank" rel="noopener">Jekyll</a>.</p></footer></div></div><div id="search-result-wrapper" class="d-flex justify-content-center d-none"><div class="col-11 content"><div id="search-hints"><section><h2 class="panel-heading">Trending Tags</h2><div class="d-flex flex-wrap mt-3 mb-1 me-3"> <a class="post-tag btn btn-outline-primary" href="/tags/android/">Android</a> <a class="post-tag btn btn-outline-primary" href="/tags/kotlin/">Kotlin</a> <a class="post-tag btn btn-outline-primary" href="/tags/dagger/">Dagger</a> <a class="post-tag btn btn-outline-primary" href="/tags/hilt/">Hilt</a> <a class="post-tag btn btn-outline-primary" href="/tags/compose/">Compose</a> <a class="post-tag btn btn-outline-primary" href="/tags/kmp/">KMP</a> <a class="post-tag btn btn-outline-primary" href="/tags/navigation/">Navigation</a> <a class="post-tag btn btn-outline-primary" href="/tags/gradle/">Gradle</a> <a class="post-tag btn btn-outline-primary" href="/tags/ios/">iOS</a> <a class="post-tag btn btn-outline-primary" href="/tags/androidx/">AndroidX</a></div></section></div><div id="search-results" class="d-flex flex-wrap justify-content-center text-muted mt-3"></div></div></div></div><aside aria-label="Scroll to Top"> <button id="back-to-top" type="button" class="btn btn-lg btn-box-shadow"> <i class="fas fa-angle-up"></i> </button></aside></div><div id="mask" class="d-none position-fixed w-100 h-100 z-1"></div><aside id="notification" class="toast" role="alert" aria-live="assertive" aria-atomic="true" data-bs-animation="true" data-bs-autohide="false" ><div class="toast-header"> <button type="button" class="btn-close ms-auto" data-bs-dismiss="toast" aria-label="Close" ></button></div><div class="toast-body text-center pt-0"><p class="px-2 mb-3">A new version of content is available.</p><button type="button" class="btn btn-primary" aria-label="Update"> Update </button></div></aside><script> document.addEventListener('DOMContentLoaded', () => { SimpleJekyllSearch({ searchInput: document.getElementById('search-input'), resultsContainer: document.getElementById('search-results'), json: '/assets/js/data/search.json', searchResultTemplate: '<article class="px-1 px-sm-2 px-lg-4 px-xl-0"><header><h2><a href="{url}">{title}</a></h2><div class="post-meta d-flex flex-column flex-sm-row text-muted mt-1 mb-1"> {categories} {tags}</div></header><p>{snippet}</p></article>', noResultsText: '<p class="mt-5">Oops! No results found.</p>', templateMiddleware: function(prop, value, template) { if (prop === 'categories') { if (value === '') { return `${value}`; } else { return `<div class="me-sm-4"><i class="far fa-folder fa-fw"></i>${value}</div>`; } } if (prop === 'tags') { if (value === '') { return `${value}`; } else { return `<div><i class="fa fa-tag fa-fw"></i>${value}</div>`; } } } }); }); </script>