|
| 1 | +package ezhard.studio.helpers; |
| 2 | + |
| 3 | + |
| 4 | +import android.content.Context; |
| 5 | +import android.content.SharedPreferences; |
| 6 | +import android.content.res.ColorStateList; |
| 7 | +import android.graphics.Color; |
| 8 | +import android.view.View; |
| 9 | +import android.widget.TextView; |
| 10 | + |
| 11 | +import androidx.annotation.NonNull; |
| 12 | +import androidx.core.view.ViewCompat; |
| 13 | + |
| 14 | +import com.google.android.material.snackbar.Snackbar; |
| 15 | + |
| 16 | + |
| 17 | +public class SnackbarHelper { |
| 18 | + |
| 19 | + public interface SnackbarHelperActions { |
| 20 | + void onActionClick(); |
| 21 | + } |
| 22 | + |
| 23 | + |
| 24 | + /** |
| 25 | + * @implNote the default colors are: SUCCESS - Color.GREEN, ERROR - Color.RED, WARNING - Color.YELLOW, INFO - Color.BLUE |
| 26 | + * @param view is for the root view of the snackbar |
| 27 | + * @param type one of: SUCCESS, ERROR, WARNING, or INFO. use setSnackbarTypeColor to adjust the snackbar background color. |
| 28 | + * @param message the message to display at the snackbar |
| 29 | + * @param actionText for the label of the button to display at the snackbar, use null to hide the action button |
| 30 | + * @param actions an interface to use at the action click, pass null to use default action of dismissing the snackbar. every action result eventually in snackbar dismissing itself |
| 31 | + * @param duration , the duration to display the snack bar. its recommended to use Snackbar.LENGTH_SHORT, Snackbar.LENGTH_LONG or Snackbar.LENGTH_INDEFINITE. |
| 32 | + */ |
| 33 | + public static void showSnackbar(@NonNull View view, @NonNull SnackbarType type, @NonNull String message, String actionText, SnackbarHelperActions actions, @NonNull int duration) { |
| 34 | + |
| 35 | + int backgroundColor = getColorForType(type, view.getContext()); |
| 36 | + int textColor = getContrastingTextColor(backgroundColor); |
| 37 | + Snackbar snackbar = Snackbar.make(view, message, duration); |
| 38 | + ViewCompat.setBackgroundTintList(snackbar.getView(), ColorStateList.valueOf(backgroundColor)); // Set background tint |
| 39 | + if(actionText != null) { |
| 40 | + snackbar.setAction(actionText, v -> { |
| 41 | + if (actions != null) { |
| 42 | + actions.onActionClick(); |
| 43 | + } |
| 44 | + snackbar.dismiss(); |
| 45 | + }); |
| 46 | + snackbar.setActionTextColor(textColor); |
| 47 | + } |
| 48 | + |
| 49 | + // Set max lines for the Snackbar text view |
| 50 | + TextView snackbarTextView = snackbar.getView().findViewById(com.google.android.material.R.id.snackbar_text); |
| 51 | + snackbarTextView.setMaxLines(Integer.MAX_VALUE); |
| 52 | + snackbarTextView.setTextColor(textColor); |
| 53 | + |
| 54 | + snackbar.show(); |
| 55 | + |
| 56 | + } |
| 57 | + public static Snackbar buildSnackbar(@NonNull View view, @NonNull SnackbarType type, @NonNull String message, String actionText, SnackbarHelperActions actions, @NonNull int duration) { |
| 58 | + int backgroundColor = getColorForType(type, view.getContext()); |
| 59 | + int textColor = getContrastingTextColor(backgroundColor); |
| 60 | + Snackbar snackbar = Snackbar.make(view, message, duration); |
| 61 | + ViewCompat.setBackgroundTintList(snackbar.getView(), ColorStateList.valueOf(backgroundColor)); // Set background tint |
| 62 | + if(actionText != null) { |
| 63 | + snackbar.setAction(actionText, v -> { |
| 64 | + if (actions != null) { |
| 65 | + actions.onActionClick(); |
| 66 | + } |
| 67 | + snackbar.dismiss(); |
| 68 | + }); |
| 69 | + snackbar.setActionTextColor(textColor); |
| 70 | + } |
| 71 | + |
| 72 | + // Set max lines for the Snackbar text view |
| 73 | + TextView snackbarTextView = snackbar.getView().findViewById(com.google.android.material.R.id.snackbar_text); |
| 74 | + snackbarTextView.setMaxLines(Integer.MAX_VALUE); |
| 75 | + snackbarTextView.setTextColor(textColor); |
| 76 | + |
| 77 | + return snackbar; |
| 78 | + |
| 79 | + } |
| 80 | + |
| 81 | + |
| 82 | + |
| 83 | + private static final String PREF_SNACK_HELPER = "snackbarHelperPref"; |
| 84 | + /** |
| 85 | + * @textColor is automatically set to be contrast color to be as visible as it could |
| 86 | + * @implNote the snackbar background color is controlled by SharedPrefrences, make sure to init the colors at the SplashScreen or any other designated loading scope to make sure the colors are defined even after memory wipe or new device installation |
| 87 | + * @param context is required for sharedPrefrences initialization |
| 88 | + * @param type which snackbar type used to set the color (SUCCESS, ERROR, WARNING, or INFO). |
| 89 | + * @param color the color to set |
| 90 | + */ |
| 91 | + public static void setSnackbarTypeColor(Context context, SnackbarType type, int color){ |
| 92 | + SharedPreferences sharedPreferences = context.getSharedPreferences(PREF_SNACK_HELPER, Context.MODE_PRIVATE); |
| 93 | + SharedPreferences.Editor editor = sharedPreferences.edit(); |
| 94 | + editor.putInt(type.toString(),color); |
| 95 | + editor.apply(); |
| 96 | + } |
| 97 | + /** |
| 98 | + * @textColor is automatically set to be contrast color to be as visible as it could |
| 99 | + * @implNote the snackbar background color is controlled by SharedPrefrences, make sure to init the colors at the SplashScreen or any other designated loading scope to make sure the colors are defined even after memory wipe or new device installation |
| 100 | + * @param context is required for sharedPrefrences initialization |
| 101 | + * @param colorSuccess the color to set for SUCCESS type snackbars |
| 102 | + * @param colorError the color to set for ERROR type snackbars |
| 103 | + * @param colorWarning the color to set for WARNING type snackbars |
| 104 | + * @param colorInfo the color to set for error INFO snackbars |
| 105 | + */ |
| 106 | + public static void setSnackbarTypeColor(Context context, int colorSuccess, int colorError, int colorWarning, int colorInfo){ |
| 107 | + SharedPreferences sharedPreferences = context.getSharedPreferences(PREF_SNACK_HELPER, Context.MODE_PRIVATE); |
| 108 | + SharedPreferences.Editor editor = sharedPreferences.edit(); |
| 109 | + editor.putInt(SnackbarType.SUCCESS.toString(),colorSuccess); |
| 110 | + editor.putInt(SnackbarType.ERROR.toString(),colorError); |
| 111 | + editor.putInt(SnackbarType.WARNING.toString(),colorWarning); |
| 112 | + editor.putInt(SnackbarType.INFO.toString(),colorInfo); |
| 113 | + |
| 114 | + editor.apply(); |
| 115 | + } |
| 116 | + private static int getSnackbarTypeColor(Context context, SnackbarType type){ |
| 117 | + SharedPreferences sharedPreferences = context.getSharedPreferences(PREF_SNACK_HELPER, Context.MODE_PRIVATE); |
| 118 | + int def = -1; |
| 119 | + switch (type){ |
| 120 | + case ERROR: |
| 121 | + def = Color.RED; |
| 122 | + break; |
| 123 | + case WARNING: |
| 124 | + def = Color.YELLOW; |
| 125 | + break; |
| 126 | + case SUCCESS: |
| 127 | + def = Color.GREEN; |
| 128 | + break; |
| 129 | + case INFO: |
| 130 | + def = Color.BLUE; |
| 131 | + break; |
| 132 | + default: |
| 133 | + def = Color.GRAY; |
| 134 | + break; |
| 135 | + } |
| 136 | + return sharedPreferences.getInt(type.toString(),def); |
| 137 | + } |
| 138 | + |
| 139 | + |
| 140 | + |
| 141 | + private static int getColorForType(SnackbarType type, Context context) { |
| 142 | + return getSnackbarTypeColor(context,type); |
| 143 | + } |
| 144 | + |
| 145 | + private static int getContrastingTextColor(int backgroundColor) { |
| 146 | + // Calculate the perceived brightness of the background color |
| 147 | + double brightness = (Color.red(backgroundColor) * 299 + |
| 148 | + Color.green(backgroundColor) * 587 + |
| 149 | + Color.blue(backgroundColor) * 114) / 1000; |
| 150 | + |
| 151 | + // Determine the appropriate text color based on brightness |
| 152 | + return brightness < 128 ? Color.WHITE : Color.BLACK; |
| 153 | + } |
| 154 | + |
| 155 | + public enum SnackbarType { |
| 156 | + ERROR, |
| 157 | + WARNING, |
| 158 | + SUCCESS, |
| 159 | + INFO |
| 160 | + } |
| 161 | +} |
0 commit comments