PinEntryWrapper.java

 1package eu.siacs.conversations.ui.util;
 2
 3import android.text.Editable;
 4import android.text.TextWatcher;
 5import android.view.KeyEvent;
 6import android.view.View;
 7import android.widget.EditText;
 8import android.widget.LinearLayout;
 9
10import java.util.ArrayList;
11import java.util.List;
12
13public class PinEntryWrapper {
14
15    private final List<EditText> digits = new ArrayList<>();
16
17    private final TextWatcher textWatcher = new TextWatcher() {
18        @Override
19        public void beforeTextChanged(CharSequence s, int start, int count, int after) {
20
21        }
22
23        @Override
24        public void onTextChanged(CharSequence s, int start, int before, int count) {
25
26        }
27
28        @Override
29        public void afterTextChanged(Editable s) {
30            int current = -1;
31            for (int i = 0; i < digits.size(); ++i) {
32                if (s.hashCode() == digits.get(i).getText().hashCode()) {
33                    current = i;
34                }
35            }
36            if (current == -1) {
37                return;
38            }
39            if (s.length() > 0) {
40                if (current < digits.size() - 1) {
41                    digits.get(current + 1).requestFocus();
42                }
43            } else {
44                int focusOn = current;
45                for (int i = current - 1; i >= 0; --i) {
46                    if (digits.get(i).getText().length() == 0) {
47                        focusOn = i;
48                    } else {
49                        break;
50                    }
51                }
52                digits.get(focusOn).requestFocus();
53            }
54        }
55    };
56
57    private final View.OnKeyListener keyListener = (v, keyCode, event) -> {
58        if (event.getAction() != KeyEvent.ACTION_DOWN) {
59            return false;
60        }
61        if (v instanceof EditText) {
62            final EditText editText = (EditText) v;
63            if (keyCode == KeyEvent.KEYCODE_DEL && editText.getText().length() == 0) {
64                final int current = digits.indexOf(editText);
65                for (int i = current - 1; i >= 0; --i) {
66                    if (digits.get(i).getText().length() > 0) {
67                        digits.get(i).getText().clear();
68                        return true;
69                    }
70                }
71            }
72        }
73        return false;
74    };
75
76    public PinEntryWrapper(LinearLayout linearLayout) {
77        for (int i = 0; i < linearLayout.getChildCount(); ++i) {
78            View view = linearLayout.getChildAt(i);
79            if (view instanceof EditText) {
80                this.digits.add((EditText) view);
81            }
82        }
83        registerListeners();
84    }
85
86    private void registerListeners() {
87        for (EditText editText : digits) {
88            editText.addTextChangedListener(textWatcher);
89            editText.setOnKeyListener(keyListener);
90        }
91    }
92
93}