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()
}
})
}
}
}
如何使用数据绑定设置子视图的宽度。要设置的值是动态的,它取决于父布局的宽度。
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()
}
})
}
}
}