-
Notifications
You must be signed in to change notification settings - Fork 192
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Compose兼容 #65
Comments
疑,你是怎么使用的,Compose 这个东西不是理论上可以内嵌到任何的 ViewGroup 里面吗? |
https://developer.android.google.cn/jetpack/compose/interop/adding#reuse-view
我是按照这种方式来做的 class ComposeScene : Scene() {
private lateinit var composeView : ComposeView
override fun onCreateView(p0: LayoutInflater, p1: ViewGroup, p2: Bundle?): View {
composeView = ComposeView(requireSceneContext())
return composeView
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
composeView.setContent {
CardTheme {
ProvideWindowInsets {
val systemUiController = rememberSystemUiController()
val darkIcons = MaterialTheme.colors.isLight
SideEffect {
systemUiController.setSystemBarsColor(Color.Transparent, darkIcons = darkIcons)
}
val navController = rememberNavController()
// val navigationActions = remember(navController){
//
// }
Greeting()
}
}
}
}
@Composable
private fun Greeting() {
Text(
text = "我是测试文字",
modifier = Modifier.padding(horizontal = 10.dp, vertical = 5.dp)
)
}
} |
在你的首页的 Activity 的 onCreate 里面补充这段代码 ViewTreeLifecycleOwner.set(window.decorView, this)
ViewTreeViewModelStoreOwner.set(window.decorView, this)
ViewTreeSavedStateRegistryOwner.set(window.decorView, this) |
头疼啊,公司内部的 androidx 版本普通很旧,所以这个框架也不好直接升级 androidx 的依赖 |
还有一种做法,我感觉这种更合适 import android.view.View
import androidx.compose.runtime.MonotonicFrameClock
import androidx.compose.runtime.PausableMonotonicFrameClock
import androidx.compose.runtime.Recomposer
import androidx.compose.ui.platform.AndroidUiDispatcher
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleEventObserver
import androidx.lifecycle.LifecycleOwner
import com.bytedance.scene.Scene
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.CoroutineStart
import kotlinx.coroutines.launch
import kotlin.coroutines.EmptyCoroutineContext
fun Scene.createLifecycleAwareViewTreeRecomposer(): Recomposer {
val currentThreadContext = AndroidUiDispatcher.CurrentThread
val pausableClock = currentThreadContext[MonotonicFrameClock]?.let {
PausableMonotonicFrameClock(it).apply { pause() }
}
val contextWithClock = currentThreadContext + (pausableClock ?: EmptyCoroutineContext)
val recomposer = Recomposer(contextWithClock)
val runRecomposeScope = CoroutineScope(contextWithClock)
val viewTreeLifecycleOwner = this
// Removing the view holding the ViewTreeRecomposer means we may never be reattached again.
// Since this factory function is used to create a new recomposer for each invocation and
// doesn't reuse a single instance like other factories might, shut it down whenever it
// becomes detached. This can easily happen as part of setting a new content view.
this.view.addOnAttachStateChangeListener(
object : View.OnAttachStateChangeListener {
override fun onViewAttachedToWindow(v: View?) {}
override fun onViewDetachedFromWindow(v: View?) {
this@createLifecycleAwareViewTreeRecomposer.view.removeOnAttachStateChangeListener(this)
recomposer.cancel()
}
}
)
viewTreeLifecycleOwner.lifecycle.addObserver(
object : LifecycleEventObserver {
override fun onStateChanged(lifecycleOwner: LifecycleOwner, event: Lifecycle.Event) {
val self = this
when (event) {
Lifecycle.Event.ON_CREATE ->
// Undispatched launch since we've configured this scope
// to be on the UI thread
runRecomposeScope.launch(start = CoroutineStart.UNDISPATCHED) {
try {
recomposer.runRecomposeAndApplyChanges()
} finally {
// If runRecomposeAndApplyChanges returns or this coroutine is
// cancelled it means we no longer care about this lifecycle.
// Clean up the dangling references tied to this observer.
lifecycleOwner.lifecycle.removeObserver(self)
}
}
Lifecycle.Event.ON_START -> pausableClock?.resume()
Lifecycle.Event.ON_STOP -> pausableClock?.pause()
Lifecycle.Event.ON_DESTROY -> {
recomposer.cancel()
}
Lifecycle.Event.ON_PAUSE -> {
// Nothing
}
Lifecycle.Event.ON_RESUME -> {
// Nothing
}
Lifecycle.Event.ON_ANY -> {
// Nothing
}
}
}
}
)
return recomposer
} 然后你的 Scene,补充 composeView.setParentCompositionContext(createLifecycleAwareViewTreeRecomposer()) class ComposeScene : Scene() {
private lateinit var composeView : ComposeView
override fun onCreateView(p0: LayoutInflater, p1: ViewGroup, p2: Bundle?): View {
composeView = ComposeView(requireSceneContext())
return composeView
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
ViewTreeLifecycleOwner.set(this.view, this)
ViewTreeViewModelStoreOwner.set(this.view, this)
ViewTreeSavedStateRegistryOwner.set(this.view, fragmentActivity())
composeView.setParentCompositionContext(createLifecycleAwareViewTreeRecomposer())
composeView.setContent {
CardTheme {
ProvideWindowInsets {
val systemUiController = rememberSystemUiController()
val darkIcons = MaterialTheme.colors.isLight
SideEffect {
systemUiController.setSystemBarsColor(Color.Transparent, darkIcons = darkIcons)
}
val navController = rememberNavController()
// val navigationActions = remember(navController){
//
// }
Greeting()
}
}
}
}
@Composable
private fun Greeting() {
Text(
text = "我是测试文字",
modifier = Modifier.padding(horizontal = 10.dp, vertical = 5.dp)
)
}
} |
好的...我试一哈,多谢大佬指点ღ( ´・ᴗ・` ) |
@qii 是可以的,多谢!! |
有考虑兼容Compose嘛(╹▽╹)尝试在Scene中嵌入ComposeView报错
The text was updated successfully, but these errors were encountered: