Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

虚拟按键开启关闭导致底部导航栏显示问题 #36

Open
MissBin opened this issue Jun 29, 2021 · 4 comments
Open

虚拟按键开启关闭导致底部导航栏显示问题 #36

MissBin opened this issue Jun 29, 2021 · 4 comments

Comments

@MissBin
Copy link

MissBin commented Jun 29, 2021

手机开启虚拟按键底部正常显示 关闭虚拟按键底部还是有虚拟按键的高度
1624960502767

@h4091
Copy link

h4091 commented Jul 11, 2021

你需要修改activity_root_view_parent的padding,可以参考下面的代码
NavigationBarHelper.java

package com.h4091.utils;

import android.app.Activity;
import android.content.Context;
import android.os.Build;
import android.view.View;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.graphics.Insets;
import androidx.core.view.OnApplyWindowInsetsListener;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;

public class NavigationBarHelper {

    public static void setNavigationBarListener(@NonNull Activity activity,
        @Nullable NavigationStateListener listener) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT_WATCH) {
            Context context = activity.getApplicationContext();
            ViewCompat.setOnApplyWindowInsetsListener(activity.getWindow().getDecorView(),
                new OnApplyWindowInsetsListener() {
                    @Override
                    public WindowInsetsCompat onApplyWindowInsets(View v, WindowInsetsCompat insets) {
                        /** 虚拟导航栏或虚拟导航线高度(使用AndroidAutoSize会使该值发生变化) */
                        int height = AndroidUtil.getNavigationBarHeight(context);
                        boolean isShowing = false;
                        Insets temp = null;
                        if (insets != null) {
                            temp = Insets.of(
                                insets.getSystemWindowInsetLeft(),
                                insets.getSystemWindowInsetTop(),
                                insets.getSystemWindowInsetRight(),
                                insets.getSystemWindowInsetBottom()
                            );
                            // or
//                            Insets statusInsets = insets.getInsets(WindowInsetsCompat.Type.statusBars());
//                            Insets navInsets = insets.getInsets(WindowInsetsCompat.Type.navigationBars());
                            isShowing = height - temp.bottom >= 0;
                        }
                        if (listener != null) {
                            listener.onStateChanged(temp, isShowing);
                        }
                        return ViewCompat.onApplyWindowInsets(v, insets);
                    }
                });
        }
    }

    /**
     * 获取虚拟导航栏或虚拟导航线高度
     */
    public static int getNavigationBarHeight(@NonNull Context context) {
        Resources resources = context.getApplicationContext().getResources();
        int resourceId = resources.getIdentifier("navigation_bar_height", "dimen", "android");
        return resources.getDimensionPixelSize(resourceId);
    }

    public interface NavigationStateListener {
        /**
         *
         * @param insets
         * @param isNavShowing 是否显示虚拟导航栏或虚拟导航线
         */
        void onStateChanged(Insets insets, boolean isNavShowing);
    }
}

BaseActivity.java

package com.h4091.base.view;

import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;

import androidx.annotation.ColorRes;
import androidx.annotation.Nullable;
import androidx.annotation.StringRes;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.ContextCompat;
import androidx.core.graphics.Insets;

import com.h4091.R;
import com.h4091.BuildConfig;
import com.h4091.utils.NavigationBarHelper;
import com.zackratos.ultimatebarx.ultimatebarx.UltimateBarX;

import me.jessyan.autosize.internal.CustomAdapt;

public abstract class BaseActivity extends AppCompatActivity implements CustomAdapt {

    protected boolean isShowNavigationBar;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        this.setStatusBar();
        this.setNavigationBar();
    }

    @Override
    public boolean isBaseOnWidth() {
        return false;
    }

    @Override
    public float getSizeInDp() {
        // 使用AndroidManifest中声明的设计图尺寸
        return 667;
    }

    /**
     * 设置状态栏
     */
    protected void setStatusBar() {
        UltimateBarX.with(this)
            .fitWindow(isFitStatusBar())
            .colorRes(getStatusBarColor())
            .light(isLight())
            .applyStatusBar();
    }

    /**
     * 是否侵入状态栏,默认true
     * @return true:不侵入,false:侵入
     */
    protected boolean isFitStatusBar() {
        return true;
    }

    /**
     * 状态栏颜色,默认R.color.white
     */
    @ColorRes
    protected int getStatusBarColor() {
        return R.color.white;
    }

    /**
     * 是否light模式,默认true
     * @return true: light模式
     */
    protected boolean isLight() {
        return true;
    }

    @ColorRes
    protected int getNavigationBarColor() {
        return R.color.blue;
    }

    public boolean isShowNavigationBar() {
        return isShowNavigationBar;
    }

    /**
     * 设置导航栏
     */
    protected void setNavigationBar() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            getWindow().setNavigationBarColor(ContextCompat.getColor(this, getNavigationBarColor()));
        }
        NavigationBarHelper.setNavigationBarListener(this, new NavigationBarHelper.NavigationStateListener() {
            @Override
            public void onStateChanged(Insets insets, boolean isNavShowing) {
                isShowNavigationBar = isNavShowing;
                getWindow().getDecorView()
                    .findViewWithTag("activity_root_view_parent")
                    .setPadding(insets.left,
                        isFitStatusBar() ? insets.top : 0,
                        insets.right,
                        insets.bottom);
            }
        });
    }
}

最后要说的是:

getSystemWindowInsetLeft()

方法已经被标记为deprecated,你也可以使用

Insets statusInsets = insets.getInsets(WindowInsetsCompat.Type.statusBars());
Insets navInsets = insets.getInsets(WindowInsetsCompat.Type.navigationBars());

这两个来实现,具体取决于你。

@lihuiqiang123
Copy link

我在realme手机也遇到类似问题,可以先获取Navigation的默认配置,然后设置fitWindow = false ,然后覆盖默认配置,在配置StateBar,可以解决底部导航白条的问题。代码如下:

val config = UltimateBarX.getNavigationBarConfig(this).fitWindow(false)
UltimateBarX.get(this).config(config).applyNavigationBar()
UltimateBarX.with(this)
   .light(true)
   .applyStatusBar()

@Zackratos
Copy link
Owner

你是在当前 Activity 打开的状态下直接关闭导航栏吗

@Zackratos
Copy link
Owner

如果你只需要设置状态栏而不需要设置导航栏的话,更新到 0.8.0 版本,使用 statusBarOnly 方法替换 statusBar 方法可以彻底解决这个问题
@h4091 @MissBin @lihuiqiang123

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants