不能使用半透明操作/导航条

我在新的 安卓奇巧(4.4)和 windowSoftInputMode="adjustResize"中遇到了半透明的操作栏/导航栏的问题。

通常,改变 输入模式adjustResize,应用程序应该调整自己的大小时,键盘显示,但在这里它不会!如果我删除透明效果的行,调整大小是有效的。

因此,如果键盘是可见的,我的 ListView是在它下面,我不能访问最后几个项目(只有隐藏键盘手动)。

返回文章页面

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="XYZ"
android:versionCode="23"
android:versionName="0.1" >


<uses-sdk
android:minSdkVersion="9"
android:targetSdkVersion="19" />


<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/Theme.XYZStyle" >
<activity
android:name="XYZ"
android:label="@string/app_name"
android:windowSoftInputMode="adjustResize" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />


<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>


</manifest>

Value-v19/styles.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>


<style name="Theme.XYZStyle" parent="@style/Theme.AppCompat.Light">
<item name="android:windowTranslucentStatus">true</item>
<item name="android:windowTranslucentNavigation">true</item>
</style>


</resources>

Xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >


<ListView
android:id="@+id/listView_contacts"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
android:divider="@null"
android:dividerHeight="0dp"
android:drawSelectorOnTop="true"
android:fastScrollAlwaysVisible="true"
android:fastScrollEnabled="true"
android:paddingBottom="@dimen/navigationbar__height" >
</ListView>


</RelativeLayout>

有什么办法吗?

117595 次浏览

您缺少以下属性:

android:fitsSystemWindows="true"

碎片.xml 布局的根 RelativeLayout中。

更新:

去年,克里斯•贝恩(Chris Bane)发表了一篇有趣的演讲,详细解释了这种方法的工作原理:

Https://www.youtube.com/watch?v=_mgdmvro3ie

有一个相关的故障报告 给你。我已经找到了一个解决方案,通过有限的测试,似乎可以做到这一点,没有任何影响。使用下面的逻辑添加根 ViewGroup的自定义实现(我几乎总是在使用 FrameLayout,所以这就是我所测试的)。然后,使用这个自定义布局代替根布局,并确保设置了 android:fitsSystemWindows="true"。然后你可以在布局之后随时调用 getInsets()(例如,添加一个 OnPreDrawListener)来调整你布局的其余部分,以适应系统的插入。

import android.content.Context;
import android.graphics.Rect;
import android.os.Build;
import android.util.AttributeSet;
import android.widget.FrameLayout;
import org.jetbrains.annotations.NotNull;


/**
* @author Kevin
*         Date Created: 3/7/14
*
* https://code.google.com/p/android/issues/detail?id=63777
*
* When using a translucent status bar on API 19+, the window will not
* resize to make room for input methods (i.e.
* {@link android.view.WindowManager.LayoutParams#SOFT_INPUT_ADJUST_RESIZE} and
* {@link android.view.WindowManager.LayoutParams#SOFT_INPUT_ADJUST_PAN} are
* ignored).
*
* To work around this; override {@link #fitSystemWindows(android.graphics.Rect)},
* capture and override the system insets, and then call through to FrameLayout's
* implementation.
*
* For reasons yet unknown, modifying the bottom inset causes this workaround to
* fail. Modifying the top, left, and right insets works as expected.
*/
public final class CustomInsetsFrameLayout extends FrameLayout {
private int[] mInsets = new int[4];


public CustomInsetsFrameLayout(Context context) {
super(context);
}


public CustomInsetsFrameLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}


public CustomInsetsFrameLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}


public final int[] getInsets() {
return mInsets;
}


@Override
protected final boolean fitSystemWindows(@NotNull Rect insets) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
// Intentionally do not modify the bottom inset. For some reason,
// if the bottom inset is modified, window resizing stops working.
// TODO: Figure out why.


mInsets[0] = insets.left;
mInsets[1] = insets.top;
mInsets[2] = insets.right;


insets.left = 0;
insets.top = 0;
insets.right = 0;
}


return super.fitSystemWindows(insets);
}
}

