Does View.getHeight/getWidth include padding?

1 week ago 10
ARTICLE AD BOX

I was under the impression that the value returned by View.getWidth() includes padding in it. I don't think I'm hallucinating things - a common line of code that Android developers write is something like myView.run { width - (paddingLeft + paddingRight) }, whose goal is to get the width of a View without the padding (the "base width", so to speak).

This is something I personally have done at my previous jobs, and is also corroborated by numerous other examples online (ref: SourceGraph code search).

However, after trying to use this pattern today, I was shocked to see that the value returned View.getWidth() does not include padding in it. To illustrate, I ran the following experiment:

activity_main.xml:

<HorizontalScrollView android:id="@+id/container" android:background="#ff00c0cb" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="8dp" android:clipToPadding="false" android:clipChildren="false" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintBottom_toBottomOf="parent"> <LinearLayout android:id="@+id/inner" android:background="#ffffc0cb" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal" /> </HorizontalScrollView>

MainActivity.kt:

myList.forEach { s -> val squareItemView = SquareItemView(this) // irrelevant boilerplate omitted innerContents.addView(squareItemView) innerContents.post { val baseWidth = innerContents.run { width - (paddingLeft + paddingRight) } Log.i( "TAG", "innerContents.measuredWidth=${innerContents.measuredWidth}, " + "innerContents.width=${innerContents.width}, " + "baseWidth=${baseWidth}, " + "innerContents.paddingLeft=${innerContents.paddingLeft}" ) Log.i("TAG", "will add 10px px on either side") innerContents.apply { setPadding(paddingLeft + 10, paddingTop, paddingRight + 10, paddingBottom) } } }

Here is the log output:

23:42:49.923 I innerContents.measuredWidth=693, innerContents.width=693, baseWidth=693, innerContents.paddingLeft=0 23:42:49.923 I will add 10px px on either side 23:42:49.924 I innerContents.measuredWidth=693, innerContents.width=693, baseWidth=673, innerContents.paddingLeft=10 23:42:49.924 I will add 10px px on either side 23:42:49.924 I innerContents.measuredWidth=693, innerContents.width=693, baseWidth=653, innerContents.paddingLeft=20 23:42:49.924 I will add 10px px on either side

In this demo, notice that each time we add 10px of padding to left and right:

the plain getMeasuredWidth and getWidth numbers are identical and remain constant the "base width" calculation decreases by the amount of the padding

This result is at odds with what we expect to see. Like I said, I don't remember this being the case a few months (weeks?) ago, but apparently it is so. Did Google change this behaviour on the library level or even the OS level? What's going on? :(

Read Entire Article