首页 文章

如何以编程方式获取Android导航栏的高度和宽度?

提问于
浏览
103

Android屏幕底部的黑色导航栏无法轻松移除 . 它从3.0开始就是Android的一部分,作为硬件按钮的替代品 . 这是一张图片:

System Bar

如何获得此UI元素的宽度和高度的大小(以像素为单位)?

15 回答

  • 7

    试试以下代码:

    Resources resources = context.getResources();
    int resourceId = resources.getIdentifier("navigation_bar_height", "dimen", "android");
    if (resourceId > 0) {
        return resources.getDimensionPixelSize(resourceId);
    }
    return 0;
    
  • 0

    底部导航栏的高度为48dp(纵向和横向模式),垂直放置时为42dp .

  • 0

    由Egidijus提出的解决方案,适用于Build.VERSION.SDK_INT> = 17

    但是在我的设备上使用Build.VERSION.SDK_INT <17执行以下语句时,我得到了“NoSuchMethodException”:

    Display.class.getMethod("getRawHeight").invoke(display);
    

    我为这种情况修改了方法getRealScreenSize():

    else if(Build.VERSION.SDK_INT >= 14) 
    {
        View decorView = getActivity().getWindow().getDecorView();
        size.x = decorView.getWidth();
        size.y = decorView.getHeight();
    }
    
  • 88

    我通过将应用程序可用的屏幕大小与实际屏幕大小进行比较来获得导航栏大小我认为当应用程序可用的屏幕尺寸小于实际屏幕尺寸时,存在导航栏 . 然后我计算导航栏的大小 . 此方法适用于API 14及更高版本 .

    public static Point getNavigationBarSize(Context context) {
        Point appUsableSize = getAppUsableScreenSize(context);
        Point realScreenSize = getRealScreenSize(context);
    
        // navigation bar on the side
        if (appUsableSize.x < realScreenSize.x) {
            return new Point(realScreenSize.x - appUsableSize.x, appUsableSize.y);
        }
    
        // navigation bar at the bottom
        if (appUsableSize.y < realScreenSize.y) {
            return new Point(appUsableSize.x, realScreenSize.y - appUsableSize.y);
        }
    
        // navigation bar is not present
        return new Point();
    }
    
    public static Point getAppUsableScreenSize(Context context) {
        WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        Display display = windowManager.getDefaultDisplay();
        Point size = new Point();
        display.getSize(size);
        return size;
    }
    
    public static Point getRealScreenSize(Context context) {
        WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        Display display = windowManager.getDefaultDisplay();
        Point size = new Point();
    
        if (Build.VERSION.SDK_INT >= 17) {
            display.getRealSize(size);
        } else if (Build.VERSION.SDK_INT >= 14) {
            try {
                size.x = (Integer) Display.class.getMethod("getRawWidth").invoke(display);
                size.y = (Integer) Display.class.getMethod("getRawHeight").invoke(display);
            } catch (IllegalAccessException e) {} catch (InvocationTargetException e) {} catch (NoSuchMethodException e) {}
        }
    
        return size;
    }
    
  • 159

    NavigationBar高度因某些设备而异,但也适用于某些设备 . 首先,您必须检查设备是否有导航栏,然后是设备是平板电脑还是非平板电脑(手机),最后您必须查看设备的方向才能获得正确的高度 .

    public int getNavBarHeight(Context c) {
             int result = 0;
             boolean hasMenuKey = ViewConfiguration.get(c).hasPermanentMenuKey();
             boolean hasBackKey = KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_BACK);
    
             if(!hasMenuKey && !hasBackKey) {
                 //The device has a navigation bar
                 Resources resources = c.getResources();
    
                 int orientation = resources.getConfiguration().orientation;
                 int resourceId;
                 if (isTablet(c)){
                     resourceId = resources.getIdentifier(orientation == Configuration.ORIENTATION_PORTRAIT ? "navigation_bar_height" : "navigation_bar_height_landscape", "dimen", "android");
                 }  else {
                     resourceId = resources.getIdentifier(orientation == Configuration.ORIENTATION_PORTRAIT ? "navigation_bar_height" : "navigation_bar_width", "dimen", "android");     
                 }
    
                 if (resourceId > 0) {
                     return resources.getDimensionPixelSize(resourceId);
                 }
             }
             return result;
    } 
    
    
    private boolean isTablet(Context c) {
        return (c.getResources().getConfiguration().screenLayout
                & Configuration.SCREENLAYOUT_SIZE_MASK)
                >= Configuration.SCREENLAYOUT_SIZE_LARGE;
    }
    
  • 25

    实际上平板电脑上的导航栏(至少是Nexus 7)在纵向和横向上有不同的大小,所以这个功能应该如下所示:

    private int getNavigationBarHeight(Context context, int orientation) {
        Resources resources = context.getResources();
    
        int id = resources.getIdentifier(
                orientation == Configuration.ORIENTATION_PORTRAIT ? "navigation_bar_height" : "navigation_bar_height_landscape",
                "dimen", "android");
        if (id > 0) {
            return resources.getDimensionPixelSize(id);
        }
        return 0;
    }
    
  • 1

    我希望这可以帮助你

    public int getStatusBarHeight() {
        int result = 0;
        int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
        if (resourceId > 0) {
            result = getResources().getDimensionPixelSize(resourceId);
        }
        return result;
    }
    
    public int getNavigationBarHeight()
    {
        boolean hasMenuKey = ViewConfiguration.get(context).hasPermanentMenuKey();
        int resourceId = getResources().getIdentifier("navigation_bar_height", "dimen", "android");
        if (resourceId > 0 && !hasMenuKey)
        {
            return getResources().getDimensionPixelSize(resourceId);
        }
        return 0;
    }
    
  • 1

    我认为更正确的答案在这里,因为它也允许你采取甚至切割高度 .

    获取您的根视图,并向其添加setOnApplyWindowInsetsListener(或者您可以从中覆盖onApplyWindowInsets),并从中获取insets.getSystemWindowInsets .

    在我的相机活动中,我添加等于systemWindowInsetBottom的填充到我的底部布局 . 最后,它解决了切断问题 .

    Camera activity insets

    与appcompat它是这样的

    ViewCompat.setOnApplyWindowInsetsListener(mCameraSourcePreview, (v, insets) -> {
        takePictureLayout.setPadding(0,0,0,insets.getSystemWindowInsetBottom());
        return insets.consumeSystemWindowInsets();
    });
    

    没有appcompat,这个:

    mCameraSourcePreview.setOnApplyWindowInsetsListener((v, insets) -> { ... })
    
  • 0

    这是我将paddingRight和paddingBottom添加到View以避开导航栏的代码 . 我在这里结合了一些答案,并与isInMultiWindowMode一起制作了横向定向的特殊条款 . 关键是要阅读navigation_bar_height,还要检查config_showNavigationBar以确保我们应该实际使用高度 .

    以前的解决方案都不适合我 . As of Android 7.0 you have to take Multi Window Mode into consideration. 这打破了将display.realSize与display.size进行比较的实现,因为realSize为您提供整个屏幕的尺寸(两个分割窗口),而尺寸仅为您提供应用程序窗口的尺寸 . 将填充设置为此差异将使整个视图成为填充 .

    /** Adds padding to a view to dodge the navigation bar.
    
        Unfortunately something like this needs to be done since there
        are no attr or dimens value available to get the navigation bar
        height (as of December 2016). */
    public static void addNavigationBarPadding(Activity context, View v) {
        Resources resources = context.getResources();
        if (hasNavigationBar(resources)) {
            int orientation = resources.getConfiguration().orientation;
            int size = getNavigationBarSize(resources);
            switch (orientation) {
            case Configuration.ORIENTATION_LANDSCAPE:
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N &&
                    context.isInMultiWindowMode()) { break; }
                v.setPadding(v.getPaddingLeft(), v.getPaddingTop(),
                             v.getPaddingRight() + size, v.getPaddingBottom());
                break;
            case Configuration.ORIENTATION_PORTRAIT:
                v.setPadding(v.getPaddingLeft(), v.getPaddingTop(),
                             v.getPaddingRight(), v.getPaddingBottom() + size);
                break;
            }
        }
    }
    
    private static int getNavigationBarSize(Resources resources) {
        int resourceId = resources.getIdentifier("navigation_bar_height",
                                                 "dimen", "android");
        return resourceId > 0 ? resources.getDimensionPixelSize(resourceId) : 0;
    }
    
    private static boolean hasNavigationBar(Resources resources) {
        int hasNavBarId = resources.getIdentifier("config_showNavigationBar",
                                                  "bool", "android");
        return hasNavBarId > 0 && resources.getBoolean(hasNavBarId);
    }
    
  • 5

    我解决了所有设备的问题(包括Nexus 5,三星Galaxy Nexus 6边缘,三星S10,三星Note II等) . 我认为这将帮助您处理与设备相关的问题 .

    我在这里添加两种类型的代码,

    Java代码(适用于原生Android):

    import android.content.Context;
    import android.content.res.Resources;
    import android.os.Build;
    import android.util.DisplayMetrics;
    import android.view.Display;
    import android.view.ViewConfiguration;
    import android.view.WindowManager;
    
    public class DeviceSpec {
    
        private int resourceID = -1;
        private Display display = null;
        private DisplayMetrics displayMetrics = null;
        private DisplayMetrics realDisplayMetrics = null;
        private Resources resources = null;
        private WindowManager windowManager = null;
    
        public double GetNavigationBarHeight(Context context) {
            try {
                windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
                display = windowManager.getDefaultDisplay();
                displayMetrics = new DisplayMetrics();
                if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) {
                    realDisplayMetrics = new DisplayMetrics();
                    display.getMetrics(displayMetrics);
                    display.getRealMetrics(realDisplayMetrics);
                    if(displayMetrics.heightPixels != realDisplayMetrics.heightPixels) {
                        resources = context.getResources();
                        return GetNavigationBarSize(context);
                    }
                }
                else {
                    resources = context.getResources();
                    resourceID = resources.getIdentifier("config_showNavigationBar", "bool", "android");
                    if (resourceID > 0 && resources.getBoolean(resourceID))
                        return GetNavigationBarSize(context);
                }
            }
            catch (Exception e){
                e.printStackTrace();
            }
            return 0;
        }
    
        private double GetNavigationBarSize(Context context) {
            resourceID = resources.getIdentifier("navigation_bar_height", "dimen", "android");
            if (resourceID > 0 && ViewConfiguration.get(context).hasPermanentMenuKey())
               return (resources.getDimensionPixelSize(resourceID) / displayMetrics.density);
            return 0;
        }
    }
    

    和C#代码(适用于Xamarin Forms / Android)

    int resourceId = -1;
            IWindowManager windowManager = null;
            Display defaultDisplay = null;
            DisplayMetrics displayMatrics = null;
            DisplayMetrics realMatrics = null;
            Resources resources = null;
    
            public double NavigationBarHeight
            {
                get
                {
                    try
                    {
                        windowManager = Forms.Context.GetSystemService(Context.WindowService).JavaCast<IWindowManager>();
                        defaultDisplay = windowManager.DefaultDisplay;
                        displayMatrics = new DisplayMetrics();
                        if (Build.VERSION.SdkInt >= BuildVersionCodes.JellyBeanMr2)
                        {
                            realMatrics = new DisplayMetrics();
                            defaultDisplay.GetMetrics(displayMatrics);
                            defaultDisplay.GetRealMetrics(realMatrics);
                            if (displayMatrics.HeightPixels != realMatrics.HeightPixels)
                            {
                                resources = Forms.Context.Resources;
                                return GetHeightOfNivigationBar();
                            }
                        }
                        else {
                            resources = Forms.Context.Resources;
                            resourceId = resources.GetIdentifier("config_showNavigationBar", "bool", "android");
                            if (resourceId > 0 && resources.GetBoolean(resourceId))
                                return GetHeightOfNivigationBar();
                        }
                    }
                    catch (Exception e) { }
                    return 0;
                }
            }
    
            private double GetHeightOfNivigationBar()
            {
                resourceId = resources.GetIdentifier("navigation_bar_height", "dimen", "android");
                if (!ViewConfiguration.Get(Forms.Context).HasPermanentMenuKey && resourceId > 0)
                {
                    return resources.GetDimensionPixelSize(resourceId) / displayMatrics.Density;
                }
                return 0;
            }
    
  • 1

    结合@egis和其他人的答案 - 这在各种设备上运行良好,在Pixel EMU,Samsung S6,Sony Z3,Nexus 4上进行测试 . 此代码使用显示尺寸来测试导航栏的可用性,然后使用实际系统导航栏大小(如果存在) .

    /**
     * Calculates the system navigation bar size.
     */
    
    public final class NavigationBarSize {
    
    	private final int systemNavBarHeight;
    	@NonNull
    	private final Point navBarSize;
    
    	public NavigationBarSize(@NonNull Context context) {
    		Resources resources = context.getResources();
    		int displayOrientation = resources.getConfiguration().orientation;
    		final String name;
    		switch (displayOrientation) {
    			case Configuration.ORIENTATION_PORTRAIT:
    				name = "navigation_bar_height";
    				break;
    			default:
    				name = "navigation_bar_height_landscape";
    		}
    		int id = resources.getIdentifier(name, "dimen", "android");
    		systemNavBarHeight = id > 0 ? resources.getDimensionPixelSize(id) : 0;
    		navBarSize = getNavigationBarSize(context);
    	}
    
    	public void adjustBottomPadding(@NonNull View view, @DimenRes int defaultHeight) {
    		int height = 0;
    		if (navBarSize.y > 0) {
    			// the device has a nav bar, get the correct size from the system
    			height = systemNavBarHeight;
    		}
    		if (height == 0) {
    			// fallback to default
    			height = view.getContext().getResources().getDimensionPixelSize(defaultHeight);
    		}
    		view.setPadding(0, 0, 0, height);
    	}
    
    	@NonNull
    	private static Point getNavigationBarSize(@NonNull Context context) {
    		Point appUsableSize = new Point();
    		Point realScreenSize = new Point();
    		WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
    		if (windowManager != null) {
    			Display display = windowManager.getDefaultDisplay();
    			display.getSize(appUsableSize);
    			display.getRealSize(realScreenSize);
    		}
    		return new Point(realScreenSize.x - appUsableSize.x, realScreenSize.y - appUsableSize.y);
    	}
    
    }
    
  • 0

    这是我解决这个问题的方法 . 我制作了一个可隐藏的底栏,需要填充,具体取决于是否有导航栏(电容式,屏幕上或只是前棒棒糖) .


    View

    setPadding(0, 0, 0, Utils.hasNavBar(getContext()) ? 30 : 0);
    

    Utils.java

    public static boolean hasNavBar(Context context) {
        // Kitkat and less shows container above nav bar
        if (android.os.Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT) {
            return false;
        }
        // Emulator
        if (Build.FINGERPRINT.startsWith("generic")) {
            return true;
        }
        boolean hasMenuKey = ViewConfiguration.get(context).hasPermanentMenuKey();
        boolean hasBackKey = KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_BACK);
        boolean hasNoCapacitiveKeys = !hasMenuKey && !hasBackKey;
        Resources resources = context.getResources();
        int id = resources.getIdentifier("config_showNavigationBar", "bool", "android");
        boolean hasOnScreenNavBar = id > 0 && resources.getBoolean(id);
        return hasOnScreenNavBar || hasNoCapacitiveKeys || getNavigationBarHeight(context, true) > 0;
    }
    
    public static int getNavigationBarHeight(Context context, boolean skipRequirement) {
        int resourceId = context.getResources().getIdentifier("navigation_bar_height", "dimen", "android");
        if (resourceId > 0 && (skipRequirement || hasNavBar(context))) {
            return context.getResources().getDimensionPixelSize(resourceId);
        }
        return 0;
    }
    
  • 9

    在我的情况下,我希望有这样的东西:

    Screenshot

    我必须遵循@Mdlc建议的相同内容,但可能稍微简单一些(目标 only > = 21):

    //kotlin
        val windowManager = getSystemService(Context.WINDOW_SERVICE) as WindowManager
        val realSize = Point()
        windowManager.defaultDisplay.getRealSize(realSize);
        val usableRect = Rect()
        windowManager.defaultDisplay.getRectSize(usableRect)
        Toast.makeText(this, "Usable Screen: " + usableRect + " real:"+realSize, Toast.LENGTH_LONG).show()
    
        window.decorView.setPadding(usableRect.left, usableRect.top, realSize.x - usableRect.right, realSize.y - usableRect.bottom)
    

    它也适用于景观:

    landscape

    Edit 上述解决方案在多窗口模式下无法正常工作,其中可用矩形因导航栏而不小,但也因为自定义窗口大小 . 我注意到的一件事是在多窗口中导航栏没有悬停在应用程序上,所以即使没有更改DecorView填充,我们也有正确的行为:

    Multi-window with no changes to decor view padding

    Single-window with no changes to decor view padding

    请注意导航栏如何悬停在这些应用程序底部的区别场景 . 幸运的是,这很容易解决 . 我们可以检查app是否是多窗口 . 下面的代码还包括计算和调整工具栏位置的部分(完整解决方案:https://stackoverflow.com/a/14213035/477790

    // kotlin
        // Let the window flow into where window decorations are
        window.addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN)
        window.addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS)
    
        // calculate where the bottom of the page should end up, considering the navigation bar (back buttons, ...)
        val windowManager = getSystemService(Context.WINDOW_SERVICE) as WindowManager
        val realSize = Point()
        windowManager.defaultDisplay.getRealSize(realSize);
        val usableRect = Rect()
        windowManager.defaultDisplay.getRectSize(usableRect)
        Toast.makeText(this, "Usable Screen: " + usableRect + " real:" + realSize, Toast.LENGTH_LONG).show()
    
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N || !isInMultiWindowMode) {
            window.decorView.setPadding(usableRect.left, usableRect.top, realSize.x - usableRect.right, realSize.y - usableRect.bottom)
            // move toolbar/appbar further down to where it should be and not to overlap with status bar
            val layoutParams = ConstraintLayout.LayoutParams(appBarLayout.layoutParams as ConstraintLayout.LayoutParams)
            layoutParams.topMargin = getSystemSize(Constants.statusBarHeightKey)
            appBarLayout.layoutParams = layoutParams
        }
    

    三星弹出模式的结果:

    enter image description here

  • 31

    用于获取导航栏高度的经过测试的代码(以像素为单位):

    public static int getNavBarHeight(Context c) {
        int resourceId = c.getResources()
                          .getIdentifier("navigation_bar_height", "dimen", "android");
        if (resourceId > 0) {
            return c.getResources().getDimensionPixelSize(resourceId);
        }
        return 0;
    }
    

    用于获取状态栏高度的经过测试的代码(以像素为单位):

    public static int getStatusBarHeight(Context c) {
        int resourceId = c.getResources()
                          .getIdentifier("status_bar_height", "dimen", "android");
        if (resourceId > 0) {
            return c.getResources().getDimensionPixelSize(resourceId);
        }
        return 0;
    }
    

    将像素转换为dp:

    public static int pxToDp(int px) {
        return (int) (px / Resources.getSystem().getDisplayMetrics().density);
    }
    
  • 1

    在三星S8的情况下,上面提供的方法都没有给出适当的导航栏高度,所以我使用了KeyboardHeightProvider keyboard height provider android . 它给了我负值的高度和我的布局定位我在计算中调整了这个值 .

    这是 KeyboardHeightProvider.java

    import android.app.Activity;
    import android.content.res.Configuration;
    import android.graphics.Point;
    import android.graphics.Rect;
    import android.graphics.drawable.ColorDrawable;
    import android.view.Gravity;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewTreeObserver.OnGlobalLayoutListener;
    import android.view.WindowManager.LayoutParams;
    import android.widget.PopupWindow;
    
    
    /**
     * The keyboard height provider, this class uses a PopupWindow
     * to calculate the window height when the floating keyboard is opened and closed. 
     */
    public class KeyboardHeightProvider extends PopupWindow {
    
        /** The tag for logging purposes */
        private final static String TAG = "sample_KeyboardHeightProvider";
    
        /** The keyboard height observer */
        private KeyboardHeightObserver observer;
    
        /** The cached landscape height of the keyboard */
        private int keyboardLandscapeHeight;
    
        /** The cached portrait height of the keyboard */
        private int keyboardPortraitHeight;
    
        /** The view that is used to calculate the keyboard height */
        private View popupView;
    
        /** The parent view */
        private View parentView;
    
        /** The root activity that uses this KeyboardHeightProvider */
        private Activity activity;
    
        /** 
         * Construct a new KeyboardHeightProvider
         * 
         * @param activity The parent activity
         */
        public KeyboardHeightProvider(Activity activity) {
            super(activity);
            this.activity = activity;
    
            LayoutInflater inflator = (LayoutInflater) activity.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
            this.popupView = inflator.inflate(R.layout.popupwindow, null, false);
            setContentView(popupView);
    
            setSoftInputMode(LayoutParams.SOFT_INPUT_ADJUST_RESIZE | LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
            setInputMethodMode(PopupWindow.INPUT_METHOD_NEEDED);
    
            parentView = activity.findViewById(android.R.id.content);
    
            setWidth(0);
            setHeight(LayoutParams.MATCH_PARENT);
    
            popupView.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
    
                    @Override
                    public void onGlobalLayout() {
                        if (popupView != null) {
                            handleOnGlobalLayout();
                        }
                    }
                });
        }
    
        /**
         * Start the KeyboardHeightProvider, this must be called after the onResume of the Activity.
         * PopupWindows are not allowed to be registered before the onResume has finished
         * of the Activity.
         */
        public void start() {
    
            if (!isShowing() && parentView.getWindowToken() != null) {
                setBackgroundDrawable(new ColorDrawable(0));
                showAtLocation(parentView, Gravity.NO_GRAVITY, 0, 0);
            }
        }
    
        /**
         * Close the keyboard height provider, 
         * this provider will not be used anymore.
         */
        public void close() {
            this.observer = null;
            dismiss();
        }
    
        /** 
         * Set the keyboard height observer to this provider. The 
         * observer will be notified when the keyboard height has changed. 
         * For example when the keyboard is opened or closed.
         * 
         * @param observer The observer to be added to this provider.
         */
        public void setKeyboardHeightObserver(KeyboardHeightObserver observer) {
            this.observer = observer;
        }
    
        /**
         * Get the screen orientation
         *
         * @return the screen orientation
         */
        private int getScreenOrientation() {
            return activity.getResources().getConfiguration().orientation;
        }
    
        /**
         * Popup window itself is as big as the window of the Activity. 
         * The keyboard can then be calculated by extracting the popup view bottom 
         * from the activity window height. 
         */
        private void handleOnGlobalLayout() {
    
            Point screenSize = new Point();
            activity.getWindowManager().getDefaultDisplay().getSize(screenSize);
    
            Rect rect = new Rect();
            popupView.getWindowVisibleDisplayFrame(rect);
    
            // REMIND, you may like to change this using the fullscreen size of the phone
            // and also using the status bar and navigation bar heights of the phone to calculate
            // the keyboard height. But this worked fine on a Nexus.
            int orientation = getScreenOrientation();
            int keyboardHeight = screenSize.y - rect.bottom;
    
            if (keyboardHeight == 0) {
                notifyKeyboardHeightChanged(0, orientation);
            }
            else if (orientation == Configuration.ORIENTATION_PORTRAIT) {
                this.keyboardPortraitHeight = keyboardHeight; 
                notifyKeyboardHeightChanged(keyboardPortraitHeight, orientation);
            } 
            else {
                this.keyboardLandscapeHeight = keyboardHeight; 
                notifyKeyboardHeightChanged(keyboardLandscapeHeight, orientation);
            }
        }
    
        /**
         *
         */
        private void notifyKeyboardHeightChanged(int height, int orientation) {
            if (observer != null) {
                observer.onKeyboardHeightChanged(height, orientation);
            }
        }
    
        public interface KeyboardHeightObserver {
            void onKeyboardHeightChanged(int height, int orientation);
        }
    }
    

    popupwindow.xml

    <?xml version="1.0" encoding="utf-8"?>
    <View
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/popuplayout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@android:color/transparent"
        android:orientation="horizontal"/>
    

    用法 MainActivity

    import android.os.Bundle
    import android.support.v7.app.AppCompatActivity
    import kotlinx.android.synthetic.main.activity_main.*
    
    /**
     * Created by nileshdeokar on 22/02/2018.
     */
    class MainActivity : AppCompatActivity() , KeyboardHeightProvider.KeyboardHeightObserver  {
    
        private lateinit var keyboardHeightProvider : KeyboardHeightProvider
    
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_main)
    
            keyboardHeightProvider = KeyboardHeightProvider(this)
            parentActivityView.post { keyboardHeightProvider?.start() }
        }
    
        override fun onKeyboardHeightChanged(height: Int, orientation: Int) {
            // In case of 18:9 - e.g. Samsung S8
            // here you get the height of the navigation bar as negative value when keyboard is closed.
            // and some positive integer when keyboard is opened.
        }
    
        public override fun onPause() {
            super.onPause()
            keyboardHeightProvider?.setKeyboardHeightObserver(null)
        }
    
        public override fun onResume() {
            super.onResume()
            keyboardHeightProvider?.setKeyboardHeightObserver(this)
        }
    
        public override fun onDestroy() {
            super.onDestroy()
            keyboardHeightProvider?.close()
        }
    }
    

    如需进一步的帮助,您可以查看此here的高级用法 .

相关问题