由于不推荐使用 fitSystemWindows,请参考下面的答案来完成解决方案。

我也有同样的问题, 我的活动有一个 ScrollView 作为根视图,半透明状态栏被激活,当键盘显示时,它没有正确调整大小... ... 因此屏幕没有滚动隐藏输入视图。

解决方案: 将所有内容(布局和活动逻辑)移动到一个新的片段中。 然后改变活动只包括这个片段。现在一切工作正常!

这是活动的布局:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"


android:id="@+id/contentView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true" />

@ kcoppock 的回答确实很有帮助,但是 FitSystemWindows 在 API 级别20中不被推荐

因此,从 API 20(KITKAT _ WatCH)开始,您应该覆盖 ApplicyWindowInsets

@Override
public final WindowInsets onApplyWindowInsets(WindowInsets insets) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT_WATCH) {
return super.onApplyWindowInsets(insets.replaceSystemWindowInsets(0, 0, 0,
insets.getSystemWindowInsetBottom()));
} else {
return insets;
}
}

基于约瑟夫 · 约翰逊在 当软键盘可见时,如何在全屏模式下调整布局中的变通方法

在你的活动中,在 setContentView()之后在 onCreate()中调用这个。

AndroidBug5497Workaround.assistActivity(this);

computeUsableHeight()中用 return r.bottom;代替 return (r.bottom - r.top);略有不同

由于某种原因,我必须将我的活动 fitsSystemWindows属性设置为 false

这个变通方法救了我。它对我很有效。希望可以帮助你。

实现类别为:

public class AndroidBug5497Workaround {


// For more information, see https://code.google.com/p/android/issues/detail?id=5497
// To use this class, simply invoke assistActivity() on an Activity that already has its content view set.


public static void assistActivity (Activity activity) {
new AndroidBug5497Workaround(activity);
}


private View mChildOfContent;
private int usableHeightPrevious;
private FrameLayout.LayoutParams frameLayoutParams;


private AndroidBug5497Workaround(Activity activity) {
FrameLayout content = (FrameLayout) activity.findViewById(android.R.id.content);
mChildOfContent = content.getChildAt(0);
mChildOfContent.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
public void onGlobalLayout() {
possiblyResizeChildOfContent();
}
});
frameLayoutParams = (FrameLayout.LayoutParams) mChildOfContent.getLayoutParams();
}


private void possiblyResizeChildOfContent() {
int usableHeightNow = computeUsableHeight();
if (usableHeightNow != usableHeightPrevious) {
int usableHeightSansKeyboard = mChildOfContent.getRootView().getHeight();
int heightDifference = usableHeightSansKeyboard - usableHeightNow;
if (heightDifference > (usableHeightSansKeyboard/4)) {
// keyboard probably just became visible
frameLayoutParams.height = usableHeightSansKeyboard - heightDifference;
} else {
// keyboard probably just became hidden
frameLayoutParams.height = usableHeightSansKeyboard;
}
mChildOfContent.requestLayout();
usableHeightPrevious = usableHeightNow;
}
}


private int computeUsableHeight() {
Rect r = new Rect();
mChildOfContent.getWindowVisibleDisplayFrame(r);
return r.bottom;
}


}

Java 注意内存泄漏。需要以下代码

getViewTreeObserver().removeOnGlobalLayoutListener(listener);

我的示例使用 RxJava,它在活动的生命周期中的 onPuse ()时自动调用 RemoveOnGlobalLayoutListener ()

