title: Custom Android pin code entry widget
body: <p>I am trying to create a custom pin code widget for android as an alternative to just using an <code>EditText</code> with a password inputType attribute. What I'd like to display is a row of boxes, and have each box be filled as the user types his pin.</p>
  
  <p>Someone else did something like this but it turned out to be a fixed number of <code>EditText</code> views and there was a lot of <strong>ugly</strong> code for swapping focus as characters were typed or deleted. This is NOT the approach I want to take; rather, I'm designing mine to have <strong>customizable length</strong> (easy) and behave as a <strong>single focusable view</strong> (not so easy).</p>
  
  <p>My concept thus far is some kind of hybrid between a <code>LinearLayout</code> (to hold the "boxes") and an <code>EditText</code> (to store the user's input).</p>
  
  <p>This is the code so far...</p>
  
  <pre><code>public class PinCodeView extends LinearLayout {
      protected static final int MAX_PIN_LENGTH = 10;
      protected static final int MIN_PIN_LENGTH = 1;
  
      protected int pinLength;
      protected EditText mText;
  
      public PinCodeView(Context context, AttributeSet attrs) {
          super(context, attrs);
  
          TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.PinCodeView);
          try {
              pinLength = a.getInt(R.styleable.PinCodeView_pinLength, 0);
          } finally {
              a.recycle();
          }
  
          pinLength = Math.min(pinLength, MAX_PIN_LENGTH);
          pinLength = Math.max(pinLength, MIN_PIN_LENGTH);
  
          setupViews();
  
          Log.d(TAG, "PinCodeView initialized with pinLength = " + pinLength);
      }
  
      private void setupViews() {
          LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(
                  Context.LAYOUT_INFLATER_SERVICE);
          for (int i = 0; i &lt; pinLength; i++) {
              // inflate an ImageView and add it
              View child = inflater.inflate(R.layout.pin_box, null, false);
              addView(child);
          }
      }
  
      public CharSequence getText() {
          // TODO return pin code text instead
          return null;
      }
  
      public int length() {
          // TODO return length of typed pin instead
          return pinLength;
      }
  
      @Override
      public boolean onCheckIsTextEditor() {
          return true;
      }
  
      @Override
      public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
          // TODO return an InputConnection
          return null;
      }
  }
  </code></pre>
  
  <p>About those overrides: <a href="http://developer.android.com/reference/android/view/View.html#onCheckIsTextEditor%28%29" rel="noreferrer">onCheckIsTextEditor()</a> should return true and <a href="http://developer.android.com/reference/android/view/View.html#onCreateInputConnection%28android.view.inputmethod.EditorInfo%29" rel="noreferrer">onCreateInputConnection(EditorInfo outAttrs)</a> should return a new <code>InputConnection</code> object to interact with an InputMethod (a keyboard), but that's all I know. </p>
  
  <p>Does anyone know if I'm on the right track? Has anyone done work with <code>InputConnection</code> before or made their own editable views able to give guidance?</p>
  
  <p>(Edit 1)
  After looking at this some more, it seems I should subclass BaseInputConnection and supply a <code>TextView</code> or <code>EditText</code> as its target:</p>
  
  <pre><code>    @Override
      public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
          if (!onCheckIsTextEditor()) {
              return null;
          }
          return new BaseInputConnection(mText, true);
      }
  </code></pre>
  
  <p>Assuming this does store the text as it is typed, I still need some way to update the views to reflect the content change...</p>
  
  <p>(Edit 2)
  So I added this custom view to a screen for testing. It shows the number of boxes, and the whole view is focusable, but the keyboard never pops up. I know it gains/loses focus because the boxes show highlighting appropriately and I set an <code>OnFocusChangedListener</code> to write to logcat. </p>
  
  <p>What makes an actual keyboard appear when an editable view takes focus?</p>