summaryrefslogtreecommitdiffstats
path: root/src/android/support/wearable/view
diff options
context:
space:
mode:
Diffstat (limited to 'src/android/support/wearable/view')
-rw-r--r--src/android/support/wearable/view/AcceptDenyDialog.java182
-rw-r--r--src/android/support/wearable/view/WearableDialogHelper.java217
2 files changed, 399 insertions, 0 deletions
diff --git a/src/android/support/wearable/view/AcceptDenyDialog.java b/src/android/support/wearable/view/AcceptDenyDialog.java
new file mode 100644
index 00000000..8961ee71
--- /dev/null
+++ b/src/android/support/wearable/view/AcceptDenyDialog.java
@@ -0,0 +1,182 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+package android.support.wearable.view;
+
+import android.annotation.TargetApi;
+import android.app.Dialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.graphics.drawable.Drawable;
+import android.os.Build;
+import android.support.annotation.StyleRes;
+import android.view.View;
+import android.widget.ImageButton;
+import android.widget.ImageView;
+import android.widget.Space;
+import android.widget.TextView;
+
+import com.android.packageinstaller.R;
+
+/**
+ * A dialog to display a title, a message, and/or an icon with a positive and a negative button.
+ *
+ * <p>The buttons are hidden away unless there is a listener attached to the button. Since there's
+ * no click listener attached by default, the buttons are hidden be default.
+ */
+@TargetApi(Build.VERSION_CODES.LOLLIPOP)
+public class AcceptDenyDialog extends Dialog {
+ /** Icon at the top of the dialog. */
+ protected ImageView mIcon;
+ /** Title at the top of the dialog. */
+ protected TextView mTitle;
+ /** Message content of the dialog. */
+ protected TextView mMessage;
+ /** Panel containing the buttons. */
+ protected View mButtonPanel;
+ /** Positive button in the button panel. */
+ protected ImageButton mPositiveButton;
+ /** Negative button in the button panel. */
+ protected ImageButton mNegativeButton;
+ /**
+ * Click listener for the positive button. Positive button should hide if this is <code>null
+ * </code>.
+ */
+ protected DialogInterface.OnClickListener mPositiveButtonListener;
+ /**
+ * Click listener for the negative button. Negative button should hide if this is <code>null
+ * </code>.
+ */
+ protected DialogInterface.OnClickListener mNegativeButtonListener;
+ /** Spacer between the positive and negative button. Hidden if one button is hidden. */
+ protected View mSpacer;
+
+ private final View.OnClickListener mButtonHandler = (v) -> {
+ if (v == mPositiveButton && mPositiveButtonListener != null) {
+ mPositiveButtonListener.onClick(this, DialogInterface.BUTTON_POSITIVE);
+ dismiss();
+ } else if (v == mNegativeButton && mNegativeButtonListener != null) {
+ mNegativeButtonListener.onClick(this, DialogInterface.BUTTON_NEGATIVE);
+ dismiss();
+ }
+ };
+
+ public AcceptDenyDialog(Context context) {
+ this(context, 0 /* use default context theme */);
+ }
+
+ public AcceptDenyDialog(Context context, @StyleRes int themeResId) {
+ super(context, themeResId);
+
+ setContentView(R.layout.accept_deny_dialog);
+
+ mTitle = (TextView) findViewById(android.R.id.title);
+ mMessage = (TextView) findViewById(android.R.id.message);
+ mIcon = (ImageView) findViewById(android.R.id.icon);
+ mPositiveButton = (ImageButton) findViewById(android.R.id.button1);
+ mPositiveButton.setOnClickListener(mButtonHandler);
+ mNegativeButton = (ImageButton) findViewById(android.R.id.button2);
+ mNegativeButton.setOnClickListener(mButtonHandler);
+ mSpacer = (Space) findViewById(R.id.spacer);
+ mButtonPanel = findViewById(R.id.buttonPanel);
+ }
+
+ public ImageButton getButton(int whichButton) {
+ switch (whichButton) {
+ case DialogInterface.BUTTON_POSITIVE:
+ return mPositiveButton;
+ case DialogInterface.BUTTON_NEGATIVE:
+ return mNegativeButton;
+ default:
+ return null;
+ }
+ }
+
+ public void setIcon(Drawable icon) {
+ mIcon.setVisibility(icon == null ? View.GONE : View.VISIBLE);
+ mIcon.setImageDrawable(icon);
+ }
+
+ /**
+ * @param resId the resourceId of the drawable to use as the icon or 0 if you don't want an icon.
+ */
+ public void setIcon(int resId) {
+ mIcon.setVisibility(resId == 0 ? View.GONE : View.VISIBLE);
+ mIcon.setImageResource(resId);
+ }
+
+ /** @param message the content message text of the dialog. */
+ public void setMessage(CharSequence message) {
+ mMessage.setText(message);
+ mMessage.setVisibility(message == null ? View.GONE : View.VISIBLE);
+ }
+
+ /** @param title the title text of the dialog. */
+ @Override
+ public void setTitle(CharSequence title) {
+ mTitle.setText(title);
+ }
+
+ /**
+ * Sets a click listener for a button.
+ *
+ * <p>Will hide button bar if all buttons are hidden (i.e. their click listeners are <code>null
+ * </code>).
+ *
+ * @param whichButton {@link DialogInterface.BUTTON_POSITIVE} or {@link
+ * DialogInterface.BUTTON_NEGATIVE}
+ * @param listener the listener to set for the button. Hide button if <code>null</code>.
+ */
+ public void setButton(int whichButton, DialogInterface.OnClickListener listener) {
+ switch (whichButton) {
+ case DialogInterface.BUTTON_POSITIVE:
+ mPositiveButtonListener = listener;
+ break;
+ case DialogInterface.BUTTON_NEGATIVE:
+ mNegativeButtonListener = listener;
+ break;
+ default:
+ return;
+ }
+
+ mSpacer.setVisibility(mPositiveButtonListener == null || mNegativeButtonListener == null
+ ? View.GONE : View.INVISIBLE);
+ mPositiveButton.setVisibility(
+ mPositiveButtonListener == null ? View.GONE : View.VISIBLE);
+ mNegativeButton.setVisibility(
+ mNegativeButtonListener == null ? View.GONE : View.VISIBLE);
+ mButtonPanel.setVisibility(
+ mPositiveButtonListener == null && mNegativeButtonListener == null
+ ? View.GONE : View.VISIBLE);
+ }
+
+ /**
+ * Convenience method for <code>setButton(DialogInterface.BUTTON_POSITIVE, listener)</code>.
+ *
+ * @param listener the listener for the positive button.
+ */
+ public void setPositiveButton(DialogInterface.OnClickListener listener) {
+ setButton(DialogInterface.BUTTON_POSITIVE, listener);
+ }
+
+ /**
+ * Convenience method for <code>setButton(DialogInterface.BUTTON_NEGATIVE, listener)</code>.
+ *
+ * @param listener the listener for the positive button.
+ */
+ public void setNegativeButton(DialogInterface.OnClickListener listener) {
+ setButton(DialogInterface.BUTTON_NEGATIVE, listener);
+ }
+}
diff --git a/src/android/support/wearable/view/WearableDialogHelper.java b/src/android/support/wearable/view/WearableDialogHelper.java
new file mode 100644
index 00000000..0bdc1cc9
--- /dev/null
+++ b/src/android/support/wearable/view/WearableDialogHelper.java
@@ -0,0 +1,217 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+package android.support.wearable.view;
+
+import android.app.AlertDialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.res.Resources;
+import android.graphics.drawable.Drawable;
+import android.support.annotation.DrawableRes;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.support.annotation.VisibleForTesting;
+import android.util.Log;
+import android.widget.Button;
+
+/**
+ * Helper to add icons to AlertDialog buttons.AlertDialog buttons.
+ */
+public class WearableDialogHelper {
+ private static final String TAG = "WearableDialogHelper";
+
+ private int mPositiveIconId;
+ private Drawable mPositiveIcon;
+
+ private int mNeutralIconId;
+ private Drawable mNeutralIcon;
+
+ private int mNegativeIconId;
+ private Drawable mNegativeIcon;
+
+ @VisibleForTesting /* package */ Resources mResources;
+ @VisibleForTesting /* package */ Resources.Theme mTheme;
+
+ /**
+ * Convenience constructor, equivalent to {@code new WearableDialogHelper(context.getResources(),
+ * context.getTheme())}.
+ */
+ public WearableDialogHelper(@NonNull Context context) {
+ this(context.getResources(), context.getTheme());
+ }
+
+ /**
+ * @param resources the Resources used to obtain Drawables from resource IDs.
+ * @param theme the Theme used to properly obtain Drawables from resource IDs.
+ */
+ public WearableDialogHelper(@NonNull Resources resources, @NonNull Resources.Theme theme) {
+ mResources = resources;
+ mTheme = theme;
+ }
+
+ @Nullable
+ public Drawable getPositiveIcon() {
+ return resolveDrawable(mPositiveIcon, mPositiveIconId);
+ }
+
+ @Nullable
+ public Drawable getNegativeIcon() {
+ return resolveDrawable(mNegativeIcon, mNegativeIconId);
+ }
+
+ @Nullable
+ public Drawable getNeutralIcon() {
+ return resolveDrawable(mNeutralIcon, mNeutralIconId);
+ }
+
+ @NonNull
+ public WearableDialogHelper setPositiveIcon(@DrawableRes int resId) {
+ mPositiveIconId = resId;
+ mPositiveIcon = null;
+ return this;
+ }
+
+ @NonNull
+ public WearableDialogHelper setPositiveIcon(@Nullable Drawable icon) {
+ mPositiveIcon = icon;
+ mPositiveIconId = 0;
+ return this;
+ }
+
+ @NonNull
+ public WearableDialogHelper setNegativeIcon(@DrawableRes int resId) {
+ mNegativeIconId = resId;
+ mNegativeIcon = null;
+ return this;
+ }
+
+ @NonNull
+ public WearableDialogHelper setNegativeIcon(@Nullable Drawable icon) {
+ mNegativeIcon = icon;
+ mNegativeIconId = 0;
+ return this;
+ }
+
+ @NonNull
+ public WearableDialogHelper setNeutralIcon(@DrawableRes int resId) {
+ mNeutralIconId = resId;
+ mNeutralIcon = null;
+ return this;
+ }
+
+ @NonNull
+ public WearableDialogHelper setNeutralIcon(@Nullable Drawable icon) {
+ mNeutralIcon = icon;
+ mNeutralIconId = 0;
+ return this;
+ }
+
+ /**
+ * Applies the button icons setup in the helper to the buttons in the dialog.
+ *
+ * <p>Note that this should be called after {@code AlertDialog.create()}, NOT {@code
+ * AlertDialog.Builder.create()}. Calling {@code AlertDialog.Builder.show()} would also accomplish
+ * the same thing.
+ *
+ * @param dialog the AlertDialog to style with the helper.
+ */
+ public void apply(@NonNull AlertDialog dialog) {
+ applyButton(dialog.getButton(DialogInterface.BUTTON_POSITIVE), getPositiveIcon());
+ applyButton(dialog.getButton(DialogInterface.BUTTON_NEGATIVE), getNegativeIcon());
+ applyButton(dialog.getButton(DialogInterface.BUTTON_NEUTRAL), getNeutralIcon());
+ }
+
+ /** Applies the specified drawable to the button. */
+ @VisibleForTesting
+ /* package */ void applyButton(@Nullable Button button, @Nullable Drawable drawable) {
+ if (button != null) {
+ button.setCompoundDrawablesRelativeWithIntrinsicBounds(drawable, null, null, null);
+ button.setAllCaps(false);
+ } else if (drawable != null) {
+ Log.w(TAG, "non-null drawable used with missing button, did you call AlertDialog.create()?");
+ }
+ }
+
+ /** Obtain a drawable between a drawable and a resource ID. */
+ @VisibleForTesting
+ /* package */ Drawable resolveDrawable(@Nullable Drawable drawable, @DrawableRes int resId) {
+ return drawable == null && resId != 0 ? mResources.getDrawable(resId, mTheme) : drawable;
+ }
+
+ /** Convenience builder to generate an AlertDialog with icons in buttons. */
+ public static class DialogBuilder extends AlertDialog.Builder {
+ private final WearableDialogHelper mHelper;
+
+ public DialogBuilder(Context context) {
+ super(context);
+ mHelper = new WearableDialogHelper(context.getResources(), context.getTheme());
+ }
+
+ public DialogBuilder(Context context, int themeResId) {
+ super(context, themeResId);
+ mHelper = new WearableDialogHelper(context.getResources(), context.getTheme());
+ }
+
+ public WearableDialogHelper getHelper() {
+ return mHelper;
+ }
+
+ public DialogBuilder setPositiveIcon(@DrawableRes int iconId) {
+ mHelper.setPositiveIcon(iconId);
+ return this;
+ }
+
+ public DialogBuilder setPositiveIcon(@Nullable Drawable icon) {
+ mHelper.setPositiveIcon(icon);
+ return this;
+ }
+
+ public DialogBuilder setNegativeIcon(@DrawableRes int iconId) {
+ mHelper.setNegativeIcon(iconId);
+ return this;
+ }
+
+ public DialogBuilder setNegativeIcon(@Nullable Drawable icon) {
+ mHelper.setNegativeIcon(icon);
+ return this;
+ }
+
+ public DialogBuilder setNeutralIcon(@DrawableRes int iconId) {
+ mHelper.setNeutralIcon(iconId);
+ return this;
+ }
+
+ public DialogBuilder setNeutralIcon(@Nullable Drawable icon) {
+ mHelper.setNeutralIcon(icon);
+ return this;
+ }
+
+ @Override
+ public AlertDialog create() {
+ final AlertDialog dialog = super.create();
+ dialog.create();
+ mHelper.apply(dialog);
+ return dialog;
+ }
+
+ @Override
+ public AlertDialog show() {
+ final AlertDialog dialog = this.create();
+ dialog.show();
+ return dialog;
+ }
+ }
+}