Firstly, by design, Snackbar should not stay there after clicking an action, so it is not a custom parameter.
Immersed in the code, I was able to find enough seams to do this by reflection.
public static void doNotHideSnackbar(Snackbar snackbar) throws NoSuchFieldException, NoSuchMethodException, IllegalAccessException { final Field sHandler = BaseTransientBottomBar.class.getDeclaredField("sHandler"); sHandler.setAccessible(true); final Method handleMessage = Handler.class.getMethod("handleMessage", Message.class); final Handler originalHandler = (Handler) sHandler.get(snackbar); Handler decoratedHandler = new Handler(Looper.getMainLooper(), new Handler.Callback() { @Override public boolean handleMessage(Message message) { switch (message.what) { case 0: try { handleMessage.invoke(originalHandler, Message.obtain(originalHandler, 0)); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } return true; } return false; } }); sHandler.set(snackbar, decoratedHandler); }
This is tested and works with the support library version 25.3.1 .
Using
final Snackbar snackbar = Snackbar.make(root, "Hello SnackBar!", Snackbar.LENGTH_INDEFINITE).setAction("Undo", new View.OnClickListener() { @Override public void onClick(View v) { Toast.makeText(v.getContext(), "clicked", Toast.LENGTH_SHORT).show(); } }); snackbar.show(); try { doNotHideSnackbar(snackbar); } catch (NoSuchFieldException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); }
Result

BEWARE is not the solution you prefer to stick with if the API can change from version to version. You should better consider implementing a custom Snackbar . But as a quick workaround, you can use this mirrored version.
source share