web-dev-qa-db-ja.com

Androidナビゲーションバーの高さと幅をプログラムで取得するにはどうすればよいですか?

画面の下部にある黒いナビゲーションバーは、Androidでは簡単に取り外しできません。 3.0以降、ハードウェアボタンの代わりとしてAndroidの一部となっています。これが写真です:

System Bar

このUI要素の幅と高さをピクセル単位で取得するにはどうすればよいですか?

107
Kevik

以下のコードを試してください:

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

アプリで使用可能な画面サイズと実際の画面サイズを比較して、ナビゲーションバーのサイズを取得します。アプリで使用可能な画面サイズが実際の画面サイズよりも小さい場合、ナビゲーションバーが表示されると想定しています。次に、ナビゲーションバーのサイズを計算します。このメソッドは、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;
}
92
Egis

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;
}
32
Mdlc

実際、タブレットのナビゲーションバー(少なくとも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;
}
25
Danylo Volokh

より正確な答えはここにあると思います。

ルートビューを取得し、それに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) -> { ... })
9
John

これがあなたのお役に立てば幸いです

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

これは、ビューにpaddingRightとpaddingBottomを追加してナビゲーションバーをかわすためのコードです。ここでいくつかの答えを組み合わせて、isInMultiWindowModeと一緒に横向きの特別な句を作成しました。キーはnavigation_bar_heightを読むことですが、config_showNavigationBarも確認してください実際に高さを使用する必要があります。

以前のソリューションはどれもうまくいきませんでした。 Android 7.0以降、マルチウィンドウモードを考慮する必要があります。これは、比較を実装に違反しますdisplay.realSizewithdisplay.sizerealSizeは、画面全体(両方の分割ウィンドウ)およびsizeは、アプリウィンドウのサイズのみを提供します。この差にパディングを設定すると、ビュー全体がパディングのままになります。

/** 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
marcus

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();
}
1
Chebyr

すべてのデバイス(Nexus 5、Samsung Galaxy Nexus 6 Edge +、Samsung S10、Samsung Note IIなど)でこの問題を解決しました。これは、デバイスに依存する問題の処理に役立つと思います。

ここでは、2種類のコードを追加しています。

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
Sino Raj

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

}
1
Meanman

下部のナビゲーションバーの高さは48dp(ポートレートモードとランドスケープモードの両方)で、バーが垂直に配置されると42dpです。

1
Aritra Roy

Samsung 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 の高度な使用法をご覧ください。

0
Nilesh Deokar

私の場合、次のようなものが必要でした:

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上記の解決策は、ナビゲーションバーだけでなくカスタムウィンドウのために使用可能な長方形が小さくないマルチウィンドウモードでは正しく動作しませんサイズ。私が気づいた1つのことは、マルチウィンドウではナビゲーションバーがアプリ上にホバーしていないため、DecorViewのパディングに変更がなくても正しい動作があることです:

Multi-window with no changes to decor view paddingSingle-window with no changes to decor view padding

これらのシナリオでは、ナビゲーションバーがアプリの下部に移動する方法の違いに注意してください。幸いなことに、これは簡単に修正できます。アプリがマルチウィンドウかどうかを確認できます。以下のコードには、ツールバーの位置を計算および調整する部分も含まれています(完全なソリューション: https://stackoverflow.com/a/14213035/47779

    // 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
    }

Samsungポップアップモードでの結果:

enter image description here

0
Bakhshi

これは私がこれをどのように解決したかです。ナビゲーションバーがあるかどうかに応じてパディングが必要な非表示の下部バーを作成しました(容量性、画面上、または単にLollipopの前)。


表示

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

tils.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;
}
0
Jonas Borggren

ナビゲーションバーの高さを取得するためのテスト済みコード(ピクセル単位):

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