public class MyActivity extends RxAppCompatActivity {
// ...


protected void onStart(){
super.onStart();


TRSoftKeyboardVisibility
.changes(this) // activity
.compose(this.<TRSoftKeyboardVisibility.ChangeEvent>bindUntilEvent(ActivityEvent.PAUSE))
.subscribe(keyboardEvent -> {
FrameLayout content = (FrameLayout) findViewById(android.R.id.content);
View firstChildView = content.getChildAt(0);
firstChildView.getLayoutParams().height = keyboardEvent.viewHeight();
firstChildView.requestLayout();


// keyboardEvent.isVisible      = keyboard visible or not
// keyboardEvent.keyboardHeight = keyboard height
// keyboardEvent.viewHeight     = fullWindowHeight - keyboardHeight
});
//...
}










package commonlib.rxjava.keyboard;


import android.app.Activity;
import android.view.View;
import android.widget.FrameLayout;
import kr.ohlab.android.util.Assert;
import rx.Observable;


public class TRSoftKeyboardVisibility {


public static Observable<ChangeEvent> changes(Activity activity) {
Assert.notNull(activity, "activity == null");
FrameLayout content = (FrameLayout) activity.findViewById(android.R.id.content);
View childOfContent = content.getChildAt(0);
return Observable.create(
new TRSoftKeyboardVisibilityEventOnSubscribe(childOfContent));
}


public static final class ChangeEvent {
private final int keyboardHeight;
private final boolean visible;
private final int viewHeight;


public static ChangeEvent create(boolean visible, int keyboardHeight,
int windowDisplayHeight) {
return new ChangeEvent(visible, keyboardHeight, windowDisplayHeight);
}


private ChangeEvent(boolean visible, int keyboardHeight, int viewHeight) {
this.keyboardHeight = keyboardHeight;
this.visible = visible;
this.viewHeight = viewHeight;
}


public int keyboardHeight() {
return keyboardHeight;
}


public boolean isVisible() {
return this.visible;
}


public int viewHeight() {
return viewHeight;
}


@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof ChangeEvent)) return false;


ChangeEvent that = (ChangeEvent) o;


if (keyboardHeight != that.keyboardHeight) return false;
if (visible != that.visible) return false;
return viewHeight == that.viewHeight;
}


@Override
public int hashCode() {
int result = keyboardHeight;
result = 31 * result + (visible ? 1 : 0);
result = 31 * result + viewHeight;
return result;
}


@Override
public String toString() {
return "ChangeEvent{" +
"keyboardHeight=" + keyboardHeight +
", visible=" + visible +
", viewHeight=" + viewHeight +
'}';
}
}
}




package commonlib.rxjava.keyboard;


import android.graphics.Rect;
import android.view.View;
import android.view.ViewTreeObserver;
import kr.ohlab.android.util.Assert;
import rx.Observable;
import rx.Subscriber;
import rx.android.MainThreadSubscription;
import timber.log.Timber;


public class TRSoftKeyboardVisibilityEventOnSubscribe
implements Observable.OnSubscribe<TRSoftKeyboardVisibility.ChangeEvent> {
private final View mTopView;
private int mLastVisibleDecorViewHeight;
private final Rect mWindowVisibleDisplayFrame = new Rect();


public TRSoftKeyboardVisibilityEventOnSubscribe(View topView) {
mTopView = topView;
}


private int computeWindowFrameHeight() {
mTopView.getWindowVisibleDisplayFrame(mWindowVisibleDisplayFrame);
return (mWindowVisibleDisplayFrame.bottom - mWindowVisibleDisplayFrame.top);
}


private TRSoftKeyboardVisibility.ChangeEvent checkKeyboardVisibility() {
int windowFrameHeightNow = computeWindowFrameHeight();
TRSoftKeyboardVisibility.ChangeEvent event = null;
if (windowFrameHeightNow != mLastVisibleDecorViewHeight) {
int mTopViewHeight = mTopView.getHeight();
int heightDiff = mTopViewHeight - windowFrameHeightNow;
Timber.e("XXX heightDiff=" + heightDiff);
if (heightDiff > (mTopViewHeight / 4)) {
event = TRSoftKeyboardVisibility.ChangeEvent.create(true, heightDiff, windowFrameHeightNow);
} else {
event = TRSoftKeyboardVisibility.ChangeEvent.create(false, 0, windowFrameHeightNow);
}
mLastVisibleDecorViewHeight = windowFrameHeightNow;
return event;
}


return null;
}


public void call(final Subscriber<? super TRSoftKeyboardVisibility.ChangeEvent> subscriber) {
Assert.checkUiThread();


final ViewTreeObserver.OnGlobalLayoutListener listener =
new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
TRSoftKeyboardVisibility.ChangeEvent event = checkKeyboardVisibility();
if( event == null)
return;
if (!subscriber.isUnsubscribed()) {
subscriber.onNext(event);
}
}
};


