对于我正在开发的应用程序,我想在用户输入后重新加载UI(基本上在对其进行更改后将其完全重置)。我想尝试避免破坏/重新创建活动并使用setContentView()
代替,因为它的速度要快得多。
但是,当我这样做时,我遇到了一个问题:新创建的UI不尊重fitsSystemWindows="true"
,而其中一部分最终落在了android的状态栏后面。
我设法将其归结为该代码示例以进行测试:
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),Button就会显示状态栏:
调用mainContainer.getMeasuredHeight()
检查发生的情况在应用程序的第一次启动时给出了1848px(在1920px高的屏幕上,因此它的高度比整个屏幕低72px,72px是状态的高度bar),但是一旦我再次调用setContentView,mainContainer.getMeasuredHeight()
就会给我1920px。
我在这里遗漏了什么吗?我可以强制mainContainer坚持1848px高度与72px顶部填充,但我宁愿避免像这样丑陋的黑客。
答案 0 :(得分:5)
所以,你想要的是让框架再次向你的根视图发送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));
}
答案 1 :(得分:0)
我遇到了同样的问题。我的解决方案是更改rootView
marginTop
或paddingTop
以手动适应View
。