android数据绑定从父宽度设置layout_width

时间:2017-09-28 06:16:26

标签: android android-databinding

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

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%。

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

3 个答案:

答案 0 :(得分:1)

您可以创建一个类文件,例如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相同。

答案 1 :(得分:1)

我担心你会对这个iori24感到失望。我尝试了qhite一段时间来弄清楚如何完成这个,但有些变量可以在绘制后完成,有些必须在绘制前完成。绑定意味着用于后期绘制类型的值。 layout_width和layout_height是需要提前设置的预绘制值。

不幸的是,目前没有办法做到这一点。我发现了很多文章,可以证实这一说法。但是,我设法找到了使用各种匹配父项或权重来操纵我的UI以实现我需要或调整代码的方法。

我很乐意,如果他们将数据绑定到layout_width和height,我认为他们最终会这样做,但是现在你只需要对你的设计有更多创意。

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

因此,如果你受约束并决心通过绑定来实现,那么我会遵循namez houyu的选择。

答案 2 :(得分:0)

我最终要做的是遵循@ 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()
                }
            })
        }
    }
}