Neither onKeyListener nor TextWatcher able to receive soft keyboard inputs

604 views Asked by At

I have looked at many posts and similiar questions have been asked. But none of the solution is working. First of all I've tried using onKeyListener, but in many posts, it is stated that it does not work for soft keyboard. So I tried to use TextWatcher instead, but it still does not printout anything.

public class GamePanel extends SurfaceView implements SurfaceHolder.Callback{
private MainThread thread;
private EditText editText;
private Bitmap textBitmap;

public GamePanel(Context context){
    super(context);

    //Add callback to the surfaceview to intercept events
    getHolder().addCallback(this);

    //Make GamePanel focusable so it can handle events
    setFocusable(true);
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format,int width, int height){}

@Override
public void surfaceDestroyed(SurfaceHolder holder){}

@Override
public void surfaceCreated(SurfaceHolder holder){

    editText = new EditText(getContext());
    editText.setSingleLine(true);
    editText.setImeOptions(EditorInfo.IME_ACTION_DONE);
    editText.setDrawingCacheEnabled(true);
    editText.layout(0, 0, WIDTH - 200, 100);
    editText.buildDrawingCache();

    textBitmap = Bitmap.createBitmap(editText.getDrawingCache());

    thread = new MainThread(getHolder(), this);

    //Start the game loop
    thread.setRunning(true);
    thread.start();

    /*editText.setOnKeyListener(new View.OnKeyListener() {
        @Override
        public boolean onKey(View v, int keyCode, KeyEvent event) {
            if (event.getAction() == KeyEvent.ACTION_DOWN) {
                Toast.makeText(getContext(), "ABCD", Toast.LENGTH_SHORT).show();
                System.out.println("KEY PRESSED");
            }
            return true;
        }
    });*/

    /*editText.addTextChangedListener(new TextWatcher() {

        @Override
        public void afterTextChanged(Editable s) {
             System.out.println("KEY PRESSED");
        }

        @Override
        public void beforeTextChanged(CharSequence s, int start,
                                      int count, int after) {
        }
        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {
            System.out.println("KEY PRESSED");
        }
    });*/
editText.setOnEditorActionListener(new EditText.OnEditorActionListener() {
            @Override
            public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
                if (actionId == EditorInfo.IME_ACTION_DONE) {
                    System.out.println("ABC");
                    return true;
                }
                return false;
            }
        });
    }
@Override
public boolean onTouchEvent(MotionEvent event){
    if(event.getAction() == MotionEvent.ACTION_DOWN ){
                editText.setFocusableInTouchMode(true);
                editText.requestFocus();
                InputMethodManager imm = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
                imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);
                //imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, InputMethodManager.HIDE_IMPLICIT_ONLY);

        return true;
    }
    return super.onTouchEvent(event);
}
@Override
    public void draw(Canvas canvas){
        if (canvas != null) {
            canvas.drawBitmap(textBitmap,50,50,null);
            canvas.restoreToCount(savedState);
        }
    }

Does drawing EditText with canvas.drawBitmap have anything to do with those solutions not working? Or is there any mistakes on implementing them?

Any solutions are welcomed, need explanations if possible. Thanks!

EDIT : tried to use onEditorActionListener

1

There are 1 answers

7
Neal Ahluvalia On

First of all check Did you include this line in your xml inside the EditText

android:singleLine="true"

if not, please add it first. Next for e.g i wanna use Done button inside my soft keyboard, than here is what you can do.

<EditText 
    android:id="edName"
    android:layout_height="wrap_content"
    android:layout_width="fill_parent"
    android:singleLine="true"    //this line to take input in single line (if you don't include this line, Done button will not take any actions)
    android:imeOptions="actionDone"/>   //this line to provide done button

Now to take the input from keyboard for done button, add this code after findViewById in your onCreate

//TODO softKey "Done" listener for keyboard
edName.setOnEditorActionListener(new EditText.OnEditorActionListener() {
     @Override
     public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
          if (actionId == EditorInfo.IME_ACTION_DONE) {
                //Do what you want here
                return true;
     }
     return false;
  }
});