fitsSystemWindows="true" не работает после вызова setContentView()

Для приложения, которое я разрабатываю, я хотел перезагрузить пользовательский интерфейс после ввода данных пользователем (по сути, полностью сбрасывая его после того, как в него были внесены изменения). Я хотел бы попытаться избежать уничтожения / воссоздания деятельности и использования setContentView() вместо этого, потому что это намного быстрее.

Однако, когда я делаю это, у меня возникает проблема: вновь созданный пользовательский интерфейс не уважает fitsSystemWindows="true" и часть этого заканчивается позади строки состояния андроида.

Мне удалось свести это к тому примеру кода, чтобы проверить это:

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);
    }
}

Когда я загружаю приложение, я получаю ожидаемый макет, то есть простую кнопку в верхней части экрана, прямо под строкой состояния:

Однако, как только я нажимаю кнопку, которая вызывает setContentView во второй раз (показывая тот же XML), кнопка оказывается за строкой состояния:

призвание mainContainer.getMeasuredHeight() проверка того, что происходит, дает мне 1848 пикселей при первом запуске приложения (на экране высотой 1920 пикселей, поэтому его высота на 72 пикселя меньше, чем на весь экран, 72 пикселя - это высота строки состояния), но как только я снова вызываю setContentView mainContainer.getMeasuredHeight() дает мне 1920px.

Я что-то здесь упускаю? Я мог бы заставить mainContainer придерживаться высоты 1848px с верхним отступом 72px, но я бы предпочел избежать такого уродливого хака, как этот.

2 ответа

Итак, вы хотите попросить структуру отправить еще раз WindowInsets в ваш корневой вид. Это именно то, что ViewCompat.requestApplyInsets(View) Сделаю:

Спросите, что новая отправка View.onApplyWindowInsets(WindowInsets) быть выполненным. Это возвращается к View.requestFitSystemWindows() где доступно.

Применение только одной строки должно решить все ваши проблемы:



    public void reloadUI() {
        setContentView(R.layout.layout);
        // `R.id.mainContainer` is the id of the root view in `R.layout.layout`
        ViewCompat.requestApplyInsets(findViewById(R.id.mainContainer));
    }


У меня такая же проблема. Мое решение состоит в том, чтобы изменить rootViewmarginTop или же paddingTop адаптироваться к View вручную.

Другие вопросы по тегам