受信トレイは標準Snackbarを使用せず、オーバーレイウィンドウも使用しません。カスタムビューを使用します。私はAPKを逆コンパイルして、どのようにこの効果を達成したかを検証し、最小限の例を再現しようとしました。その後、カスタムスナックバーを表示し、却下するこれらのメソッドを作成
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#323232"
android:paddingLeft="10dp"
android:paddingRight="10dp">
<TextView
android:id="@+id/text"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center_vertical"
android:text="Marked done"
android:textColor="@android:color/white"/>
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:background="@android:color/transparent"
android:gravity="center_vertical"
android:minWidth="48dp"
android:text="undo"
android:textAllCaps="true"
android:textColor="#a1c2fa"/>
</LinearLayout>
:
:
private View customSnackbar;
private void showCustomSnackbar(final Context context) {
customSnackbar = LayoutInflater.from(context).inflate(R.layout.custom_snackbar, null, false);
customSnackbar.findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//action implementation
}
});
WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
lp.width = WindowManager.LayoutParams.MATCH_PARENT;
lp.format = PixelFormat.TRANSLUCENT;
lp.gravity = Gravity.BOTTOM;
lp.flags = WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH |
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
customSnackbar.setLayoutParams(lp);
WindowManager windowManager = (WindowManager) context.getSystemService(WINDOW_SERVICE);
if (windowManager != null) {
windowManager.addView(customSnackbar, customSnackbar.getLayoutParams());
Point m = new Point();
windowManager.getDefaultDisplay().getSize(m);
int childMeasureSpecWidth = ViewGroup.getChildMeasureSpec(View.MeasureSpec.makeMeasureSpec(m.x, View.MeasureSpec.EXACTLY), 0, lp.width);
int childMeasureSpecHeight = ViewGroup.getChildMeasureSpec(View.MeasureSpec.makeMeasureSpec(m.y, View.MeasureSpec.EXACTLY), 0, lp.height);
customSnackbar.measure(childMeasureSpecWidth, childMeasureSpecHeight);
customSnackbar.setTranslationY(customSnackbar.getMeasuredHeight());
customSnackbar.animate()
.setDuration(300)
.translationX(0.0f)
.translationY(0.0f);
}
}
private void dismissCustomSnackbar(final Context context) {
customSnackbar.animate()
.setDuration(300)
.translationX(0.0f)
.translationY(customSnackbar.getMeasuredHeight())
.withEndAction(new Runnable() {
@Override
public void run() {
WindowManager windowManager = (WindowManager) context.getSystemService(WINDOW_SERVICE);
if (windowManager != null) {
windowManager.removeView(customSnackbar);
}
}
});
}
これは結果を得ている
まず第一には、新しいレイアウトcustom_snackbar.xmlを作成します
デフォルトでは6であるsnackbarのビューの標高を大きな数値に設定しようとしましたが、これは役に立ちません。私は5000まで高度を試しました! – Erik
私はオーバーレイウィンドウ(例えば、8.0より前の 'TYPE_SYSTEM_OVERLAY'、8.0+では' TYPE_APPLICATION_OVERLAY'など)を使用しなければならないと仮定します。私はこのシナリオをテストすることができないので私はGoogleの受信トレイを使用しません。しかし、Inboxが8.0以上でこの動作をしなくても、7.1以降では、[オーバーレイはIMEを8.0+にオーバーレイできないため]オーバーレイになる可能性が非常に高くなります(https://developer.android.com /about/versions/oreo/android-8.0-changes.html#cwt)。 – CommonsWare
'elevations'はアプリケーションレイアウト内でのみ影響を与えます。私は、異なるコンテキストでスネークバーを作成するといくつかのトリックがあるかもしれないと思う。 – sakiM