PinPicker.java
/*
* Copyright 2018 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 androidx.leanback.widget.picker;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.view.KeyEvent;
import androidx.core.view.ViewCompat;
import androidx.leanback.R;
import java.util.ArrayList;
import java.util.List;
/**
* {@link Picker} subclass for allowing the user to enter a numerical PIN. The column count can be
* customized, and defaults to 4.
*
* {@link R.attr#columnCount}
*/
public class PinPicker extends Picker {
private static final int DEFAULT_COLUMN_COUNT = 4;
public PinPicker(Context context, AttributeSet attrs) {
this(context, attrs, R.attr.pinPickerStyle);
}
@SuppressLint("CustomViewStyleable")
public PinPicker(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
final TypedArray a = context.obtainStyledAttributes(
attrs, R.styleable.lbPinPicker, defStyleAttr, 0);
ViewCompat.saveAttributeDataForStyleable(
this, context, R.styleable.lbPinPicker, attrs, a, defStyleAttr, 0);
try {
setSeparator(" ");
setNumberOfColumns(a.getInt(R.styleable.lbPinPicker_columnCount, DEFAULT_COLUMN_COUNT));
} finally {
a.recycle();
}
}
/**
* Sets the number of columns for entering the PIN.
*
* @param count how many columns to display.
*/
public void setNumberOfColumns(int count) {
final List<PickerColumn> columns = new ArrayList<>(count);
for (int i = 0; i < count; i++) {
final PickerColumn column = new PickerColumn();
column.setMinValue(0);
column.setMaxValue(9);
column.setLabelFormat("%d");
columns.add(column);
}
setColumns(columns);
}
@Override
public boolean performClick() {
final int column = getSelectedColumn();
if (column == getColumnsCount() - 1) {
return super.performClick();
} else {
setSelectedColumn(column + 1);
return false;
}
}
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
final int keyCode = event.getKeyCode();
if (event.getAction() == KeyEvent.ACTION_UP
&& keyCode >= KeyEvent.KEYCODE_0 && keyCode <= KeyEvent.KEYCODE_9) {
final int selectedColumn = getSelectedColumn();
setColumnValue(selectedColumn, keyCode - KeyEvent.KEYCODE_0, false /* animate */);
performClick();
return true;
}
return super.dispatchKeyEvent(event);
}
/**
* Returns the PIN that the user has entered.
*
* @return Currently entered PIN
*/
public String getPin() {
final StringBuilder pin = new StringBuilder();
final int columnsCount = getColumnsCount();
for (int i = 0; i < columnsCount; i++) {
pin.append(Integer.toString(getColumnAt(i).getCurrentValue()));
}
return pin.toString();
}
/**
* Resets all columns and selects the first one.
*/
public void resetPin() {
final int columnsCount = getColumnsCount();
for (int i = 0; i < columnsCount; i++) {
setColumnValue(i, 0, false /* animate */);
}
setSelectedColumn(0);
}
}