文章目录
- 一、前言
- 二、示例代码
- 三、AndroidView的注意事项
- 四、参考链接
一、前言
Compose自身组件有时候并不能完全满足要求,这里演示如何在Compose中添加原生组件及其注意事项
二、示例代码
@Composablefun AndroidTextView(modifier: Modifier) {AndroidView(modifier = modifier,factory = { ctx ->
// 以下的方式也可以加载Fragmentval viewGroup = LayoutInflater.from(ctx).inflate(R.layout.ad_banner_fragment, null) as FrameLayoutviewGroup.post {Log.e("YM--->","渲染结束")showFragment(fragmentManager, viewGroup, adsFragment)}viewGroup},)}
这里需要注意的是添加布局有三种方式,一种是使用AndroidViewBinding
、一种是使用AndroidView
。上述是AndroidView
的演示,
下面是AndroidViewBinding
的演示
AndroidViewBinding(MyFragmentLayoutBinding::inflate) {val myFragment = fragmentContainerView.getFragment<MyFragment>()// ...}
三、AndroidView的注意事项
假如在Compose中只是简单的把控件定义完进行显示的话。可以使用加载布局的方式,也可以使用动态生成控件的方式,如下
@Composablefun AndroidTextView(modifier: Modifier) {AndroidView(modifier = modifier,factory = { ctx ->val imageView = ImageView(ctx)imageView.layoutParams = ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.MATCH_PARENT)imageView.id = View.generateViewId()imageView.setImageResource(R.drawable.ic_rc_track_user)imageView},)}
不过该方式仅仅适用于创建控件之前就准备好了数据,然后仅仅是用来显示后续不做其余操作。假如创建一个ViewGroup
,后要往里面添加Fragment
类似的操作,这时候需要使用到控件id的话,这时候使用会有问题,因为组件并没有完全创建完毕,通过id获取控件的结果是空值或者是另外一个控件,所以需要使用view.post{}
的方式等待渲染完成后再做其余操作。这里可以使用定义一个布局,然后使用布局里面的id给ViewGropu
赋值id。虽然控件还是找不到,通过findViewById
的方式获取的控件还是null,但是在添加到Fragment到时候还是有很大可能创建完毕的。或者使用view.post{}
的方式等待渲染结果,这里等待结果的方式不可以使用ViewTreeObserver.OnGlobalLayoutListener
来获取,有可能完成的回调不执行。
以上情况在同一个布局中出现多个原生组件时候会在某些手机上有较大概率发生。
四、参考链接
- 在 Compose 中使用 View