Skip to content

Instantly share code, notes, and snippets.

View tfcporciuncula's full-sized avatar

Fred Porciúncula tfcporciuncula

View GitHub Profile
@tfcporciuncula
tfcporciuncula / composables.kt
Created April 23, 2024 13:31
Getting arg from ViewModel with Hilt assisted injection
@HiltViewModel(assistedFactory = DetailsViewModel.Factory::class)
class DetailsViewModel @AssistedInject constructor(
@Assisted val arg: String,
) : ViewModel() {
@AssistedFactory interface Factory {
fun create(arg: String): DetailsViewModel
}
private val state = MutableStateFlow(DetailsUiState(arg = arg))
fun state() = state.asStateFlow()
@tfcporciuncula
tfcporciuncula / composables.kt
Last active April 23, 2024 13:29
Getting arg from ViewModel with savedStateHandle
// Both screens look the same, but now we have a ViewModel and some differences on the App composable
@HiltViewModel
class DetailsViewModel @Inject constructor(
savedStateHandle: SavedStateHandle,
) : ViewModel() {
private val state = MutableStateFlow(requireNotNull(savedStateHandle.get("arg")))
fun state() = state.asStateFlow()
}
@Composable
@tfcporciuncula
tfcporciuncula / Composables.kt
Last active April 23, 2024 11:51
Getting arg directly from navBackStackEntry
@Composable
fun StartScreen(onNavigateClick: (String) -> Unit) {
Column(
modifier = Modifier.fillMaxSize(),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally,
) {
var argText by rememberSaveable { mutableStateOf("") }
TextField(
value = argText,
@tfcporciuncula
tfcporciuncula / PdfAdapter.kt
Last active March 19, 2024 11:50
PDF rendering the easy way
class PdfAdapter(
// this would come from the ViewModel so we don't need to recreate it on config change
// and the VM can close it within onCleared()
private val renderer: PdfRenderer,
// this would come from the Activity/Fragment based on the display metrics
private val pageWidth: Int
) : RecyclerView.Adapter<PdfAdapter.ViewHolder>() {
class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
class TokenAuthenticator @Inject constructor(
private val api: Api,
private val tokenStore: TokenStore,
private val logoutTrigger: LogoutTrigger
) : Authenticator {
companion object {
const val AUTH_HEADER_NAME = "Authorization"
const val AUTH_HEADER_VALUE_FORMAT = "Bearer %s"
}
val viewModelStoreOwner = requireNotNull(
LocalViewModelStoreOwner.current as? HasDefaultViewModelProviderFactory
)
val viewModel = viewModel<MyViewModel>(
extras = viewModelStoreOwner
.defaultViewModelCreationExtras
.withCreationCallback<MyViewModel.Factory> { factory ->
factory.create(runtimeArg = "abc")
}
)
val creationCallback: (MyViewModel.Factory) -> MyViewModel = { factory ->
factory.create(runtimeArg = "abc")
}
val viewModel = viewModel<MyViewModel>(
extras = requireNotNull(LocalViewModelStoreOwner.current).run {
if (this is HasDefaultViewModelProviderFactory) {
this.defaultViewModelCreationExtras.withCreationCallback(creationCallback)
} else {
CreationExtras.Empty.withCreationCallback(creationCallback)
}
val viewModel = hiltViewModel<MyViewModel, MyViewModel.Factory>(
creationCallback = { factory -> factory.create(runtimeArg = "abc") }
)
private val viewModel by viewModels<MyViewModel>(
extrasProducer = {
defaultViewModelCreationExtras.withCreationCallback<MyViewModel.Factory> { factory ->
factory.create(runtimeArg = "abc")
}
}
)
@HiltViewModel(assistedFactory = MyViewModel.Factory::class)
class MyViewModel @AssistedInject constructor(
@Assisted val runtimeArg: String,
// other dependencies
) : ViewModel() {
@AssistedFactory interface Factory {
fun create(runtimeArg: String): MyViewModel
}
...
}