Skip to content

Instantly share code, notes, and snippets.

@AndroidEntryPoint
class CounterFragment : Fragment() {
@Inject
internal lateinit var analyticsModelProvider: AnalyticsModelProvider
private var analyticsModel: CounterAnalyticsModel? = null
private val viewModel: CounterViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
class AnalyticsModelProvider(private val analyticsModelMap: Map<Class<out AnalyticsModel<*>>, Provider<AnalyticsModel<*>>>) {
@Suppress("UNCHECKED_CAST")
operator fun <T : AnalyticsModel<*>> get(modelClass: Class<T>): T? {
val analyticsModel = analyticsModelMap[modelClass]?.get() ?: return null
return analyticsModel as T
}
}
@Module
@InstallIn(ApplicationComponent::class)
abstract class AnalyticsModule {
@Binds
@IntoMap
@AnalyticsModelKey(CounterAnalyticsModel::class)
internal abstract fun provideCounterScreenAnalyticsModel(
analyticsModel: CounterAnalyticsModel
): AnalyticsModel<*>
@MapKey
annotation class AnalyticsModelKey(val value: KClass<out AnalyticsModel<*>>)
class CounterAnalyticsModel @Inject constructor(
private val analyticsTracker: AnalyticsTracker
) : AnalyticsModel<CounterViewModel>() {
override fun onScreenViewModelAttached() {
viewModel.viewModelScope.launch {
flowOf(
viewModel.decrementValue
.getExecutedEvents()
.onEach {
abstract class AnalyticsModel<T : ViewModel> {
protected lateinit var viewModel: T
fun getScreenViewModel(): T = viewModel
fun setScreenViewModel(model: T) {
viewModel = model
onScreenViewModelAttached()
}
class FunctionCommand(
private val function: () -> Unit
) : Command {
private val eventChannel = BroadcastChannel<Any>(Channel.BUFFERED)
override fun execute() {
function.invoke()
eventChannel.offer(Any())
}
interface Command {
fun execute()
fun getExecutedEvents(): Flow<Any>
}
...
<data>
<import type="io.supercharge.hiltexample.io.supercharge.hiltexample.analytics.AnalyticsConstants.Event" />
<variable
name="vm"
type="io.supercharge.hiltexample.main.model.CounterViewModel" />
</data>
...
@BindingAdapter(value = ["command", "analyticsEvent"], requireAll = false)
fun View.bindAnalyticsCommandToButton(command: Command?, event: AnalyticsConstants.Event?) {
setOnClickListener {
command?.execute()
event?.let {
(context.applicationContext as HiltApplication?)?.tracker?.logEvent(event)
}
}
}