mTopView.getViewTreeObserver().addOnGlobalLayoutListener(listener);


subscriber.add(new MainThreadSubscription() {
@Override
protected void onUnsubscribe() {
mTopView.getViewTreeObserver().removeOnGlobalLayoutListener(listener);
}
});
}
}

我遇到了点麻烦。

我将 windowDrawsSystemBarBackground 设置为“ true”,我的应用程序应该显示在状态栏下。

这是我的活动主题。

<item name="android:windowTranslucentStatus" tools:targetApi="KITKAT">false</item>
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
<item name="android:windowTranslucentNavigation">true</item>
<item name="android:statusBarColor">@android:color/transparent</item>

我得到了 建树的博客的帮助。 你可以读代码,但像我一样发短信。 我添加了一些代码。

public final class ZeroInsetsFrameLayout extends FrameLayout {
private int[] mInsets = new int[4];


public ZeroInsetsFrameLayout(Context context) {
super(context);
}


public ZeroInsetsFrameLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}


public ZeroInsetsFrameLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}


public final int[] getInsets() {
return mInsets;
}


@Override
public WindowInsets computeSystemWindowInsets(WindowInsets in, Rect outLocalInsets) {
outLocalInsets.left = 0;
outLocalInsets.top = 0;
outLocalInsets.right = 0;


return super.computeSystemWindowInsets(in, outLocalInsets);
}


@Override
protected final boolean fitSystemWindows(@NonNull Rect insets) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
// Intentionally do not modify the bottom inset. For some reason,
// if the bottom inset is modified, window resizing stops working.
// TODO: Figure out why.


mInsets[0] = insets.left;
mInsets[1] = insets.top;
mInsets[2] = insets.right;


insets.left = 0;
insets.top = 0;
insets.right = 0;
}


return super.fitSystemWindows(insets);
}
}

这是我的片段布局。

<com.dhna.widget.ZeroInsetsFrameLayout 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:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:background="@color/white">


<!-- your xml code -->


</ZeroInsetsFrameLayout>

我希望这对你有帮助。 祝你好运!

这个工作为我有半透明的状态栏和调整大小在碎片:

  1. 制作一个定制的 RelativeLayout,如@Victor91和@kcoppock 所说。

  2. 使用 CustomRelativeLayout 作为片段的父布局。

  3. 用 android 声明主题: windowTranslucentStatus = true

  4. 容器 Activity 必须在 Manifest 中用 Android: windowSoftInputMode = “调整大小”并使用声明的 主题

  5. 请在片段根布局上使用 fitsSystemWindows!

    public class CustomRelativeLayout extends RelativeLayout {
    
    
    private int[] mInsets = new int[4];
    
    
    public CustomRelativeLayout(Context context) {
    super(context);
    }
    
    
    public CustomRelativeLayout(Context context, AttributeSet attrs) {
    super(context, attrs);
    }
    
    
    public CustomRelativeLayout(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    }
    
    
    public CustomRelativeLayout(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
    super(context, attrs, defStyleAttr, defStyleRes);
    }
    
    
    @Override
    public final WindowInsets onApplyWindowInsets(WindowInsets insets) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT_WATCH) {
    mInsets[0] = insets.getSystemWindowInsetLeft();
    mInsets[1] = insets.getSystemWindowInsetTop();
    mInsets[2] = insets.getSystemWindowInsetRight();
    return super.onApplyWindowInsets(insets.replaceSystemWindowInsets(0, 0, 0,
    insets.getSystemWindowInsetBottom()));
    } else {
    return insets;
    }
    }
    }
    

Then in xml,

<com.blah.blah.CustomRelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
</com.blah.blah.CustomRelativeLayout>

最佳实践允许用户在显示键盘时滚动内容。 因此,为了添加这个功能,您需要将根布局放在 ScrollView中,并使用 windowSoftInputMode="adjustResize"活动方法。

