代码创建的视图规则应用异常,自定义双图Dialog问题排查
解决自定义Dialog中代码创建视图未正确应用布局规则的问题
我看你在创建带两张图片的自定义Dialog时,碰到了代码生成的视图布局规则不生效的问题,结合你给出的代码片段,我来帮你分析下最常见的原因和解决办法:
首先先把你给出的代码片段补全展示:
class TransparentProgressDialog(context: Context) : Dialog(context, R.style.DialogTheme) { private val iv_logo: ImageView private val iv: ImageView init { val wlmp = getWindow().getAttributes() wlmp.gravity = Gravity.CENTER_HORIZONTAL getWindow().setAttributes(wlmp) getWindow().requestFeature(Window.FEATURE_NO_TITLE); setTitle(null) setCancelable(false) setOnCancelListener(null) val rl = RelativeLayout(this.context) // 此处应该是创建iv_logo和iv的代码,但未完成,布局失效大概率源于未设置布局参数 } }
核心问题:缺少显式的布局参数设置
通过纯代码创建View时,每个子View都必须设置对应父容器类型的LayoutParams——如果不设置,父容器(这里是RelativeLayout)不知道如何摆放子View,就会出现布局混乱、视图不显示或者规则不生效的情况。
具体解决步骤
给根RelativeLayout设置窗口布局参数
因为Dialog的窗口有自己的容器,需要给根布局设置合适的宽高参数:val rl = RelativeLayout(context).apply { layoutParams = WindowManager.LayoutParams( WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.WRAP_CONTENT ) // 可以给根布局加个背景或者padding,优化显示效果 setPadding( context.resources.getDimensionPixelSize(R.dimen.dialog_padding), context.resources.getDimensionPixelSize(R.dimen.dialog_padding), context.resources.getDimensionPixelSize(R.dimen.dialog_padding), context.resources.getDimensionPixelSize(R.dimen.dialog_padding) ) }给两个ImageView设置RelativeLayout布局参数
假设你想让两张图水平居中、上下排列,需要给每个ImageView设置RelativeLayout.LayoutParams,并添加对应的布局规则:iv_logo = ImageView(context).apply { setImageResource(R.drawable.your_logo_icon) // 生成唯一id,方便后续布局规则引用 id = View.generateViewId() val logoParams = RelativeLayout.LayoutParams( RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT ).apply { // 水平居中 addRule(RelativeLayout.CENTER_HORIZONTAL) // 靠父布局顶部 addRule(RelativeLayout.ALIGN_PARENT_TOP) // 设置顶部间距 topMargin = context.resources.getDimensionPixelSize(R.dimen.margin_top) } layoutParams = logoParams } iv = ImageView(context).apply { setImageResource(R.drawable.your_progress_indicator) val ivParams = RelativeLayout.LayoutParams( RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT ).apply { // 水平居中 addRule(RelativeLayout.CENTER_HORIZONTAL) // 放在iv_logo的下方 addRule(RelativeLayout.BELOW, iv_logo.id) // 设置与logo的间距 topMargin = context.resources.getDimensionPixelSize(R.dimen.margin_between_images) } layoutParams = ivParams }将ImageView添加到根布局,并设置为Dialog内容视图
最后别忘了把视图添加到容器里,再设置给Dialog:rl.addView(iv_logo) rl.addView(iv) setContentView(rl)
额外检查点
- 确认你的
DialogTheme配置正确,避免主题影响布局显示:<style name="DialogTheme" parent="@android:style/Theme.Material.Dialog"> <item name="android:windowBackground">@android:color/transparent</item> <item name="android:windowNoTitle">true</item> <item name="android:windowIsFloating">true</item> <item name="android:windowContentOverlay">@null</item> </style> - 如果觉得代码创建布局太繁琐,也可以改用xml自定义布局的方式:先写一个
dialog_progress.xml布局文件,直接在Dialog里调用setContentView(R.layout.dialog_progress),这样xml里的布局规则会自动生效,更不容易出错。
按照上面的步骤补全布局参数后,你的Dialog布局规则应该就能正常生效了。
内容的提问来源于stack exchange,提问作者Ahad Porkar
相关产品推荐
相关产品推荐

