0

I'm developing an app for nexus 7, and I need for certain EditText to show the keyboard view with numbers and special characters. I know you can set the layout for an EditText with inputType, but my problem is that if i set inputType="number" the dialpad appears and is not possible to switch to the characters view. All I need (is a customer's request) is to open the keyboard with the layout shown when you click on the key "123" in the bottom left. I've tried all combinations of setRawInputType and setInputType with no luck. This combination shows the dialpad

txtLineCode.setInputType(InputType.TYPE_CLASS_TEXT);
txtLineCode.setRawInputType(InputType.TYPE_CLASS_NUMBER);

this combination shows dialpad too

txtLineCode.setInputType(InputType.TYPE_CLASS_TEXT);
txtLineCode.setRawInputType(InputType.TYPE_NUMBER_VARIATION_NORMAL|InputType.TYPE_CLASS_NUMBER);

Here are screenshots to better explain what I need

this is the default keyboard

this is the default keyboard

this is the layout shown when I click on "?123" and this is what I need to show by default this is the layout shown when I click on "?123"

this the layout shown if I set inputType="number", which do not allow to switch to lecters layout enter image description here

By the moment I some EditText are prevalently numbers, but should contains numbers, what can I do?

many thanks

Apperside
  • 3,542
  • 2
  • 38
  • 65
  • Keep in mind that if you get this working (which I doubt), users can install different keyboards that have a completely different behaviour. – Siebe Jul 25 '13 at 13:21
  • Yes I know, but my goal is to ensure the correct behavior with the stock keyboard. Why do you doubt about getting it working? – Apperside Jul 25 '13 at 13:31
  • If you get it to display the keys under ?123 what is to stop the user switching back. Try a custom keyboard http://stackoverflow.com/questions/9577304/how-to-make-a-android-custom-keyboard – Daniel S. Fowler Jul 25 '13 at 13:32
  • I don't need to stop the user switching back, I need to allow the switching, but the customer wants the keys under ?123 by default because the values are numbers 95% of the times, but could contain letters as well – Apperside Jul 25 '13 at 13:50
  • You might be able to just send a key press to the keyboard with that particular key code. Not really the best solution but it might work. – user2483079 Jul 25 '13 at 14:47
  • @user2483079 it's a nice "not best solution", do you know how can I do this? – Apperside Jul 25 '13 at 14:54
  • In my unit testing I've been doing something like this: myEditText.requestFocus(); myEditText.onEditorAction(KeyEvent.KEYCODE_ENTER); This is to press the enter button, I'm not sure what the key is called that you want, I'll poke around. – user2483079 Jul 25 '13 at 16:03
  • There is one called KEYCODE_SWITCH_CHARSET, not sure if that's the one, but you may as well give it a shot. – user2483079 Jul 25 '13 at 16:11

1 Answers1

1

I think I found a quite elegant solution: I've used a Drawable in the textbox (in my case drawableRight), and I've assigned a click listener just on the drawable that executes the switch between numeric and text mode. I'm able to assign a listener just on the drawable using a little trick taken from Handling click events on a drawable within an EditText :

public class MyEdittextextends EditText {

    private Drawable drawableRight;
    private Drawable drawableLeft;
    private Drawable drawableTop;
    private Drawable drawableBottom;


//YOUR STUFF HERE

@Override
    public void setCompoundDrawables(Drawable left, Drawable top, Drawable right, Drawable bottom) {
        if (right != null) {
            drawableRight = right;
        }

        if (left != null) {
            drawableLeft = left;
        }
        super.setCompoundDrawables(left, top, right, bottom);
    }
View.OnClickListener _leftDrawableClickListener = null;
View.OnClickListener _rightDrawableClickListener = null;

public void setLeftDrawableClickListener(View.OnClickListener clickListener) {
    _leftDrawableClickListener = clickListener;
}

public void setRightDrawableClickListener(View.OnClickListener clickListener) {
    _rightDrawableClickListener = clickListener;
}

@Override
    public boolean onTouchEvent(MotionEvent event) {

        if (event.getAction() == MotionEvent.ACTION_DOWN) {
            int x, y;
            Rect bounds;
            x = (int) event.getX();
            y = (int) event.getY();
            // this works for left since container shares 0,0 origin with bounds
            if (drawableLeft != null) {
                bounds = drawableLeft.getBounds();
                if (bounds.contains(x - fuzz, y - fuzz)) {
                    try {
                        _leftDrawableClickListener.onClick(this);
                    } catch (Exception e) {
                    }
                    if (consumeEvent) {
                        event.setAction(MotionEvent.ACTION_CANCEL);
                        return false;
                    }
                }
            } else if (drawableRight != null) {
                bounds = drawableRight.getBounds();
                if (x >= (this.getRight() - bounds.width() - fuzz) && x <= (this.getRight() - this.getPaddingRight() + fuzz) && y >= (this.getPaddingTop() - fuzz) && y <= (this.getHeight() - this.getPaddingBottom()) + fuzz) {

                    try {
                        _rightDrawableClickListener.onClick(this);
                    } catch (Exception e) {
                    }
                    if (consumeEvent) {
                        event.setAction(MotionEvent.ACTION_CANCEL);
                        return false;
                    }
                }
            } else if (drawableTop != null) {
                // not implemented yet
            } else if (drawableBottom != null) {
                // not implemented yet
            }
        }

        return super.onTouchEvent(event);
    }


@Override
    protected void finalize() throws Throwable {
        drawableRight = null;
        drawableBottom = null;
        drawableLeft = null;
        drawableTop = null;
        super.finalize();
    }

}

Once the custom EditText has been created, I used this code in my Activity

myEdittext = (EditText) findViewById(R.id.myEdittext);
        myEdittext.setRightDrawableClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                if (myEdittext.getInputType() != InputType.TYPE_CLASS_TEXT) {
                    myEdittext.setInputType(InputType.TYPE_CLASS_TEXT);
                    myEdittext.setRawInputType(InputType.TYPE_CLASS_TEXT);
                    myEdittext.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.keyboard_123, 0);

                } else {
                    myEdittext.setRawInputType(InputType.TYPE_CLASS_NUMBER);
                    myEdittext.setInputType(InputType.TYPE_CLASS_NUMBER);
                    myEdittext.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.keyboard_abc, 0);
                }

            }
        });

this is the result: when the EditText is first shown appears like this

enter image description here

and clicking on "ABC" image becomes like this

enter image description here

hope this can help someone

Community
  • 1
  • 1
Apperside
  • 3,542
  • 2
  • 38
  • 65