但是如果您希望在 < code > < item name = “ android: windowTranslucentStatus”> true 中使用此功能 Android 5上的标志内容不会滚动,而且会与键盘重叠。

要解决这个问题,请检查这个 回答

如果您想自定义 insets,并且您的目标是 API 级别 > = 21,那么您可以在不必创建自定义视图组的情况下完成此任务。默认情况下,只需设置 fitsSystemWindows填充就会应用到容器视图,这可能是您不希望看到的。

版本检查内置在这个方法中,只有设备 > = 21将执行 lambda 中的代码。科特林的例子:

ViewCompat.setOnApplyWindowInsetsListener(container) { view, insets ->
insets.replaceSystemWindowInsets(0, 0, 0, insets.systemWindowInsetBottom).apply {
ViewCompat.onApplyWindowInsets(view, this)
}
}

确保您的布局仍然设置 fitsSystemWindows标志,否则窗口插入侦听器将不会被调用。

<FrameLayout
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
/>

这些信息来源很有帮助:

Https://medium.com/google-developers/why-would-i-want-to-fitssystemwindows-4e26d9ce1eec Https://medium.com/@azizbekian/windowinsets-24e241d4afb9

它不应该工作与半透明状态栏,该设置强制窗口进入全屏模式,不与调整大小。

可以使用调整盘或使用 fitsSystemWindows 属性。不过,我建议读读这个功能,它有明显的副作用:

Https://medium.com/google-developers/why-would-i-want-to-fitssystemwindows-4e26d9ce1eec

  • 在我在所有论坛上研究过之后。这些方法都不能帮助我们找到答案。幸运的是,当我尝试这样做的时候。它帮助我解决问题

XML

<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<!-- Your xml -->
</RelativeLayout>

活动

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView("Your Activity");
setAdjustScreen();


}

创造性功能

protected void setAdjustScreen(){
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
/*android:windowSoftInputMode="adjustPan|adjustResize"*/
}

终于在主流音乐中添加了一些代码行

 <activity
android:name="Your Activity"
android:windowSoftInputMode="adjustPan|adjustResize"
android:screenOrientation="portrait"></activity>

我也遇到过同样的问题,我已经用坐标布局解决了

Activity.main.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
android:layout_height="match_parent" android:layout_width="match_parent"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android">




<android.support.design.widget.AppBarLayout
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:theme="@style/AppTheme.AppBarOverlay">


<android.support.v7.widget.Toolbar
android:layout_height="?attr/actionBarSize"
android:layout_width="match_parent"
app:popupTheme="@style/AppTheme.PopupOverlay"
android:background="?attr/colorPrimary"
android:id="@+id/toolbar"/>


</android.support.design.widget.AppBarLayout>


<include layout="@layout/content_main2"/>


</android.support.design.widget.CoordinatorLayout>

Content _ main2. xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">




<android.support.v7.widget.RecyclerView
android:layout_height="match_parent"
android:layout_width="match_parent"
android:layout_marginTop="30dp"
android:layout_marginBottom="30dp"
app:layout_scrollFlags="scroll|exitUntilCollapsed"
android:id="@+id/post_msg_recyclerview">
</android.support.v7.widget.RecyclerView>


<EditText
android:layout_width="match_parent"
android:layout_height="50dp"
app:layout_constraintBottom_toBottomOf="parent"
android:background="@color/colorPrimary"




/>


</android.support.constraint.ConstraintLayout>

MainActivity.java

现在添加这一行线性 LayoutManager.setStackFromEnd (true) ;

 LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
linearLayoutManager.setStackFromEnd(true);
recyclerView.setLayoutManager(linearLayoutManager);
Adapter adapter1=new Adapter(arrayList);
recyclerView.setAdapter(adapter1);
<androidx.constraintlayout.widget.ConstraintLayout
android:fitsSystemWindows="true">


<androidx.coordinatorlayout.widget.CoordinatorLayout>
<com.google.android.material.appbar.AppBarLayout>


