aboutsummaryrefslogtreecommitdiff
path: root/src/com/android/tv/dialog/PinDialogFragment.java
diff options
context:
space:
mode:
authornchalko <nchalko@google.com>2018-03-15 18:56:54 -0700
committerNick Chalko <nchalko@google.com>2018-03-16 06:35:06 -0700
commit363cfbb22bbdb0db9c236f22926d68ee1b8ea56c (patch)
treed1d1e3d7004f265ad9c6a3d76d9786c193dddc14 /src/com/android/tv/dialog/PinDialogFragment.java
parent19748f08960d442113c27893216fe00116a21074 (diff)
downloadTV-363cfbb22bbdb0db9c236f22926d68ee1b8ea56c.tar.gz
Use leanback picker for PinDialog
PiperOrigin-RevId: 189281323 Change-Id: Ide9fb229e771f54e479bb07d0e84961a90728c9f
Diffstat (limited to 'src/com/android/tv/dialog/PinDialogFragment.java')
-rw-r--r--src/com/android/tv/dialog/PinDialogFragment.java429
1 files changed, 16 insertions, 413 deletions
diff --git a/src/com/android/tv/dialog/PinDialogFragment.java b/src/com/android/tv/dialog/PinDialogFragment.java
index 71f45fbe..81966b8a 100644
--- a/src/com/android/tv/dialog/PinDialogFragment.java
+++ b/src/com/android/tv/dialog/PinDialogFragment.java
@@ -16,37 +16,26 @@
package com.android.tv.dialog;
-import android.animation.Animator;
-import android.animation.AnimatorInflater;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.AnimatorSet;
-import android.animation.ObjectAnimator;
-import android.animation.ValueAnimator;
import android.app.ActivityManager;
import android.app.Dialog;
-import android.content.Context;
import android.content.DialogInterface;
import android.content.SharedPreferences;
-import android.content.res.Resources;
import android.media.tv.TvContentRating;
import android.os.Bundle;
import android.os.Handler;
import android.preference.PreferenceManager;
import android.text.TextUtils;
-import android.util.AttributeSet;
import android.util.Log;
-import android.util.TypedValue;
-import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
-import android.widget.FrameLayout;
import android.widget.TextView;
import android.widget.Toast;
import com.android.tv.R;
import com.android.tv.TvSingletons;
import com.android.tv.common.SoftPreconditions;
+import com.android.tv.dialog.picker.PinPicker;
import com.android.tv.util.TvSettings;
public class PinDialogFragment extends SafeDismissDialogFragment {
@@ -77,17 +66,12 @@ public class PinDialogFragment extends SafeDismissDialogFragment {
private static final int MAX_WRONG_PIN_COUNT = 5;
private static final int DISABLE_PIN_DURATION_MILLIS = 60 * 1000; // 1 minute
- private static final String INITIAL_TEXT = "—";
private static final String TRACKER_LABEL = "Pin dialog";
private static final String ARGS_TYPE = "args_type";
private static final String ARGS_RATING = "args_rating";
public static final String DIALOG_TAG = PinDialogFragment.class.getName();
- private static final int NUMBER_PICKERS_RES_ID[] = {
- R.id.first, R.id.second, R.id.third, R.id.fourth
- };
-
private int mType;
private int mRequestType;
private boolean mPinChecked;
@@ -96,7 +80,7 @@ public class PinDialogFragment extends SafeDismissDialogFragment {
private TextView mWrongPinView;
private View mEnterPinView;
private TextView mTitleView;
- private PinNumberPicker[] mPickers;
+ private PinPicker mPicker;
private SharedPreferences mSharedPreferences;
private String mPrevPin;
private String mPin;
@@ -140,7 +124,6 @@ public class PinDialogFragment extends SafeDismissDialogFragment {
public Dialog onCreateDialog(Bundle savedInstanceState) {
Dialog dlg = super.onCreateDialog(savedInstanceState);
dlg.getWindow().getAttributes().windowAnimations = R.style.pin_dialog_animation;
- PinNumberPicker.loadResources(dlg.getContext());
return dlg;
}
@@ -171,6 +154,14 @@ public class PinDialogFragment extends SafeDismissDialogFragment {
mWrongPinView = (TextView) v.findViewById(R.id.wrong_pin);
mEnterPinView = v.findViewById(R.id.enter_pin);
mTitleView = (TextView) mEnterPinView.findViewById(R.id.title);
+ mPicker = v.findViewById(R.id.pin_picker);
+ mPicker.setOnClickListener(
+ view -> {
+ String pin = getPinInput();
+ if (!TextUtils.isEmpty(pin)) {
+ done(pin);
+ }
+ });
if (TextUtils.isEmpty(getPin())) {
// If PIN isn't set, user should set a PIN.
// Successfully setting a new set is considered as entering correct PIN.
@@ -210,31 +201,13 @@ public class PinDialogFragment extends SafeDismissDialogFragment {
}
}
- mPickers = new PinNumberPicker[NUMBER_PICKERS_RES_ID.length];
- for (int i = 0; i < NUMBER_PICKERS_RES_ID.length; i++) {
- mPickers[i] = (PinNumberPicker) v.findViewById(NUMBER_PICKERS_RES_ID[i]);
- mPickers[i].setValueRangeAndResetText(0, 9);
- mPickers[i].setPinDialogFragment(this);
- mPickers[i].updateFocus(false);
- }
- for (int i = 0; i < NUMBER_PICKERS_RES_ID.length - 1; i++) {
- mPickers[i].setNextNumberPicker(mPickers[i + 1]);
- }
-
if (mType != PIN_DIALOG_TYPE_NEW_PIN) {
updateWrongPin();
}
+ mPicker.requestFocus();
return v;
}
- private final Runnable mUpdateEnterPinRunnable =
- new Runnable() {
- @Override
- public void run() {
- updateWrongPin();
- }
- };
-
private void updateWrongPin() {
if (getActivity() == null) {
// The activity is already detached. No need to update.
@@ -248,6 +221,7 @@ public class PinDialogFragment extends SafeDismissDialogFragment {
mWrongPinView.setVisibility(View.INVISIBLE);
mEnterPinView.setVisibility(View.VISIBLE);
mWrongPinCount = 0;
+ showToast(R.string.pin_toast_wrong);
} else {
mEnterPinView.setVisibility(View.INVISIBLE);
mWrongPinView.setVisibility(View.VISIBLE);
@@ -257,7 +231,8 @@ public class PinDialogFragment extends SafeDismissDialogFragment {
R.plurals.pin_enter_countdown,
remainingSeconds,
remainingSeconds));
- mHandler.postDelayed(mUpdateEnterPinRunnable, 1000);
+
+ mHandler.postDelayed(this::updateWrongPin, 1000);
}
}
@@ -364,383 +339,11 @@ public class PinDialogFragment extends SafeDismissDialogFragment {
}
private String getPinInput() {
- String result = "";
- try {
- for (PinNumberPicker pnp : mPickers) {
- pnp.updateText();
- result += pnp.getValue();
- }
- } catch (IllegalStateException e) {
- result = "";
- }
- return result;
+ return mPicker.getPinInput();
}
private void resetPinInput() {
- for (PinNumberPicker pnp : mPickers) {
- pnp.setValueRangeAndResetText(0, 9);
- }
- mPickers[0].requestFocus();
- }
-
- public static class PinNumberPicker extends FrameLayout {
- private static final int NUMBER_VIEWS_RES_ID[] = {
- R.id.previous2_number,
- R.id.previous_number,
- R.id.current_number,
- R.id.next_number,
- R.id.next2_number
- };
- private static final int CURRENT_NUMBER_VIEW_INDEX = 2;
- private static final int NOT_INITIALIZED = Integer.MIN_VALUE;
-
- private static Animator sFocusedNumberEnterAnimator;
- private static Animator sFocusedNumberExitAnimator;
- private static Animator sAdjacentNumberEnterAnimator;
- private static Animator sAdjacentNumberExitAnimator;
-
- private static float sAlphaForFocusedNumber;
- private static float sAlphaForAdjacentNumber;
-
- private int mMinValue;
- private int mMaxValue;
- private int mCurrentValue;
- // a value for setting mCurrentValue at the end of scroll animation.
- private int mNextValue;
- private final int mNumberViewHeight;
- private PinDialogFragment mDialog;
- private PinNumberPicker mNextNumberPicker;
- private boolean mCancelAnimation;
-
- private final View mNumberViewHolder;
- // When the PinNumberPicker has focus, mBackgroundView will show the focused background.
- // Also, this view is used for handling the text change animation of the current number
- // view which is required when the current number view text is changing from INITIAL_TEXT
- // to "0".
- private final TextView mBackgroundView;
- private final TextView[] mNumberViews;
- private final AnimatorSet mFocusGainAnimator;
- private final AnimatorSet mFocusLossAnimator;
- private final AnimatorSet mScrollAnimatorSet;
-
- public PinNumberPicker(Context context) {
- this(context, null);
- }
-
- public PinNumberPicker(Context context, AttributeSet attrs) {
- this(context, attrs, 0);
- }
-
- public PinNumberPicker(Context context, AttributeSet attrs, int defStyleAttr) {
- this(context, attrs, defStyleAttr, 0);
- }
-
- public PinNumberPicker(
- Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
- super(context, attrs, defStyleAttr, defStyleRes);
- View view = inflate(context, R.layout.pin_number_picker, this);
- mNumberViewHolder = view.findViewById(R.id.number_view_holder);
- mBackgroundView = (TextView) view.findViewById(R.id.focused_background);
- mNumberViews = new TextView[NUMBER_VIEWS_RES_ID.length];
- for (int i = 0; i < NUMBER_VIEWS_RES_ID.length; ++i) {
- mNumberViews[i] = (TextView) view.findViewById(NUMBER_VIEWS_RES_ID[i]);
- }
- Resources resources = context.getResources();
- mNumberViewHeight =
- resources.getDimensionPixelSize(R.dimen.pin_number_picker_text_view_height);
-
- mNumberViewHolder.setOnFocusChangeListener(
- new OnFocusChangeListener() {
- @Override
- public void onFocusChange(View v, boolean hasFocus) {
- updateFocus(true);
- }
- });
-
- mNumberViewHolder.setOnKeyListener(
- new OnKeyListener() {
- @Override
- public boolean onKey(View v, int keyCode, KeyEvent event) {
- if (event.getAction() == KeyEvent.ACTION_DOWN) {
- switch (keyCode) {
- case KeyEvent.KEYCODE_DPAD_UP:
- case KeyEvent.KEYCODE_DPAD_DOWN:
- {
- if (mCancelAnimation) {
- mScrollAnimatorSet.end();
- }
- if (!mScrollAnimatorSet.isRunning()) {
- mCancelAnimation = false;
- if (keyCode == KeyEvent.KEYCODE_DPAD_DOWN) {
- mNextValue =
- adjustValueInValidRange(
- mCurrentValue + 1);
- startScrollAnimation(true);
- } else {
- mNextValue =
- adjustValueInValidRange(
- mCurrentValue - 1);
- startScrollAnimation(false);
- }
- }
- return true;
- }
- }
- } else if (event.getAction() == KeyEvent.ACTION_UP) {
- switch (keyCode) {
- case KeyEvent.KEYCODE_DPAD_UP:
- case KeyEvent.KEYCODE_DPAD_DOWN:
- {
- mCancelAnimation = true;
- return true;
- }
- }
- }
- return false;
- }
- });
- mNumberViewHolder.setScrollY(mNumberViewHeight);
-
- mFocusGainAnimator = new AnimatorSet();
- mFocusGainAnimator.playTogether(
- ObjectAnimator.ofFloat(
- mNumberViews[CURRENT_NUMBER_VIEW_INDEX - 1],
- "alpha",
- 0f,
- sAlphaForAdjacentNumber),
- ObjectAnimator.ofFloat(
- mNumberViews[CURRENT_NUMBER_VIEW_INDEX],
- "alpha",
- sAlphaForFocusedNumber,
- 0f),
- ObjectAnimator.ofFloat(
- mNumberViews[CURRENT_NUMBER_VIEW_INDEX + 1],
- "alpha",
- 0f,
- sAlphaForAdjacentNumber),
- ObjectAnimator.ofFloat(mBackgroundView, "alpha", 0f, 1f));
- mFocusGainAnimator.setDuration(
- context.getResources().getInteger(android.R.integer.config_shortAnimTime));
- mFocusGainAnimator.addListener(
- new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animator) {
- mNumberViews[CURRENT_NUMBER_VIEW_INDEX].setText(
- mBackgroundView.getText());
- mNumberViews[CURRENT_NUMBER_VIEW_INDEX].setAlpha(
- sAlphaForFocusedNumber);
- mBackgroundView.setText("");
- }
- });
-
- mFocusLossAnimator = new AnimatorSet();
- mFocusLossAnimator.playTogether(
- ObjectAnimator.ofFloat(
- mNumberViews[CURRENT_NUMBER_VIEW_INDEX - 1],
- "alpha",
- sAlphaForAdjacentNumber,
- 0f),
- ObjectAnimator.ofFloat(
- mNumberViews[CURRENT_NUMBER_VIEW_INDEX + 1],
- "alpha",
- sAlphaForAdjacentNumber,
- 0f),
- ObjectAnimator.ofFloat(mBackgroundView, "alpha", 1f, 0f));
- mFocusLossAnimator.setDuration(
- context.getResources().getInteger(android.R.integer.config_shortAnimTime));
-
- mScrollAnimatorSet = new AnimatorSet();
- mScrollAnimatorSet.setDuration(
- context.getResources().getInteger(R.integer.pin_number_scroll_duration));
- mScrollAnimatorSet.addListener(
- new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- // Set mCurrent value when scroll animation is finished.
- mCurrentValue = mNextValue;
- updateText();
- mNumberViewHolder.setScrollY(mNumberViewHeight);
- mNumberViews[CURRENT_NUMBER_VIEW_INDEX - 1].setAlpha(
- sAlphaForAdjacentNumber);
- mNumberViews[CURRENT_NUMBER_VIEW_INDEX].setAlpha(
- sAlphaForFocusedNumber);
- mNumberViews[CURRENT_NUMBER_VIEW_INDEX + 1].setAlpha(
- sAlphaForAdjacentNumber);
- }
- });
- }
-
- static void loadResources(Context context) {
- if (sFocusedNumberEnterAnimator == null) {
- TypedValue outValue = new TypedValue();
- context.getResources()
- .getValue(R.dimen.pin_alpha_for_focused_number, outValue, true);
- sAlphaForFocusedNumber = outValue.getFloat();
- context.getResources()
- .getValue(R.dimen.pin_alpha_for_adjacent_number, outValue, true);
- sAlphaForAdjacentNumber = outValue.getFloat();
-
- sFocusedNumberEnterAnimator =
- AnimatorInflater.loadAnimator(context, R.animator.pin_focused_number_enter);
- sFocusedNumberExitAnimator =
- AnimatorInflater.loadAnimator(context, R.animator.pin_focused_number_exit);
- sAdjacentNumberEnterAnimator =
- AnimatorInflater.loadAnimator(
- context, R.animator.pin_adjacent_number_enter);
- sAdjacentNumberExitAnimator =
- AnimatorInflater.loadAnimator(context, R.animator.pin_adjacent_number_exit);
- }
- }
-
- @Override
- public boolean dispatchKeyEvent(KeyEvent event) {
- if (event.getAction() == KeyEvent.ACTION_UP) {
- int keyCode = event.getKeyCode();
- if (keyCode >= KeyEvent.KEYCODE_0 && keyCode <= KeyEvent.KEYCODE_9) {
- mNextValue = adjustValueInValidRange(keyCode - KeyEvent.KEYCODE_0);
- updateFocus(false);
- } else if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER
- || keyCode == KeyEvent.KEYCODE_ENTER) {
- if (mNextNumberPicker == null) {
- String pin = mDialog.getPinInput();
- if (!TextUtils.isEmpty(pin)) {
- mDialog.done(pin);
- }
- } else {
- mNextNumberPicker.requestFocus();
- }
- return true;
- }
- }
- return super.dispatchKeyEvent(event);
- }
-
- void startScrollAnimation(boolean scrollUp) {
- mFocusGainAnimator.end();
- mFocusLossAnimator.end();
- final ValueAnimator scrollAnimator =
- ValueAnimator.ofInt(0, scrollUp ? mNumberViewHeight : -mNumberViewHeight);
- scrollAnimator.addUpdateListener(
- new ValueAnimator.AnimatorUpdateListener() {
- @Override
- public void onAnimationUpdate(ValueAnimator animation) {
- int value = (Integer) animation.getAnimatedValue();
- mNumberViewHolder.setScrollY(value + mNumberViewHeight);
- }
- });
- scrollAnimator.setDuration(
- getResources().getInteger(R.integer.pin_number_scroll_duration));
-
- if (scrollUp) {
- sAdjacentNumberExitAnimator.setTarget(mNumberViews[CURRENT_NUMBER_VIEW_INDEX - 1]);
- sFocusedNumberExitAnimator.setTarget(mNumberViews[CURRENT_NUMBER_VIEW_INDEX]);
- sFocusedNumberEnterAnimator.setTarget(mNumberViews[CURRENT_NUMBER_VIEW_INDEX + 1]);
- sAdjacentNumberEnterAnimator.setTarget(mNumberViews[CURRENT_NUMBER_VIEW_INDEX + 2]);
- } else {
- sAdjacentNumberEnterAnimator.setTarget(mNumberViews[CURRENT_NUMBER_VIEW_INDEX - 2]);
- sFocusedNumberEnterAnimator.setTarget(mNumberViews[CURRENT_NUMBER_VIEW_INDEX - 1]);
- sFocusedNumberExitAnimator.setTarget(mNumberViews[CURRENT_NUMBER_VIEW_INDEX]);
- sAdjacentNumberExitAnimator.setTarget(mNumberViews[CURRENT_NUMBER_VIEW_INDEX + 1]);
- }
-
- mScrollAnimatorSet.playTogether(
- scrollAnimator,
- sAdjacentNumberExitAnimator,
- sFocusedNumberExitAnimator,
- sFocusedNumberEnterAnimator,
- sAdjacentNumberEnterAnimator);
- mScrollAnimatorSet.start();
- }
-
- void setValueRangeAndResetText(int min, int max) {
- if (min > max) {
- throw new IllegalArgumentException(
- "The min value should be greater than or equal to the max value");
- } else if (min == NOT_INITIALIZED) {
- throw new IllegalArgumentException(
- "The min value should be greater than Integer.MIN_VALUE.");
- }
- mMinValue = min;
- mMaxValue = max;
- mNextValue = mCurrentValue = NOT_INITIALIZED;
- for (int i = 0; i < NUMBER_VIEWS_RES_ID.length; ++i) {
- mNumberViews[i].setText(i == CURRENT_NUMBER_VIEW_INDEX ? INITIAL_TEXT : "");
- }
- mBackgroundView.setText(INITIAL_TEXT);
- }
-
- void setPinDialogFragment(PinDialogFragment dlg) {
- mDialog = dlg;
- }
-
- void setNextNumberPicker(PinNumberPicker picker) {
- mNextNumberPicker = picker;
- }
-
- int getValue() {
- if (mCurrentValue < mMinValue || mCurrentValue > mMaxValue) {
- throw new IllegalStateException("Value is not set");
- }
- return mCurrentValue;
- }
-
- void updateFocus(boolean withAnimation) {
- mScrollAnimatorSet.end();
- mFocusGainAnimator.end();
- mFocusLossAnimator.end();
- updateText();
- if (mNumberViewHolder.isFocused()) {
- if (withAnimation) {
- mBackgroundView.setText(String.valueOf(mCurrentValue));
- mFocusGainAnimator.start();
- } else {
- mBackgroundView.setAlpha(1f);
- mNumberViews[CURRENT_NUMBER_VIEW_INDEX - 1].setAlpha(sAlphaForAdjacentNumber);
- mNumberViews[CURRENT_NUMBER_VIEW_INDEX + 1].setAlpha(sAlphaForAdjacentNumber);
- }
- } else {
- if (withAnimation) {
- mFocusLossAnimator.start();
- } else {
- mBackgroundView.setAlpha(0f);
- mNumberViews[CURRENT_NUMBER_VIEW_INDEX - 1].setAlpha(0f);
- mNumberViews[CURRENT_NUMBER_VIEW_INDEX + 1].setAlpha(0f);
- }
- mNumberViewHolder.setScrollY(mNumberViewHeight);
- }
- }
-
- private void updateText() {
- boolean wasNotInitialized = false;
- if (mNumberViewHolder.isFocused() && mCurrentValue == NOT_INITIALIZED) {
- mNextValue = mCurrentValue = mMinValue;
- wasNotInitialized = true;
- }
- if (mCurrentValue >= mMinValue && mCurrentValue <= mMaxValue) {
- for (int i = 0; i < NUMBER_VIEWS_RES_ID.length; ++i) {
- if (wasNotInitialized && i == CURRENT_NUMBER_VIEW_INDEX) {
- // In order to show the text change animation, keep the text of
- // mNumberViews[CURRENT_NUMBER_VIEW_INDEX].
- } else {
- mNumberViews[i].setText(
- String.valueOf(
- adjustValueInValidRange(
- mCurrentValue - CURRENT_NUMBER_VIEW_INDEX + i)));
- }
- }
- }
- }
-
- private int adjustValueInValidRange(int value) {
- int interval = mMaxValue - mMinValue + 1;
- if (value < mMinValue - interval || value > mMaxValue + interval) {
- throw new IllegalArgumentException(
- "The value( " + value + ") is too small or too big to adjust");
- }
- return (value < mMinValue)
- ? value + interval
- : (value > mMaxValue) ? value - interval : value;
- }
+ mPicker.resetPinInput();
}
/**