Show Android SnackBar above keyboard?

Is it possible to show the Android Snackbar above the keyboard (as in Y coordinate, not layering)? The Snackbar currently gets hidden if the keyboard is shown, which is an undesirable behavior.

23705 次浏览

Set

android:windowSoftInputMode="adjustResize"

in the AndroidManifest.xml for the activity containing your snackbar

If you nest your layout in a ScrollView, the snackbar will appear on top of the keyboard. This is because the view will resize to take up only the available space above the keyboard. And, of course, your View will also be scroll-able if necessary at any time, while the keyboard is shown or not.

This is my code for snackbar and its working similarly+ as you need relativeLayout is the parent main layout id i have passed.

        snackbar=snackbar.make(relativeLayout,"Image is Saved to "+Savedfile.getPath().toString(),Snackbar.LENGTH_INDEFINITE)
.setAction("OK", new OnClickListener() {
@Override
public void onClick(View v) {
snackbar.dismiss();
snackbar=null;


System.gc();
finish();
}
});
snackbar.show();

You can hide the keyboard when the Snackbar is shown.

InputMethodManager imm = (InputMethodManager)activity.getSystemService(Activity.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(view.getWindowToken(), 0);

The following works:

  1. Ensure the activity/fragment from which you are calling the Snackbar contains a ScrolView.
  2. Ensure you set the snackbar view to findViewById(android.R.id.content):

Snackbar.make(getActivity().findViewById(android.R.id.content), "hello world").show();

  1. OR, if you want to be able to swipe away the Snackbar, ensure the ScrolView is nested within a CoordinatorLayout.

Snackbar.make(getActivity().findViewById(android.R.id.my_coordinator_layout), "hello world").show();

I have solved the issue like this:

Create a class:

public class ShowSnackBar {
public static void show(Context context, String message, View view) {
InputMethodManager imm = (InputMethodManager) context.getSystemService(Activity.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
Snackbar.make(view, message, Snackbar.LENGTH_SHORT).show();
}
}

You can access this class from any activity in the application

Usage:

ShowSnackBar.show(LoginOtpActivity.this,"Please enter Email ID /Mobile",linear_container);

this is my code , there is no need to set view from method , you can get it from DecoreView :

public static void longSnack(final String text) {
hideKeyboard();
Snackbar snackbar = Snackbar.make(context.getWindow().getDecorView(), text, Snackbar.LENGTH_LONG);
snackbar.show();
}


public static void shortSnack(final String text) {
hideKeyboard();
Snackbar snackbar = Snackbar.make(context.getWindow().getDecorView(), text, Snackbar.LENGTH_SHORT);
snackbar.show();
}


private static void hideKeyboard() {
InputMethodManager inputMethodManager = (InputMethodManager)context.getSystemService(Activity.INPUT_METHOD_SERVICE);
if (inputMethodManager != null) {
inputMethodManager.hideSoftInputFromWindow(context.getWindow().getDecorView().getWindowToken(), 0);
}
}

I had this problem myself and was able to solve it quite easily.

Previously, I had set android:fitsSystemWindows="true".

The solution is to set it to false, or just delete that line. Now, you don't need to hide the keyboard to get your desired result.

Here is my layout file for reference:

<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/relative"
android:orientation="vertical"
android:fitsSystemWindows="false">
<LinearLayout
android:id="@+id/linear"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/default_gap"
android:orientation="horizontal">
<EditText
android:id="@+id/input"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="15dp"
android:layout_weight="1"
android:hint="@string/input_a_number"
android:ems="10"
android:imeOptions="actionDone|flagNoPersonalizedLearning"
android:inputType="numberSigned|numberDecimal"
android:maxLines="1"
android:maxLength="30"
android:singleLine="true"
android:importantForAutofill="no"
android:focusable="true"
android:focusableInTouchMode="true"
android:focusedByDefault="true"
tools:ignore="LabelFor"
tools:targetApi="o" />
<Spinner
android:id="@+id/spinner"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:minWidth="180dp"
android:layout_marginEnd="@dimen/default_gap"
android:layout_weight="1" />
</LinearLayout>


<ListView
android:id="@+id/listview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/linear"
android:layout_marginEnd="10dp"
android:layout_marginStart="5dp"
android:layout_marginTop="5dp" />


<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/fab"
android:visibility="gone"
android:layout_alignParentBottom="true"
android:layout_alignParentEnd="true"
android:layout_margin="16dp"
app:elevation="4dp"
app:srcCompat="@drawable/jade"
app:backgroundTint="@color/jade_fab"
android:layout_gravity="bottom|end"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />


</androidx.coordinatorlayout.widget.CoordinatorLayout>

Add snack bar in this way, place a Container @ content argument, with padding from bottom of Keyboard size.




SnackBar snackBar =
SnackBar(
content: Container(
padding: EdgeInsets.only( bottom:
MediaQuery.of(context).viewInsets.bottom),
child: Text('Please add your quote !!!')),
duration: Duration(milliseconds:  800),
);
// Add this given line in function body where to show snack bar
ScaffoldMessenger.of(context.showSnackBar(snackBar);

Jetpack Compose:

Based on androidx.compose.foundation:foundation-layout documentation

  1. Add android:windowSoftInputMode="adjustResize" to your AndroidManifest.xml

  2. Call WindowCompat.setDecorFitsSystemWindows(window, false) in your Activity onCreate method

  3. Finally, add WindowInsets.ime.asPaddingValues() to your Snackbar's modifier like this:

    Snackbar(
modifier = modifier
.padding(vertical = 32.dp, horizontal = 16.dp)
.padding(WindowInsets.ime.asPaddingValues()),
...
)

enter image description here