diff options
author | nchalko <nchalko@google.com> | 2018-03-15 18:56:54 -0700 |
---|---|---|
committer | Nick Chalko <nchalko@google.com> | 2018-03-16 06:35:06 -0700 |
commit | 363cfbb22bbdb0db9c236f22926d68ee1b8ea56c (patch) | |
tree | d1d1e3d7004f265ad9c6a3d76d9786c193dddc14 /src/com/android/tv/dialog/PinDialogFragment.java | |
parent | 19748f08960d442113c27893216fe00116a21074 (diff) | |
download | TV-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.java | 429 |
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(); } /** |