Google Inbox如何在鍵盤上顯示快餐欄(覆蓋,分層)?這不是默認行爲,我已經使用基本協調器佈局,鍵盤打開和小吃棒進行了測試:默認行爲是在後面顯示小鍵盤鍵盤。對於這個問題,SO上有很多答案:'我如何在以上的快捷鍵上顯示鍵盤',但我還沒有找到如何重現Google自己的Inbox應用程序快餐欄行爲。
你能告訴我如何做到這一點嗎?
Google Inbox如何在鍵盤上顯示快餐欄(覆蓋,分層)?這不是默認行爲,我已經使用基本協調器佈局,鍵盤打開和小吃棒進行了測試:默認行爲是在後面顯示小鍵盤鍵盤。對於這個問題,SO上有很多答案:'我如何在以上的快捷鍵上顯示鍵盤',但我還沒有找到如何重現Google自己的Inbox應用程序快餐欄行爲。
你能告訴我如何做到這一點嗎?
收件箱不使用標準Snackbar,也不使用疊加窗口,它使用自定義視圖。我反編譯APK以驗證它們如何實現這種效果,並試圖重現一個最小的例子。
,首先創建一個新的佈局custom_snackbar.xml:
<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);
}
}
});
}
這是得到的結果:
我不會'WindowManager'太多......但爲什麼這能夠出現在IME上?我認爲Android 8.0中有關'WindowManager'添加窗口的更改應該可以防止這種情況發生。無論如何,好的工作! – CommonsWare
Android 8.0的限制似乎只適用於'TYPE_APPLICATION_OVERLAY'類型。在這個例子中,視圖具有缺省類型'TYPE_APPLICATION'。 –
謝謝,這真棒。我會稍後在我的應用程序中嘗試此操作,並在發生任何怪癖或邊緣情況時向我們報告。我也猜想有可能以常規的方式建立一個'Snackbar',然後,如果鍵盤是打開的,而不是定期顯示它,使用這種方法將它顯示在鍵盤前面。這種自定義小吃棒行爲可以適應不同的鍵盤情況。 – Erik
我嘗試將快餐欄的視圖的高度(默認爲6)設置爲大數字,但這不起作用。我嘗試了高達5000的高程! – Erik
我假設他們必須使用覆蓋窗口(例如,8.0+以前的'TYPE_SYSTEM_OVERLAY','8.0的TYPE_APPLICATION_OVERLAY')。我不使用Google收件箱,因此我無法測試這種情況。但是,如果Inbox在8.0+上沒有這種行爲,但是在7.1和更舊的版本上,那麼它很可能是覆蓋圖,因爲[覆蓋圖不能覆蓋8.0+上的IME](https://developer.android.com /about/versions/oreo/android-8.0-changes.html#cwt)。 – CommonsWare
'高程'隻影響你的應用程序佈局。我認爲創建具有不同上下文的Snakebar可能會有一些技巧。 – sakiM