私が使用して参照することができ、ライブラリにパッケージ化され、githubのにアップロードし、プログラムを終了した後フィットになります
プロジェクト住所:github.com/smarxpan/No ...
画面サイズと市場フルスクリーンのプログラムの多種多様。
ここで私は、キビを説明するために、チャートを使用します。
両方の画面を総称フリンジ画面と呼ぶことができるが、より小さい右側前髪のために、業界は、一般的に水滴画面や未亡人のピークと呼びます。説明を簡単にするため、以下、「前髪画面」「フリンジ領域」全2画面分のビューに同じ時間を参照するために呼ばれます。
私たちは、画面の適応について話すとき、私たちは何をについて話しています
- 長い画面アダプテーション
- コンテンツ前髪を防ぎます
最初のポイントは、すべてのアプリケーションは、以下に対応する適応を必要とすることです声明最大长宽比
そして第二の点は、アプリケーション自体が全画面表示を必要とするか、浸漬ステータスバーを必要としないように構成されている使用していない場合。
第二フィッティングポイントを必要とする用途のために、我々は、干渉縞の位置と幅と高さを取得する必要があり、表示内容を回避することができます。
免責最大アスペクト比
16の元の一般的な画面のアスペクト比:9、フルスクリーン携帯電話の画面のアスペクト比は、あなたが適合しない場合、それは次のようになりますが、多くのことを増加しました。
未使用領域の黒い部分。
適応モード
適応方法は2つあります。
-
targetSdkVersionバージョンはAPI 24とオーバーに設定されています
以下のため、この操作意志
<application>
タグが暗黙的にプロパティを追加するにはandroid:resizeableActivity="true"
、プロパティには、後の処理について詳細に説明します。 -
で
<application>
[プロパティ]タブを増やします:android:resizeableActivity="false"
ノードを追加するときに
meta-data
ラベル:<!-- Render on full screen up to screen aspect ratio of 2.4 --> <!-- Use a letterbox on screens larger than 2.4 --> <meta-data android:name="android.max_aspect" android:value="2.4" /> 复制代码
理由
resizeableActivityプロパティ:ここでは、Androidの知識に来ます。
アンドロイド7.0(APIレベル24)以降のアプリケーションでは、アンドロイド:trueにresizeableActivityプロパティのデフォルト値は、(適応モード1に対応します)。このプロパティは、マルチウィンドウ表示を制御して、現在のアプリケーションを決定またはアクティビティは、複数のウィンドウをサポートしています。
リスト内<activity>
または<application>
プロパティノードを設定し、マルチウィンドウ表示を有効または無効にします:
android:resizeableActivity=["true" | "false"]
复制代码
このプロパティがtrueに設定されている場合は、アクティビティやフリーフォームモード画面を分割するように活性化されます。このプロパティをfalseに設定すると、活動はマルチウィンドウモードをサポートしていません。値がfalseであり、ユーザは、マルチウィンドウモードでの活動を開始しようとすると、フルスクリーンの意志活動。
モード2は、適応が画面の最大アスペクト比を設定し、これは正式なオファーを設定する方法です。
あなたは最大のアスペクト比の必須を設定した場合android:resizeableActivity="false"
。そうでなければ、効果なしの最大アスペクト比。
劉画面アダプテーション
Android9.0以上の適応
AndroidのP(9.0)は、道の公式形状の画面適応を開始します。
新しいクラスによってDisplayCutout、非機能領域の位置及び形状を決定することができ、これらの領域は、コンテンツを表示すべきではありません。画面とその位置のリセス領域が存在するかどうかを決定するために、getDisplayCutout()関数を使用します。
-
新しいウィンドウレイアウトのプロパティは、アプリケーションがデバイスノッチ画面の周りのコンテンツのために配置することができる作るlayoutInDisplayCutoutMode。あなたは、次のいずれかの値に、このプロパティを使用することができます。
LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT
LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER
デフォルト値は
LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT
表示せずに、フリンジエリア、あなたが値を設定する必要がありますLAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
-
AndroidのPのを実行している任意のデバイスまたはエミュレーター上のギャップを次のように画面をシミュレートすることができます。
- 開発者向けのオプションを有効にします。
- 開発者向けオプション画面では、描画部までスクロールし、切り欠き部との表示をシミュレートを選択します。
- 画面のノッチサイズを選択します。
-
アダプタ参照:
// 延伸显示区域到刘海 WindowManager.LayoutParams lp = window.getAttributes(); lp.layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES; window.setAttributes(lp); // 设置页面全屏显示 final View decorView = window.getDecorView(); decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE); 复制代码
表示領域は、フリンジコードに延在し、例えばアプリケーション活性またはスタイルを変更することによって達成することができます。
<?xml version="1.0" encoding="utf-8"?> <resources> <style name="AppTheme" parent="xxx"> <item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item> </style> </resources> 复制代码
AndroidのOアダプタ
Googleの公式のAndroid Pの適応方式に打ち上げられた原因、AndroidのOデバイスよう、様々なメーカーが独自の実装を持っています。
私はここで主に適応Huawei社、キビ、OPPO、3は完全なソリューションを与えています。インビボ、インビボように前髪がAPIをスクリーニングず、無駄なフリンジ領域がAPIを表示するように設定されているので、何のアダプターかどうかを決定します。
Huawei社のAndroid Oアダプタデバイス
オプション1:
-
詳細な説明は次のとおりです。
<meta-data android:name="android.notch_support" android:value="true"/> 复制代码
-
アプリケーションの特別な処理を有効にするには右に、それはすべてのページが、アプリケーションシステムは、特別なポートレートシーンをダウンまたは横画面のシーンにしないことを意味します:
<application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:testOnly="false" android:supportsRtl="true" android:theme="@style/AppTheme"> <meta-data android:name="android.notch_support" android:value="true"/> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/> </intent-filter> </activity> 复制代码
-
あなたがプロパティシステムの活動は、特別な治療を行うことはありませんし、単一のページのための前髪画面適応できることを意味発効のための活動、:
<application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:testOnly="false" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/> </intent-filter> </activity> <activity android:name=".LandscapeFullScreenActivity" android:screenOrientation="sensor"> </activity> <activity android:name=".FullScreenActivity"> <meta-data android:name="android.notch_support" android:value="true"/> </activity> </application> 复制代码
オプションII
右を有効にするアプリケーションの特別な治療に、それはすべてのページ、アプリケーションシステムは、特別なポートレートシーンダウンや風景のシーンを作成しないことを意味します
マイNotchScreenTool使用中には、独自の勧告を改正、活動のために必要であれば、第2の方式です。
-
Huawei社フリンジ前髪エリアの設定ウィンドウ画面の携帯電話の使用
/*刘海屏全屏显示FLAG*/ public static final int FLAG_NOTCH_SUPPORT=0x00010000; /** * 设置应用窗口在华为刘海屏手机使用刘海区 * @param window 应用页面window对象 */ public static void setFullScreenWindowLayoutInDisplayCutout(Window window) { if (window == null) { return; } WindowManager.LayoutParams layoutParams = window.getAttributes(); try { Class layoutParamsExCls = Class.forName("com.huawei.android.view.LayoutParamsEx"); Constructor con=layoutParamsExCls.getConstructor(LayoutParams.class); Object layoutParamsExObj=con.newInstance(layoutParams); Method method=layoutParamsExCls.getMethod("addHwFlags", int.class); method.invoke(layoutParamsExObj, FLAG_NOTCH_SUPPORT); } catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException |InstantiationException | InvocationTargetException e) { Log.e("test", "hw add notch screen flag api error"); } catch (Exception e) { Log.e("test", "other Exception"); } } 复制代码
-
クリアHuawei社の前髪が旗を選別追加、回復アプリケーションは、前髪の表示領域を使用していません
/** * 设置应用窗口在华为刘海屏手机使用刘海区 * @param window 应用页面window对象 */ public static void setNotFullScreenWindowLayoutInDisplayCutout (Window window) { if (window == null) { return; } WindowManager.LayoutParams layoutParams = window.getAttributes(); try { Class layoutParamsExCls = Class.forName("com.huawei.android.view.LayoutParamsEx"); Constructor con=layoutParamsExCls.getConstructor(LayoutParams.class); Object layoutParamsExObj=con.newInstance(layoutParams); Method method=layoutParamsExCls.getMethod("clearHwFlags", int.class); method.invoke(layoutParamsExObj, FLAG_NOTCH_SUPPORT); } catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException |InstantiationException | InvocationTargetException e) { Log.e("test", "hw clear notch screen flag api error"); } catch (Exception e) { Log.e("test", "other Exception"); } } 复制代码
ミレーのAndroid Oアダプタデバイス
-
前髪が画面かどうかを確認
private static boolean isNotch() { try { Method getInt = Class.forName("android.os.SystemProperties").getMethod("getInt", String.class, int.class); int notch = (int) getInt.invoke(null, "ro.miui.notch", 0); return notch == 1; } catch (Throwable ignore) { } return false; } 复制代码
-
フリンジに表示領域を設定します
@Override public void setDisplayInNotch(Activity activity) { int flag = 0x00000100 | 0x00000200 | 0x00000400; try { Method method = Window.class.getMethod("addExtraFlags", int.class); method.invoke(activity.getWindow(), flag); } catch (Exception ignore) { } } 复制代码
-
前髪の幅と高さを取得します。
public static int getNotchHeight(Context context) { int resourceId = context.getResources().getIdentifier("notch_height", "dimen", "android"); if (resourceId > 0) { return context.getResources().getDimensionPixelSize(resourceId); } return 0; } public static int getNotchWidth(Context context) { int resourceId = context.getResources().getIdentifier("notch_width", "dimen", "android"); if (resourceId > 0) { return context.getResources().getDimensionPixelSize(resourceId); } return 0; } 复制代码
OppoAndroid Oアダプタ装置
-
前髪が画面かどうかを確認
@Override public boolean hasNotch(Activity activity) { boolean ret = false; try { ret = activity.getPackageManager().hasSystemFeature("com.oppo.feature.screen.heteromorphism"); } catch (Throwable ignore) { } return ret; } 复制代码
-
前髪の左右の角座標取得
/** * 获取刘海的坐标 * <p> * 属性形如:[ro.oppo.screen.heteromorphism]: [378,0:702,80] * <p> * 获取到的值为378,0:702,80 * <p> * <p> * (378,0)是刘海区域左上角的坐标 * <p> * (702,80)是刘海区域右下角的坐标 */ private static String getScreenValue() { String value = ""; Class<?> cls; try { cls = Class.forName("android.os.SystemProperties"); Method get = cls.getMethod("get", String.class); Object object = cls.newInstance(); value = (String) get.invoke(object, "ro.oppo.screen.heteromorphism"); } catch (Throwable ignore) { } return value; } 复制代码
親しい同僚のAndroid Oモデルは、単にデフォルトの表示になりますフルスクリーンアプリケーションを設定し、フリンジ領域に表示を設定する必要はありません。
したがって、親しい同僚のモデルが適応しなければなりません。
適応概要
:上記の特徴によれば、私はそれが依存するライブラリとなっソートされますNotchScreenTool
使用するのは簡単です:
// 支持显示到刘海区域
NotchScreenManager.getInstance().setDisplayInNotch(this);
// 获取刘海屏信息
NotchScreenManager.getInstance().getNotchInfo(this, new INotchScreen.NotchScreenCallback() {
@Override
public void onResult(INotchScreen.NotchScreenInfo notchScreenInfo) {
Log.i(TAG, "Is this screen notch? " + notchScreenInfo.hasNotch);
if (notchScreenInfo.hasNotch) {
for (Rect rect : notchScreenInfo.notchRects) {
Log.i(TAG, "notch screen Rect = " + rect.toShortString());
}
}
}
});
复制代码
重要なコントロールを避けるために、あなたのアプリケーションのために必要な情報を取得した後フリンジエリア。
詳細については、私はプロジェクトのコードを参照してください。
参考リンク
限られた画面のサポートを宣言する:最大アスペクト比を宣言する
ます。https://juejin.im/post/5cf635846fb9a07f0c466ea7で再現