Setting the width and height by itself will not trigger a layout of the widget. Either a layout pass is already scheduled which will be true if your code is in the onCreate()
method of an activity or there is another piece of code that triggers the layout. For example, if, in addition to setting the width and height, you also set the scale type the method to set the scale type will trigger the layout.
From ImageView.java
/**
* Controls how the image should be resized or moved to match the size
* of this ImageView.
*
* @param scaleType The desired scaling mode.
*
* @attr ref android.R.styleable#ImageView_scaleType
*/
public void setScaleType(ScaleType scaleType) {
if (scaleType == null) {
throw new NullPointerException();
}
if (mScaleType != scaleType) {
mScaleType = scaleType;
requestLayout();
invalidate();
}
}
As you can see, setting the scale type triggers a request for a layout if the scale type has changed.
Here is a small app to test the concepts. In a nutshell, the size can be changed prior to the initial layout (in onCreate()), after the initial layout completed (in onGlobalLayout()) or via some user action (in onClick()). See the comments in the code regarding how the app works.
MainActivity.java
public class MainActivity extends AppCompatActivity implements View.OnClickListener,
ViewTreeObserver.OnGlobalLayoutListener {
private View theView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
theView = findViewById(R.id.view);
// If the following line execute, it is before the initial layout pass,
// so the new width will take effect during that layout pass.
// Comment and uncomment this line to see the effect.
// theView.getLayoutParams().width *= 2;
// Uncomment the following to change size after the initial layout.
theView.getViewTreeObserver().addOnGlobalLayoutListener(this);
}
@Override
public void onClick(View v) {
// theView.getLayoutParams().width *= 2;
// The layout pass has completed since the button is available to click.
// Here setting the width without requesting a layout will not change the
// width of the widget - at least not until there is a layout pass requested.
// Comment and uncomment this line to see the effect.
// theView.requestLayout();
}
@Override
public void onGlobalLayout() {
theView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
theView.getLayoutParams().width *= 2;
theView.requestLayout();
}
}
activity_main.xml
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<View
android:id="@+id/viewStatic"
android:layout_width="100dp"
android:layout_height="50dp"
android:layout_marginBottom="16dp"
android:background="@android:color/holo_red_light"
android:text="Hello World!"
app:layout_constraintBottom_toTopOf="@+id/view"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_chainStyle="packed" />
<View
android:id="@+id/view"
android:layout_width="100dp"
android:layout_height="50dp"
android:background="@android:color/holo_red_light"
android:text="Hello World!"
app:layout_constraintBottom_toTopOf="@+id/button"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/viewStatic" />
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:text="Make larger"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/view" />
</androidx.constraintlayout.widget.ConstraintLayout>