Android Input Box

edited February 2018 in Android Mode

Hi. I am trying to code an android Input Box. The G4P lib uses libs that are not available on android. I did manage to write a working code in plain Processing code, but the "key" keyword doesn't read coded keys like BACKSPACE and other characters like 'á'. on my device. Then I found a really nice code of @akenaton here , and with the kind help of @olivi55 who teached me how to edit the TextField, I wrote an example code for an InputBox. I now need to figure out how to hide the textbox as soon as I enter the End key.( Enter) , how to link that. In code below it will hide the keyboard., but not the textbox. The textbox will hide and write the input string on the screen only after I hit the input button.

CODE:

import android.os.Bundle;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.widget.FrameLayout;
import android.widget.RelativeLayout;
import android.widget.LinearLayout;  
import android.text.Editable;
import android.graphics.Color;
import android.widget.EditText;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;
import android.view.View;
import android.widget.TextView;
import android.view.ViewGroup;
import android.view.ViewParent;

EditText edit;
Activity act;
Context mC;
FrameLayout fl;
boolean bflag = true;
String txt;
int flag = 1, xbut, ybut, wbut = 110, hbut = 35;

@Override
  public void onStart() {
    super.onStart();
    act = this.getActivity();
    mC= act.getApplicationContext();
    act.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
    edit = new EditText(mC);
    edit.setLayoutParams (
      new RelativeLayout.LayoutParams (
        RelativeLayout.LayoutParams.WRAP_CONTENT,RelativeLayout.LayoutParams.WRAP_CONTENT
      )
    );
    edit.setHint("Write Here!");
    edit.setTextColor(Color.rgb(0, 0, 0));
    edit.setHintTextColor(Color.rgb(170, 170, 170));  
    edit.setBackgroundColor(Color.WHITE);      // edit.getBackground().setAlpha(255);
    fl = (FrameLayout)act.findViewById(0x1000);
    edit.getLayoutParams().width=14*width/26;  
    edit.getLayoutParams().height=height/17; 
    edit.setX(width/3);
    edit.setY(height/6);
    edit.requestFocus();
    edit.setInputType(android.text.InputType.TYPE_CLASS_TEXT);
    fl.addView(edit);
  }

void setup() {
  fullScreen();
  orientation(LANDSCAPE);
  background(0, 0, 255);
  xbut = width/10;
  ybut = height/6;
  inputButton(xbut, ybut, wbut, hbut);
}

void draw() {
  if (flag == 1) { 
    showInputBox();
    flag = 3;
  }
  if (flag == 2) {
    hideInputBox();
    flag = 3;
  }
}

void showInputBox() {
  background(0, 0, 255);
  String txt = edit.getText().toString();
  edit.getText().clear();
  text("Please type some input.", width/3, height/12);
  inputButton(xbut, ybut, wbut, hbut);  
  act.runOnUiThread(
    new Runnable() { 
      public void run() {
        edit.setVisibility(View.VISIBLE);
        edit.requestFocus();
      }
    }
  );
}

  public void onResume() {
    super.onResume();
      act.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
  }


void hideInputBox() {
  background(0, 0, 255);
  inputButton(xbut, ybut, wbut, hbut); 
  String txt = edit.getText().toString();
  text("Your input was:  " + txt, width/3, height/12);
  act.runOnUiThread(
    new Runnable() {
      public void run() {
        edit.setVisibility(View.GONE);
      }
    }
  );
}  

void mousePressed() {
  if (mouseX >= xbut && mouseX <= xbut + wbut &&  mouseY >= ybut && mouseY <= ybut + hbut) { 
    if (bflag) { 
      flag = 2;
      bflag = false;
    } else {
      flag = 1;
      bflag = true;
    }
  }
}

