rishabhsinghbisht
11/14/2022, 5:04 PMAndroidViewLazyListFunkyMuse
11/14/2022, 7:32 PMChris Sinco [G]
11/14/2022, 9:30 PMBen Trengrove [G]
11/14/2022, 9:31 PMrishabhsinghbisht
11/15/2022, 5:27 AMrishabhsinghbisht
11/21/2022, 3:50 AMmattinger
11/22/2022, 3:53 AMcontentType: Any? = nullobject MyViewType
item(contentType=MyViewType) {
    AndroidView(...) { ... }
}rishabhsinghbisht
11/22/2022, 3:57 AMmattinger
11/22/2022, 5:27 AMrishabhsinghbisht
11/22/2022, 5:29 AMremember{ViewPool()}mattinger
11/22/2022, 5:35 AMmattinger
11/22/2022, 6:18 AMclass ViewPool<T : View>(
    val factory: (Context) -> T,
    val viewBlockCreateSize: Int = 1,
) {
    private val allocatedViews = mutableListOf<T>()
    private val freeViews = mutableListOf<T>()
    private var createCounter = 0
    fun checkoutView(context: Context): T {
        Log.d("VIEWPOOL", "checkout")
        return synchronized(this) {
            if (freeViews.isEmpty()) {
                (0 until viewBlockCreateSize).forEach {
                    createCounter += 1
                    Log.d("VIEWPOOL", "create ${createCounter}")
                    freeViews.add(factory(context))
                }
            }
            freeViews.removeAt(0).apply {
                allocatedViews.add(this)
            }
        }
    }
    fun returnView(view: T) {
        Log.d("VIEWPOOL", "return")
        synchronized(this) {
            (view.parent as? ViewGroup)?.removeView(view)
            if (allocatedViews.remove(view)) {
                freeViews.add(view)
            }
        }
    }
    fun dispose() {
        synchronized(this) {
            freeViews.clear()
            allocatedViews.forEach {
                (it.parent as ViewGroup)?.removeView(it)
            }
            allocatedViews.clear()
        }
    }
}
@Composable
fun RecycledIcon(
    viewPool: ViewPool<AppCompatImageView>,
    @DrawableRes drawableRes: Int,
) {
    val contentColor = LocalContentColor.current
    val tintColor = Color.argb(
        contentColor.toArgb().alpha,
        contentColor.toArgb().red,
        contentColor.toArgb().green,
        contentColor.toArgb().blue,
    )
    RecycledView(
        viewPool = viewPool,
        update = { view ->
            val drawable = view.context.getDrawable(drawableRes)
            drawable?.let {
                view.setImageDrawable(
                    it.mutate().apply {
                        setTint(this, tintColor)
                    }
                )
                view.layoutParams?.width = it.intrinsicWidth ?: 0
                view.layoutParams?.width = it.intrinsicHeight ?: 0
            }
        }
    )
}
@Composable
fun <T : View> RecycledView(
    viewPool: ViewPool<T>,
    update: (T) -> Unit,
) {
    lateinit var view: T
    AndroidView(
        factory = { context ->
            view = viewPool.checkoutView(context)
            view
        },
        update = update
    )
    DisposableEffect(key1 = true) {
        onDispose {
            viewPool.returnView(view)
        }
    }
}
@Composable
@Preview
fun RecycledIconPreview() {
    MaterialTheme {
        Surface(modifier = Modifier.fillMaxSize()) {
            val viewPool = remember {
                ViewPool<AppCompatImageView>(
                    factory = { context ->
                        AppCompatImageView(context)
                    },
                    viewBlockCreateSize = 1,
                )
            }
            LazyColumn {
                (0..60).forEach {
                    item {
                        RecycledIcon(viewPool, androidx.appcompat.R.drawable.abc_ic_menu_cut_mtrl_alpha)
                    }
                }
            }
            DisposableEffect(key1 = true) {
                onDispose {
                    viewPool.dispose()
                }
            }
        }
    }
}