<com.google.android.material.appbar.CollapsingToolbarLayout/>


</com.google.android.material.appbar.AppBarLayout>


<androidx.core.widget.NestedScrollView>
<Editext/>
<androidx.core.widget.NestedScrollView/>


</androidx.coordinatorlayout.widget.CoordinatorLayout>


</androidx.constraintlayout.widget.ConstraintLayout>

首先在根布局中添加这个。

android:fitsSystemWindows="true"

当您使用这种方法时,您有责任确保应用程序 UI 的关键部分(例如,地图应用程序中的内置控件)最终不会被系统栏覆盖。这会让你的应用程序无法使用。在大多数情况下,可以通过将 android: fitsSystemWindows 属性添加到 XML 布局文件(设置为 true)来处理这个问题。这会调整父 ViewGroup 的填充,为系统窗口留出空间。这对于大多数应用程序来说已经足够了。

但是,在某些情况下,您可能需要修改默认填充,以获得所需的应用程序布局。要直接操作内容相对于系统栏的布局方式(系统栏占据一个称为窗口“内容插入”的空间) ,覆盖 fitSystemWindows (Rect 插入)。当窗口的内容插入发生更改时,视图层次结构将调用 fitSystemWindows ()方法,以允许窗口相应地调整其内容。通过重写此方法,您可以按照自己的意愿处理插入(以及应用程序的布局)。

Https://developer.android.com/training/system-ui/status#behind

如果你想成为一个窗口安装大师,请观看来自 Android 开发者的视频。 Https://www.youtube.com/watch?v=_mgdmvro3ie

由于 replaceSystemWindowInsetssystemWindowInsetBottom方法的弃用而导致的 @ Victor Rendina回答的小更新。

先决条件:

  • 空气污染指数 > = 21
  • 至少是 implementation 'androidx.core:core-ktx:1.5.0-alpha02'

科特林分机:

fun View?.fitSystemWindowsAndAdjustResize() = this?.let { view ->
ViewCompat.setOnApplyWindowInsetsListener(view) { v, insets ->
view.fitsSystemWindows = true
val bottom = insets.getInsets(WindowInsetsCompat.Type.ime()).bottom


WindowInsetsCompat
.Builder()
.setInsets(
WindowInsetsCompat.Type.systemBars(),
Insets.of(0, 0, 0, bottom)
)
.build()
.apply {
ViewCompat.onApplyWindowInsets(v, this)
}
}
}

用法:

rootView.fitSystemWindowsAndAdjustResize()

其中 rootView实际上是布局的根视图:)

注: 如果扩展对根视图不起作用(我在使用 ABC0作为 ABC1时遇到了这种情况) ,则用 FrameLayout包装整个布局,使 FrameLayout成为新的根视图

这是我用的 在 xml 文件的主视图中,您将添加以下内容

android:animateLayoutChanges="true"

然后在“ onCreate”函数中,在每件事情得到状态栏大小之前,你会得到这样的状态栏大小

int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resourceId > 0)
{
status_bar=getResources().getDimensionPixelSize(resourceId);
}

然后最后在“ onCreate”中添加这个来更新大小

        main_view= findViewById(R.id.the_main);
main_view.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener()
{
@Override
public void onGlobalLayout()
{
Rect r = new Rect();
View view = getWindow().getDecorView();
view.getWindowVisibleDisplayFrame(r);
if (Math.abs(old_size - r.height()) > 100)
{
ViewGroup.LayoutParams params = main_view.getLayoutParams();
params.height = r.height()+ status_bar ;
main_view.setLayoutParams(params);
}
old_size = r.height();
}
});

我不知道为什么,但选项调整大小不工作的全屏幕。我刚刚添加了 title Bar 和 works (android: theme = “@style/AppTheme”)。我在代码中使用的 Insted”getSupportActionBar ()。隐藏() ;

 <activity
android:name=".ChatActivity"
android:launchMode="singleInstance"
android:screenOrientation="portrait"
android:windowSoftInputMode="adjustResize"
android:theme="@style/AppTheme"
/>