void inputButton (int x, int y, float w, float h) {
  textSize(20);
  stroke(127);
  rect(x, y, w, h);
  color c2 = color(130, 0, 0);
  color c1 = color(255, 85, 0);
  for (int i = y; i <= y+h; i++) { 
    float inter = map(i, y, y+h, 0, 1); 
    color c = lerpColor(c1, c2, inter); 
    stroke(c); 
    line(x, i, x+w, i);
  }
  fill(255);
  text("Input", x + 30, y + 25);
}

I loaded the AIDE App, to learn Java. but I don't want to lett Processing down because I love it for my artwork and arduino projects. I really would appreciate some help. Emmanuel

Tagged:

Answers

  • Have you consider using a DialogBox? I can assist you sometime tonight, just tag me if you don't find relevant posts in the forum.

    Just to clarify, are you coding in Processing AM or in the Processing App? Is it AIDE or PIDE? Sorry, not familiar with them... I have seen them before but I thought on asking to save me some work

    Kf

  • Hi @kfrayer. I just managed to hide the the textfield. And I will edit my post in the afternoon. I am using the exellent APDE App for coding with Processing in Android and starting to learn Java with the AIDE App.

    I would love to see also a DialogBox for Processing. So I appreciate it if you have something for me to start with.

  • @kfrajer Thanks,, I missed that post. Maybe the title could be edited to Dialog box:) I have edited my first post which now shows and hides the textfield with the input button. I rather would like to se this happening when I hit the Enter or End key. Do you have any idea how to accomplish this?

  • Thany you for the links. I tried the keyPress function, but it doesn't work in the code above. If you comment out the line fl.addView(edit); it will work again. But then again you have to out comment the line edit.setInputType(android.text.InputType.TYPE_CLASS_TEXT); Then the softKeyboard will be a default one with the Enter or Return key instead of a Done key. And can be captured with if (int(key) == 10). Btw, using the default board has the advantage of having a scrollable textfield with /n , but you have to put a button to grab the whole string to display or store. I found an interesting java tutorial here, and I managed to put a listener on the field so that it hides the field and shows the input text as soon as the Done button is hit.

    What I finaly want is to start the program with only the input button (it at the moment starts with the field, button and keyboard right away), than hitting the button displaying the input box. Maybe it's simple but I can't see it now.

    Any idea?

    import android.os.Bundle;
    import android.app.Activity;
    import android.content.Context;
    import android.content.Intent;
    import android.content.*;   //View;
    import android.widget.FrameLayout;
    import android.widget.RelativeLayout;
    import android.widget.LinearLayout;  
    import android.widget.EditText;
    import android.widget.TextView;
    import android.text.Editable;
    import android.graphics.Color;
    import android.view.WindowManager;
    import android.view.inputmethod.InputMethodManager;
    import android.view.View;
    import android.view.ViewGroup;
    import android.view.ViewParent;
    import android.view.View.OnKeyListener;
    import android.view.View;
    import android.view.KeyEvent;
    
    EditText edit;
    Activity act;
    Context mC;
    FrameLayout fl;
    String txt;
    int xbut, ybut, wbut = 110, hbut = 35;
    
    @Override
      public void onStart() {
        super.onStart();
        act = this.getActivity();
        mC= act.getApplicationContext();
        act.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
        edit = new EditText(mC);
        edit.setLayoutParams (
          new RelativeLayout.LayoutParams (
            RelativeLayout.LayoutParams.WRAP_CONTENT,RelativeLayout.LayoutParams.WRAP_CONTENT
          )
        );
        edit.setHint("Write Here!");
        edit.setTextColor(Color.rgb(0, 0, 0));
        edit.setHintTextColor(Color.rgb(170, 170, 170));  
        edit.setBackgroundColor(Color.WHITE);      // edit.getBackground().setAlpha(255);
        fl = (FrameLayout)act.findViewById(0x1000);
        edit.getLayoutParams().width=14*width/26;  
        edit.getLayoutParams().height=height/17; 
        edit.setX(width/3);
        edit.setY(height/6);
        edit.requestFocus();
        edit.setInputType(android.text.InputType.TYPE_CLASS_TEXT);
        fl.addView(edit);
        edit.setOnKeyListener(
          new View.OnKeyListener() {
            @Override
            public boolean onKey(View v, int keyCode, KeyEvent event) {
              if (event.getAction() == KeyEvent.ACTION_DOWN && event.getKeyCode()== KeyEvent.KEYCODE_ENTER) {
                InputMethodManager imm = (InputMethodManager)v.getContext().getSystemService(Context.INPUT_METHOD_SERVICE); 
                imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
                hideInputBox();
                return true;
              }
              return false;
            }
          }
        );
        android.view.inputmethod.InputMethodManager imm = (android.view.inputmethod.InputMethodManager) getActivity().getSystemService(android.content.Context.INPUT_METHOD_SERVICE);
        imm.hideSoftInputFromWindow(getActivity().getCurrentFocus().getWindowToken(), 0);
     }
    
    
    
    void setup() {
      fullScreen();
      orientation(LANDSCAPE);
      background(0, 0, 255);
      xbut = width/10;
      ybut = height/6;
      inputButton(xbut, ybut, wbut, hbut);
    }
    
    void draw() {
    }
    
    void showInputBox() {
      background(0, 0, 255);
      String txt = edit.getText().toString();
      edit.getText().clear();
      inputButton(xbut, ybut, wbut, hbut);  
      act.runOnUiThread(
        new Runnable() { 
          public void run() {
            edit.setVisibility(View.VISIBLE);
            edit.requestFocus();
          }
        }
      );
    }
    
    public void onResume() {
      super.onResume();
        act.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
    }
    
    void hideInputBox() {
      background(0, 0, 255);
      inputButton(xbut, ybut, wbut, hbut); 
      String txt = edit.getText().toString();
      text("Your input was:  " + txt, width/3, height/12);
      act.runOnUiThread(
        new Runnable() {
          public void run() {
            edit.setVisibility(View.GONE);
          }
        }
      );
    }  
    
    
    void mousePressed() {
      if (mouseX >= xbut && mouseX <= xbut + wbut &&  mouseY >= ybut && mouseY <= ybut + hbut) { 
        showInputBox();
      }
    }
    
    void inputButton (int x, int y, float w, float h) {
      textSize(20);
      stroke(127);
      rect(x, y, w, h);
      color c2 = color(130, 0, 0);
      color c1 = color(255, 85, 0);
      for (int i = y; i <= y+h; i++) { 
        float inter = map(i, y, y+h, 0, 1); 
        color c = lerpColor(c1, c2, inter); 
        stroke(c); 
        line(x, i, x+w, i);
      }
      fill(255);
      text("Input", x + 30, y + 25);
    }
    
  • edited February 2018

    Ok, so if you put in the code above :

    edit.setVisibility(View.GONE);
    act.getWindow().setSoftInputMode(WindowManager.LayoutParams. SOFT_INPUT_STATE_HIDDEN ); 
    

    in the start activity, and set a flag in the onResume function like

        public void onResume() {
          super.onResume();
          if (flag) {    act.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
          }
        }
    

    and put flag = true; in the showInputBox() function the program works, but it is a work around. I would like to do it the correct way following Activity methods like explained here. But how to do that?

  • edited February 2018 Answer ✓

    @noel===

    • your code is not good for the latest versions of android mode: the framelayout id to which you add the editext view was hardcoded, now it is generated (there are solutions)

    • create your button in P5

    • create your editext as you have done BUT do not add the view onStart(); add to it an action done button; when this button is clicked the soft keyboard will disappear (but the editext view will remain)

    • add (with a runnable) the edittext (addview) when your button is clicked

    • create a method with a listener for the editText (OnEditorActionListener()); in this method add : if(EditorInfo.IME.ACTION_DONE).......

    • use here your "workaround" which is not a workaround (ViewGone) but a good solution because viewgone is not view invisible: editext layoutParams are set to (0);if you prefer you can also create another runnable and remove the editview from the frame layout: in this case you can reuse the addview.

    try to do that; in case there is a problem i can post some snippet.

  • edited February 2018

    Hi, akenaton. Thank you for the constructive comments.But it was cold water in my face starting with point 1. I was happily writing a class of the code, but when i read this I stopped right away and did some research, but I found only your own issue about this on the processing Github, with your link to the answer here. There is some doubt about what should be the correct answer. What is your opinion? Also a day later @codeanticode wrote that there was no problem because of this. I am confused now.

  • Answer ✓

    I am not sure if this answers all your questions bc I am not sure what is the current status of your code. This next is tested. Notice some added imports and a single line change in setup, between other minor changes, like adding a button from Android widgets.

    Kf

    //REFERENCE: https:// forum.processing.org/two/discussion/26349/android-input-box#latest
    //REFERENCE: https:// forum.processing.org/two/discussion/14206/on-screen-buttons-without-apwidgets
    //REFERENCE:
    //REFERENCE:
    //REFERENCE:
    
    import android.os.Bundle;
    import android.app.Activity;
    import android.content.Context;
    import android.content.Intent;
    import android.content.*;   //View;
    import android.widget.FrameLayout;
    import android.widget.RelativeLayout;
    import android.widget.LinearLayout;  
    import android.widget.EditText;
    import android.widget.TextView;
    import android.text.Editable;
    import android.graphics.Color;
    import android.view.WindowManager;
    import android.view.inputmethod.InputMethodManager;
    import android.view.View;
    import android.view.ViewGroup;
    import android.view.ViewParent;
    import android.view.View.OnKeyListener;
    import android.view.View;
    import android.view.KeyEvent;
    
    import android.widget.Button;
    import android.view.View.OnClickListener;
    import android.view.ViewGroup.LayoutParams;
    import android.view.Gravity;
    import    android.R;
    import android.widget.Toast;
    import android.os.Looper;
    
    private static final int MY_BUTTON1 = 9000;
    
    Activity act;
    Context mC;
    
    FrameLayout fl;
    EditText edit;
    Button iButton;
    
    String txt;
    int xbut, ybut, wbut = 110, hbut = 35;
    
    boolean pressed;
    
    
    void setup() {
      fullScreen();
      orientation(LANDSCAPE);
      background(0, 0, 255);
      xbut = width/10;
      ybut = height/6;
      inputButton(xbut, ybut, wbut, hbut);
    
       Looper.prepare();
    }
    
    void draw() {
    }
    
    void showInputBox() {
      background(0, 0, 255);
      String txt = edit.getText().toString();
      edit.getText().clear();
      inputButton(xbut, ybut, wbut, hbut);  
      act.runOnUiThread(
        new Runnable() { 
        public void run() {
          edit.setVisibility(View.VISIBLE);
          edit.requestFocus();
        }
      }
      );
    }
    
    
    
    void hideInputBox() {
      background(0, 0, 255);
      inputButton(xbut, ybut, wbut, hbut); 
      String txt = edit.getText().toString();
      text("Your input was:  " + txt, width/3, height/12);
      act.runOnUiThread(
        new Runnable() {
        public void run() {
          edit.setVisibility(View.GONE);
        }
      }
      );
    }  
    
    
    void mousePressed() {
      if (mouseX >= xbut && mouseX <= xbut + wbut &&  mouseY >= ybut && mouseY <= ybut + hbut) { 
        showInputBox();
      }
    }
    
    void inputButton (int x, int y, float w, float h) {
      textSize(20);
      stroke(127);
      rect(x, y, w, h);
      color c2 = color(130, 0, 0);
      color c1 = color(255, 85, 0);
      for (int i = y; i <= y+h; i++) { 
        float inter = map(i, y, y+h, 0, 1); 
        color c = lerpColor(c1, c2, inter); 
        stroke(c); 
        line(x, i, x+w, i);
      }
      fill(255);
      text("Input", x + 30, y + 25);
    }
    
    
    
    //===========================================================================
    // ANDROID ACTIVITY LIFECYCLE'S FUNCTIONS:
    
    
    //  @@@@@@@@@@@@
    @ Override 
      public void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
    }
    
    //  @@@@@@@@@@@@
    @ Override 
      public void onStart() {
      super.onStart();
      act = this.getActivity();
      mC= act.getApplicationContext();
    
      act.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
    
    
      iButton = new Button(act);
      iButton.setText("InputButton");
      iButton.setBackgroundColor(Color.GREEN);
      iButton.setId(MY_BUTTON1);
      OnClickListener oclMonBouton = new OnClickListener() {
        public void onClick(View v) {
          println("clicked");
          pressed = true;
        }
      };
      iButton.setOnClickListener(oclMonBouton);
    
      edit = new EditText(mC);
      edit.setLayoutParams (
        new RelativeLayout.LayoutParams (
        RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT
        )
        );
      edit.setHint("Write Here!");
      edit.setTextColor(Color.rgb(0, 0, 0));
      edit.setHintTextColor(Color.rgb(170, 170, 170));  
      edit.setBackgroundColor(Color.WHITE);      // edit.getBackground().setAlpha(255);  
      edit.getLayoutParams().width=14*width/26;  
      edit.getLayoutParams().height=height/17; 
      edit.setX(width/3);
      edit.setY(height/6);
      edit.requestFocus();
      edit.setInputType(android.text.InputType.TYPE_CLASS_TEXT);  
      edit.setOnKeyListener(
        new View.OnKeyListener() {
        @ Override
          public boolean onKey(View v, int keyCode, KeyEvent event) {
          if (event.getAction() == KeyEvent.ACTION_DOWN && event.getKeyCode()== KeyEvent.KEYCODE_ENTER) {
            InputMethodManager imm = (InputMethodManager)v.getContext().getSystemService(Context.INPUT_METHOD_SERVICE); 
            imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
            hideInputBox();
            return true;
          }
          return false;
        }
      }
      );
    
      fl = (FrameLayout)act.findViewById(R.id.content);
      FrameLayout.LayoutParams params1 = new FrameLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, Gravity.CENTER);  
      fl.addView(iButton, params1);
      fl.addView(edit);
    
    
      android.view.inputmethod.InputMethodManager imm = (android.view.inputmethod.InputMethodManager) getActivity().getSystemService(android.content.Context.INPUT_METHOD_SERVICE);
      imm.hideSoftInputFromWindow(getActivity().getCurrentFocus().getWindowToken(), 0);
    }
    
    //  @@@@@@@@@@@@
    @ Override 
      public void onResume() {
      super.onResume();
      act = this.getActivity();
      mC= act.getApplicationContext();
      act.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
    }
    
    //  @@@@@@@@@@@@
    @ Override 
      public void onPause() {
      super.onPause();
    }
    
    //  @@@@@@@@@@@@
    @ Override 
      public void onStop() {
      super.onStop();
    }
    
    //  @@@@@@@@@@@@
    @ Override 
      public void onDestroy() {
      super.onDestroy();
    }
    
  • edited February 2018

    Thank you very much for this -almost giving all answers to my questions- code. Sorry that I've still some questions. I do my research but english is not even my second language and I hope you'll bare with me. :) So you used fl = (FrameLayout)act.findViewById(R.id.content); That would make it work on almost every device/api? On what device/api did you tested the code? And then for the button you used instead of iButton = (iButton) findViewById,
    setId(MY_BUTTON1); But why is MY_BUTTON1 9000? I don"t understand the working of this yet. So now I take akenaton's second point. The button, of which you already kindly gave an example. For my one line purpose the code above is sufficient, but @akaneton is right because if I want to write a class for multiple boxes I'll need buttons. But rather then using a simple button I would like to have a custom button using widget's imageButton. My question would be: how link the image in the data folder programmatically rather than using a XML file? And than, in the code below I drew the design into an image() array How can I link this to the button? Notice I still used the findView but I would like to use the setId Thanks in advance.

    import android.content.Context;
    import android.content.Intent;
    import android.content.*;   //View;
    import android.widget.FrameLayout;
    import android.widget.RelativeLayout;
    import android.widget.LinearLayout;  
    import android.graphics.Color;
    import android.view.WindowManager;
    import android.view.inputmethod.InputMethodManager;
    import android.view.View;
    import android.view.ViewGroup;
    import android.view.ViewParent;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.view.ViewGroup.LayoutParams;
    import android.view.Gravity;
    import android.R;
    import android.app.Activity; 
    import android.os.Bundle; 
    import android.widget.ImageButton; 
    
    PGraphics ib; 
    ImageButton myImageButton;
     int xbut, ybut, wbut = 110, hbut = 35;
    
    void setup() {
      fullScreen();
      orientation(LANDSCAPE);
      background(0, 0, 255);
      xbut = width/10;
      ybut = height/6;
      ib = createGraphics(wbut, hbut);
      drawib();
    }
    
    // image(ib, width/?, height/?);   //  How to link?
    
    void draw() {
    }
    
    @ Override
      public void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
    }
    
    @ Override 
      public void onStart() {
      super.onStart();
      act = this.getActivity();
      mC= act.getApplicationContext();
      act.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
      myImageButton = new ImageButton(act);
      myImageButton.setX(xbut);
      myImageButton.setY(ybut);
      myImageButton.setHeight(hbut); 
      myImageButton.setWidth(wbut); 
      myImageButton.setId(MY_BUTTON1); // ??
      fl = (FrameLayout)act.findViewById(R.id.content);
      FrameLayout.LayoutParams params1 = new FrameLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, Gravity.LEFT);  
      fl.addView(myImageButton, params1);
    }
    
    @Override
      public void onCreate(Bundle savedInstanceState) {         
      super.onCreate(savedInstanceState);       
      setContentView(R.layout.main);        
      addListenerOnButton();
    }   
    
    void addListenerOnButton() {        
      myImageButton = (ImageButton) findViewById(    // <<<????  How to link to image()
      myImageButton.setOnClickListener(new OnClickListener() { 
     @Override  
        public void onClick(View arg0) {             
          println("clicked");
        }
      }
      );
    }
    
    void drawib() {
      ib.beginDraw(); 
      ib.textSize(20);
      ib.stroke(127);
      ib.rect (0, 0, ib.width, ib.height); );
      color c2 = color(130, 0, 0);
      color c1 = color(255, 85, 0);
      for (int i = 0; i <= ib.height; i++) { 
        float inter = map(i, 0, ib.height, 0, 1); 
        color c = lerpColor(c1, c2, inter); 
        ib.stroke(c); 
        ib.line(0, i, ib.width, i);
      }
      ib.fill(255);
      ib.text("Input", 30, 25);
      ib.endDraw();
    }
    
  • @noel===

    • as for the first question: yes, though on some devices it's better to add "getWindow().getDecorView()..." - in order to understand better: when Processing creates the fragment in which you are it creates a frameLayout (that s why in have written "fl") and uses the "convert" to add it: setContentView(...)

    • as for the second one: with android each element has an id (which is an integer, sometimes associated with a string); so you can get this element using this id which can be set by XML or by code using ".setId()" - Yet you can create a view, like an imageButton without it: you declare it by name: "ImageButton ib" then make an instance; new()...and can get it by its "name" (ib) when you want, even if you have not set its (integer) id (android creates it for you in the R file)

    • as for the third one: you can set by code the image for your imageButton with ib.setImageResource or setImageBitmap(); as for P5 i think (no tested) that it is better to use the second one, putting the image or images in the assets folder.

Sign In or Register to comment.