package cgeo.geocaching.activity; import cgeo.geocaching.CgeoApplication; import cgeo.geocaching.MainActivity; import cgeo.geocaching.R; import cgeo.geocaching.settings.Settings; import android.app.Activity; import android.content.Context; import android.content.Intent; import android.support.annotation.NonNull; import android.support.annotation.StringRes; import android.support.v4.app.ActivityCompat; import android.support.v4.app.NavUtils; import android.support.v4.app.TaskStackBuilder; import android.support.v7.app.ActionBar; import android.support.v7.app.ActionBarActivity; import android.view.ContextThemeWrapper; import android.view.Gravity; import android.view.Window; import android.view.WindowManager; import android.view.WindowManager.LayoutParams; import android.widget.EditText; import android.widget.Toast; import org.apache.commons.lang3.StringUtils; public final class ActivityMixin { private ActivityMixin() { // utility class } public static void setTitle(final Activity activity, final CharSequence text) { if (StringUtils.isBlank(text)) { return; } if (activity instanceof ActionBarActivity) { final ActionBar actionBar = ((ActionBarActivity) activity).getSupportActionBar(); if (actionBar != null) { actionBar.setTitle(text); } } } public static void showProgress(final ActionBarActivity activity, final boolean show) { if (activity == null) { return; } activity.setSupportProgressBarIndeterminateVisibility(show); } private static int getThemeId() { if (Settings.isLightSkin()) { return R.style.light; } return R.style.dark; } public static void setTheme(final Activity activity) { activity.setTheme(getThemeId()); } public static int getDialogTheme() { // Light theme dialogs don't work on Android Api < 11 if (Settings.isLightSkin()) { return R.style.popup_light; } return R.style.popup_dark; } /** * Show a long toast message to the user. This can be called from any thread. * * @param context * the activity the user is facing * @param resId * the message */ public static void showToast(final Context context, @StringRes final int resId) { showToast(context, context.getString(resId)); } private static void showCgeoToast(final Context context, final String text, final int toastDuration) { final Toast toast = Toast.makeText(context, text, toastDuration); toast.setGravity(Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM, 0, 100); toast.show(); } private static void postShowToast(final Activity activity, final String text, final int toastDuration) { if (StringUtils.isNotBlank(text)) { activity.runOnUiThread(new Runnable() { @Override public void run() { showCgeoToast(activity, text, toastDuration); } }); } } /** * Show a (long) toast message in application context (e.g. from background threads) */ public static void showApplicationToast(final String message) { final Context context = new ContextThemeWrapper(CgeoApplication.getInstance().getApplicationContext(), getThemeId()); showCgeoToast(context, message, Toast.LENGTH_LONG); } /** * Show a long toast message to the user. This can be called from any thread. * * @param activity the activity the user is facing * @param text the message */ public static void showToast(final Activity activity, final String text) { postShowToast(activity, text, Toast.LENGTH_LONG); } /** * Show a long toast message to the user. This can be called from any thread. * * @param context * any context. If this is not an activity, then the application context will be used. * @param text * the message */ public static void showToast(final Context context, final String text) { if (context instanceof Activity) { showToast((Activity) context, text); } else { showApplicationToast(text); } } /** * Show a short toast message to the user. This can be called from any thread. * * @param activity * the activity the user is facing * @param text * the message */ public static void showShortToast(final Activity activity, final String text) { postShowToast(activity, text, Toast.LENGTH_SHORT); } public static void onCreate(final Activity abstractActivity, final boolean keepScreenOn) { final Window window = abstractActivity.getWindow(); if (keepScreenOn) { window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); } if (Settings.useHardwareAcceleration()) { enableHardwareAcceleration(window); } } private static void enableHardwareAcceleration(final Window window) { window.addFlags(LayoutParams.FLAG_HARDWARE_ACCELERATED); } public static void invalidateOptionsMenu(final Activity activity) { if (activity instanceof ActionBarActivity) { ((ActionBarActivity) activity).supportInvalidateOptionsMenu(); } else { ActivityCompat.invalidateOptionsMenu(activity); } } /** * insert text into the EditText at the current cursor position * * @param moveCursor * place the cursor after the inserted text */ public static void insertAtPosition(final EditText editText, final String insertText, final boolean moveCursor) { final int selectionStart = editText.getSelectionStart(); final int selectionEnd = editText.getSelectionEnd(); final int start = Math.min(selectionStart, selectionEnd); final int end = Math.max(selectionStart, selectionEnd); final String content = editText.getText().toString(); final String completeText; if (start > 0 && !Character.isWhitespace(content.charAt(start - 1))) { completeText = " " + insertText; } else { completeText = insertText; } editText.getText().replace(start, end, completeText); final int newCursor = moveCursor ? start + completeText.length() : start; editText.setSelection(newCursor); } public static boolean navigateUp(@NonNull final Activity activity) { // first check if there is a parent declared in the manifest Intent upIntent = NavUtils.getParentActivityIntent(activity); // if there is no parent, and if this was not a new task, then just go back to simulate going to a parent if (upIntent == null && !activity.isTaskRoot()) { activity.finish(); return true; } // use the main activity, if there was no back stack and no manifest based parent if (upIntent == null) { upIntent = new Intent(CgeoApplication.getInstance(), MainActivity.class); } if (NavUtils.shouldUpRecreateTask(activity, upIntent) || activity.isTaskRoot()) { // This activity is NOT part of this app's task, so create a new task // when navigating up, with a synthesized back stack. TaskStackBuilder.create(activity) // Add all of this activity's parents to the back stack .addNextIntentWithParentStack(upIntent) // Navigate up to the closest parent .startActivities(); } else { // This activity is part of this app's task, so simply // navigate up to the logical parent activity. NavUtils.navigateUpTo(activity, upIntent); } return true; } }