Reputation: 4035
How to set the child view's width using data binding. The value to set is dynamic and it depends on the width of the parent layout.
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>
The model can give me a percentage. Ex, if the percentage is 40%, it means the width of the textview should be 40% of the parent layout.
I know the idea of using data binding adapters, but dont know how to do it with the parent layout's width.
Upvotes: 1
Views: 2708
Reputation: 4035
What I end up doing is follow @Raghunandan's suggestion
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()
}
})
}
}
}
Upvotes: 0
Reputation: 5392
I'm afraid you will be disappointed on this one iori24. I tried for qhite a while to figure out how to accomplish this, but some variables can be done post draw and some have to be done pre draw. Binding is meant to be for post draw type of values. layout_width and layout_height are pre draw values that need to be set ahead of time.
Unfortunately there is no current way to do this. I found many articles on it and can confirm this statement. However, I managed to find ways to manipulate my UI with various match parents or weights to accomplish what I needed or adjust in code.
I would love if they brought data binding to layout_width and height, and I think they will eventually, but for now you will just have to get more creative with your design.
If you would like you could provide your full sample code for someone to modify and hand back with potential fixes, but I'm guessing you will need a code option here and not an XML option. Now namezhouyu posted a binding adapter option. This is a postdraw that will take the textview and potentially modify it's value after it has been drawn. This could work, but you may see strange behavior as the original size would be wrap_content and then each subsequent change would cause it to jump to correct size. But I do like his work around, it is a clever solution.
So if you are bound and determined to do it through binding, then I would follow namez houyu's option.
Upvotes: 2
Reputation: 224
You can create a class file, example MyBingding.class
@BindingAdapter({ "bindWidth" })
public static void bindWidth(TextView textView, double perc) {
//You can do something by java code here
textView.xxxxxxxx;
}
Then use bindWidth method in XML:
<TextView
app:bindWidth="@{model.usedBarWidthPercentage}"
android:layout_width="wrap_content"
android:layout_height="4dp"/>
Make sure the usedBarWidthPercentage's data type is same as bindWidth method's perc.
Upvotes: 2