Open wilfredbtan opened 3 months ago
The problem is in ViewAttachmentManager. It adds FrameLayout to WindowManager and non of them have reference on LifecycleOwner.
Here is workaround I created temporary. Replace lib's ViewAttachmentManager on this one:
`import android.content.Context import android.graphics.PixelFormat import android.view.View import android.view.ViewGroup import android.view.WindowManager import android.widget.FrameLayout import androidx.lifecycle.DefaultLifecycleObserver import androidx.lifecycle.LifecycleOwner import androidx.lifecycle.ViewModelStoreOwner import androidx.lifecycle.setViewTreeLifecycleOwner import androidx.lifecycle.setViewTreeViewModelStoreOwner import androidx.savedstate.SavedStateRegistryOwner import androidx.savedstate.setViewTreeSavedStateRegistryOwner import com.google.ar.sceneform.rendering.ViewAttachmentManager
/**
Don't forget to add to lifecycle observers otherwise View will not be rendered */ class ComposableViewAttachmentManager( context: Context, private val lifecycleOwner: LifecycleOwner, private val viewModelStoreOwner: ViewModelStoreOwner, private val savedStateRegistryOwner: SavedStateRegistryOwner, private val ownerView: View // Used to post callbacks onto the UI thread. ): ViewAttachmentManager(context, ownerView), DefaultLifecycleObserver { private val windowManager: WindowManager private val windowLayoutParams: WindowManager.LayoutParams private val frameLayout: FrameLayout private val viewLayoutParams: ViewGroup.LayoutParams
init { windowManager = context.getSystemService(Context.WINDOW_SERVICE) as WindowManager windowLayoutParams = createWindowLayoutParams() frameLayout = FrameLayout(context) viewLayoutParams = createViewLayoutParams()
frameLayout.setViewTreeLifecycleOwner(lifecycleOwner)
frameLayout.setViewTreeSavedStateRegistryOwner(savedStateRegistryOwner)
frameLayout.setViewTreeViewModelStoreOwner(viewModelStoreOwner)
}
override fun onResume(owner: LifecycleOwner) { onResume() }
override fun onPause(owner: LifecycleOwner) { onPause() }
override fun onResume() { // A ownerView can only be added to the WindowManager after the activity has finished resuming. // Therefore, we must use post to ensure that the window is only added after resume is finished. ownerView.post { if (frameLayout.parent == null && ownerView.isAttachedToWindow) { windowManager.addView(frameLayout, windowLayoutParams) } } }
override fun onPause() { // The ownerView must be removed from the WindowManager before the activity is destroyed, or the // window will be leaked. Therefore we add/remove the ownerView in resume/pause. if (frameLayout.parent != null) { windowManager.removeView(frameLayout) } }
/**
/**
companion object { private const val VIEW_RENDERABLE_WINDOW = "ViewRenderableWindow" private fun createWindowLayoutParams(): WindowManager.LayoutParams { val params = WindowManager.LayoutParams( WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.TYPE_APPLICATION_PANEL, WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE or WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS or WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE or WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED, PixelFormat.TRANSLUCENT ) params.title = VIEW_RENDERABLE_WINDOW return params }
private fun createViewLayoutParams(): ViewGroup.LayoutParams {
return ViewGroup.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT
)
}
} } `
Previously, I would use the ViewRenderable to render an AndroidView. However, as
ViewNode
has changed significantly in v2.1.0, I am unable to get my AndroidView to show properly.This is my old code:
This is my broken attempt at trying to render the a child node:
Running the above results in the following crash:
Could anyone guide me in the right direction to render a ViewNode properly in v2.1.0?