Dynamic DP values to the layout files using DataBinding

Srinivasa Rao Makkena
3 min readNov 11, 2021

--

We usually display lot of products in the horizontal list in e-commerce apps like recommendations to the customers or others also viewing products or similar products etc. So, to display those products in different width/height in different pages like in marketing page or checkout page etc. We need to add DP’s dynamically and sometimes we may need to add some peaking in to the edge product to let the user know that there are more products on horizontal scrolling, we may have to add the DP’s dynamically. In some scenarios, we may have to display the product to match_parent if there is only one product and add some edge if there are more products. For all these scenarios, we need to add DP’s dynamically to the layout files.

We can apply dynamic width/height/margins etc using data binding dynamically in the layout file.

  • BindingAdapter in Kotlin
  • DisplayMetrics to get the width and height of the device
  • Custom DP’s in layout width and height.

Here these are 2 different items in horizontal list with different height and width. We can use this approach to customize margins/padding/height/width etc. for recycler view items or any view in layout.

We need to create binding adapters as needed and shown in this file. Have created for few xml props that I used in this project.

With this data binding adapters, we can add the custom dimens in the layout file as needed as shown in this layout file.

Here, we are having the custom dimensions of the layout for each recycler view item based on index of the item.

And calculated the list item height using displayMetrics as I need to display different items in different height and width and using them directly in layout using data binding. I have just given random values here, we can change as needed.

val width: LayoutParamValue = if (index == 1) {
LayoutParamValue((Resources.getSystem().displayMetrics.widthPixels - 32.toPx()))
} else LayoutParamValue(240.toPx())

val imageHeight: LayoutParamValue = if (index == 1) {
LayoutParamValue(343.toPx())
} else LayoutParamValue(300.toPx())

LayoutParamValue is my own object that I created in the project. And created Binding Adapter for width and height to pass LayoutParamValue as an input to the layout.

@BindingAdapter("android:layout_width")
@JvmStatic
fun setWidth(view: View, layoutParamValue: LayoutParamValue) {
val params = view.layoutParams
params.width = layoutParamValue.value
view.layoutParams = params
}

Then, we can just pass it through the view in layout as mentioned below in the layout_height ( We are passing imageHeight, which is nothing but returns LayoutParamValue.

<ImageView
android:id="@+id/collection_image"
android:layout_width="match_parent"
android:layout_height="@{data.imageHeight, default = wrap_content}"
android:src="@drawable/ic_launcher_background"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:background="@color/black"
tools:layout_height="150dp"
tools:visibility="visible"
/>

Please see the codebase for more details of implementation in the below mentioned repository.

Please read similar articles.

Thanks for reading through this.

--

--