android 数据绑定集 layout_width 来自父宽度

android data binding set layout_width from parent width

如何使用数据绑定设置子视图的宽度。要设置的值是动态的,它取决于父布局的宽度。

item_bar.xml

<LinearLayout
    android:id="@+id/barLayout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">
    <TextView
        android:layout_width="@{model.usedBarWidthPercentage}"
        android:layout_height="4dp"/>
</LinearLayout>

模特可以给我一个百分比。例如,如果百分比为 40%,则表示 textview 的宽度应为父布局的 40%。

我知道使用数据绑定适配器的想法,但不知道如何使用父布局的宽度。

您可以创建一个 class 文件,例如 MyBingding.class

@BindingAdapter({ "bindWidth" })
public static void bindWidth(TextView textView, double perc) {
    //You can do something by java code here 
    textView.xxxxxxxx; 
}

然后在XML中使用bindWidth方法:

<TextView
    app:bindWidth="@{model.usedBarWidthPercentage}"
    android:layout_width="wrap_content"
    android:layout_height="4dp"/>

确保 usedBarWidthPercentage 的数据类型与 bindWidth 方法的 perc 相同。

恐怕你会对这个 iori24 感到失望。我为 qhite 尝试了一段时间以弄清楚如何完成此操作,但有些变量可以 post 绘制完成,有些必须在绘制前完成。绑定是为了 post 绘制类型的值。 layout_width和layout_height是需要提前设置的预绘制值。

遗憾的是,目前没有办法做到这一点。我在上面找到了很多文章,可以证实这个说法。但是,我设法找到了使用各种匹配 parents 或权重来操纵我的 UI 的方法,以完成我需要的或在代码中进行调整。

如果他们将数据绑定带到 layout_width 和高度,我会很高兴,我认为他们最终会,但现在你只需要在你的设计中更有创意。

如果您愿意,可以提供完整的示例代码供他人修改并返回可能的修复程序,但我猜您将需要此处的代码选项,而不是 XML 选项。现在 namezhouyu posted 了一个绑定适配器选项。这是一个 postdraw,它将获取 textview 并可能在绘制后修改它的值。这可行,但您可能会看到奇怪的行为,因为原始大小为 wrap_content,然后每次后续更改都会导致它跳转到正确的大小。但我确实喜欢他的工作,这是一个聪明的解决方案。

所以如果你是绑定的,并且确定要通过绑定来实现,那么我会按照namez houyu的选择。

我最终做的是遵循@Raghunandan 的建议

class ViewHolder(val binding: ItemViewBinding) : RecyclerView.ViewHolder(binding.root) {

    fun bind(model: Model) {
        Logger.d("START")
        binding.model = model

        val treeObserver = binding.viewLayout.viewTreeObserver
        if (treeObserver.isAlive) {
            treeObserver.addOnGlobalLayoutListener(object : OnGlobalLayoutListener {
                override fun onGlobalLayout() {
                    binding.viewLayout.viewTreeObserver.removeOnGlobalLayoutListener(this) // need to call viewTreeObserver again
                    val maxValue = binding.viewLayout.width
                    val usePerc = binding.model.getUsedBarWidthPercentage()
                    Logger.d("maxValue=$maxValue, usePerc=$usePerc")
                    binding.view.layoutParams.width = (maxValue * usePerc).toInt()
                }
            })
        }
    }
}