For an app I'm developing I wanted to reload the UI after a user input (basically resetting it completely after they made changes to it). I wanted to try avoiding destroying/recreating the activity and use setContentView()
instead because it's a lot faster.
However when I do that I'm having an issue: the newly created UI doesn't respect the fitsSystemWindows="true"
and part of it ends up behind the android's status bar.
I managed to boil it down to that code example to test it :
layout.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/mainContainer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:orientation="vertical">
<Button
android:text="Button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/button" />
</LinearLayout>
MainActivity.java
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout);
Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
reloadUI();
}
});
}
public void reloadUI() {
setContentView(R.layout.layout);
}
}
When I load the app, I get the expected layout, that is a simple button on top of the screen, right below the status bar:
However, once I click the button which calls setContentView
a second time (showing the same XML), the Button gets behind the status bar:
Calling mainContainer.getMeasuredHeight()
to check what happens gives me 1848px on the first start of the app (on a screen that is 1920px tall, so its height is 72px less than the whole screen, 72px being the height of the status bar), but once I call setContentView again the mainContainer.getMeasuredHeight()
gives me 1920px.
Am I missing something here? I could force the mainContainer to stick to a 1848px height with a 72px top padding, but I'd prefer to avoid an ugly hack like this.
I had the same problem. My solution is to change the
rootView
marginTop
orpaddingTop
to adapt to theView
manually.