华为广告Native Ads实现中MediaView约束不匹配、高度无法调整问题
问题原因
- 布局中给
MediaView设置了app:layout_constraintHeight_percent="0.8",百分比约束优先级高于代码动态设置的高度,导致修改无效 OnHierarchyChangeListener是在子View添加时才触发回调,你设置监听的时候MediaView内部的图片/视频子View可能已经添加完成,回调不会执行,自然没有修改效果- 你只修改了
MediaView内部子View的高度,没有同步修改MediaView本身的布局高度,父容器的约束会限制子View的展示范围
修复方案
1. 调整布局文件
删除固定的高度百分比约束,保留上下约束即可,给动态修改高度留空间:
<com.huawei.hms.ads.nativead.MediaView android:id="@+id/ad_media" android:layout_width="0dp" android:layout_height="wrap_content" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintBottom_toTopOf="@id/constraintLayout"/> <androidx.constraintlayout.widget.ConstraintLayout android:id="@+id/constraintLayout" android:layout_width="0dp" android:layout_height="wrap_content" android:background="@drawable/white_bg" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@id/ad_media"/>
2. 修改初始化逻辑
主动遍历已存在的子View修改高度,同时保留监听处理后续新增的子View,同步修改MediaView本身的高度:
private fun initNativeAdView(nativeAd: NativeAd?, nativeView: NativeView) { nativeAd ?: return nativeView.titleView = nativeView.findViewById(R.id.ad_title) (nativeView.titleView as TextView).text = nativeAd.title val mediaView = nativeView.findViewById<MediaView>(R.id.ad_media) nativeView.mediaView = mediaView mediaView.setMediaContent(nativeAd.mediaContent) // 计算动态高度,示例为占屏幕宽度的60%,可按需求调整比例 val displayMetrics = context.resources.displayMetrics val screenWidth = displayMetrics.widthPixels val expectMediaHeight = (screenWidth * 0.6f).toInt() // 如果需要适配素材本身的宽高比,可替换为:val expectMediaHeight = (screenWidth / nativeAd.mediaContent.aspectRatio).toInt() // 先处理已经添加的子View,解决监听添加前子View已存在的问题 for (i in 0 until mediaView.childCount) { adjustChildViewHeight(mediaView.getChildAt(i), expectMediaHeight) } // 设置层级监听,处理后续新增的子View mediaView.setOnHierarchyChangeListener(object : ViewGroup.OnHierarchyChangeListener { override fun onChildViewAdded(parent: View, child: View) { adjustChildViewHeight(child, expectMediaHeight) } override fun onChildViewRemoved(parent: View, child: View) {} }) // 同步修改MediaView本身的布局高度 val mediaParams = mediaView.layoutParams mediaParams.height = expectMediaHeight mediaView.layoutParams = mediaParams } private fun adjustChildViewHeight(child: View, expectHeight: Int) { if (child is ImageView) { child.adjustViewBounds = true child.maxHeight = expectHeight child.scaleType = ImageView.ScaleType.CENTER_CROP } else { val params = child.layoutParams params.height = expectHeight child.layoutParams = params } }
注意事项
- 视频类广告可根据返回的素材宽高比计算高度,避免画面拉伸
- 不要同时使用
layout_constraintHeight_percent和动态高度设置,百分比约束会覆盖代码修改的高度值
内容的提问来源于stack exchange,提问作者Waheed Shah
相关产品推荐
相关产品推荐

