Posts

ViewModel Factory (Class Instances)

Image
In the previous post,  ViewModel Factory (Old vs. Newer DSL) , we talked about a more modern ViewModel factory. This practice works well, but there is something dangerous you may miss... Previous Example Take a quick look at this code below and think about where this might go wrong... companion object { private const val MODERN_UI_STATE_KEY = "modern_ui_state" @VisibleForTesting internal fun factory (name: String) = viewModelFactory { initializer { ModernDSLStyleFactoryViewModel( name = name, savedStateHandle = createSavedStateHandle () ) } } @Composable fun get ( name: String = "Modern DSL ViewModel Factory" ): ModernDSLStyleFactoryViewModel { return viewModel ( factory = factory(name)) } } The code above is safe, but that's because we're using literals... ...but if we pass in an object, things get more complicated. New Example We'll s...

Bugs are Fun!!

Image
Introduction / Audience I stumbled across a bug in my code and I couldn't figure out what was causing it. After tracking it down, I felt this would make a good post to highlight a rare and interesting bug. I believe this is a known bug so this post is nothing groundbreaking, but I don't think it is very widely known. The target audience is anyone from beginners to experts: For beginners, you can learn how to approach finding a difficult bug in a logical methodical manner. It will also introduce you to Kotlin Playground if you haven't seen it before.  For experts, you can test you knowledge and experience and see if you can identify the issue from the original code. Warning: This post contains bugs and cute images of bugs. The Bug The bug was, as is usually the case, hidden in a large amount of code. The Error Exception in thread "main" java.lang.NullPointerException : Cannot invoke "Node$Option.getCode()" because "it" is null So a null-pointe...

Navigation 3 - Part 3 - Muscle Car Example

Image
Part 3 As mentioned in Part 2 , this series is a little longer than I had originally hoped. In this third (and hopefully final) part, we will cover ViewModels with Navigation3 and make something that looks a little nicer. The code listing is quite long so I will avoid explaining the UI elements here and focus on the sections relevant to Navigation3 . If you haven't already read the previous entries and are not already familiar with Navigation3 , I strongly recommend starting with Part 1 . The main goal here is to give you a working sample to play with. This post will not go into too much detail on each of these points so you will need to read around any new subjects that come up to learn more. Notes - Saving Data One compromise I chose to make was not saving any data . You will be able to take notes for each car, but those notes will vanish when you change to another page. If you want to store those notes, please take a look at my DataStore post or my Room3 post . That should give...

Navigation 3 - Part 2 - Dual Pane Examples

Image
Part 2 I was originally going to stick with two parts for this guide, but there was just far too much content to cram it in. I think the final version would have introduce far too many concepts and this would have been a nightmare to explain and learn from. Rather than jump straight from the basic introduction to the final muscle car example, I decided to add an intermediate step. So here we are, the added part two. Focus This part will focus on adding dual-pane support and and a backstack guard to handle that (our previous version will not). We will briefly cover size restrictions for dual-pane testing as well as hierarchical back vs chronological back . We are reusing most of the code from our previous examples so the code listing will be short and simple - perfect for learning. This does mean you will need the previous examples and of course the dependencies to get everything working. There are two solutions: Dual Pane Example 1  and  Dual Pane Example 2 . You can sk...