Slarti Bartfast Slarti Bartfast - 3 months ago 17
Android Question

Long-press on Button to Change Text

I have several buttons in my app which have single character numbers on them (such as '1','2', '3', ...). As it is, when the user clicks a button the text on that button changes from a digit to a letter (such as 'A', 'B' or 'C'...) and will change back should the user click it again. This all works well and good as the characters and digits are essentially hard programmed into the app however I am wanting to enable the user to enter 'custom' characters displayed on buttons through the use of a long-click. For instance, instead of the first button only showing '1' or 'A' I would like for the user to be able to do a long press on the button and select say 'X' from the keyboard then have the button display this value.

I have done a lot of searching on how to do this but all the examples I come across all refer to reading input for an EditText rather than a Button (or TextView). I have attempted to use an "InputMethodManager" as discussed in the Developer Docs (as well as many other places) but I don't really understand how it should be used and simply copying the example code into my 'onLongClick(...)' method doesn't work, and probably isn't the right approach anyhow.

Probably the most promising lead I've been able to find is this one called Possbile to long press button and change its text in Android, which contains the comment:


You can't put a cursor on a button. You could put an edittext behind the button and when long clicking on the button you could make the button invisible and then focus the Edittext. After typing your text in the edittext in onFocusChanged() of the edittext make the button reappear and then set the text from the edittext to the button


Which sounds promising though the thread is a little short on details.

As it is I have extended the regular Button class to handle my requirements so I can add a dummy EditText to my 'CustomButton' if that will get me through.

If it's of any value here is my feeble attempt to capture keyboard input with a dummy EditText:

private class MyLongClickListener implements View.OnLongClickListener {
@Override
public boolean onLongClick(final View view) {
final CustomButton button = (CustomButton) view;

EditText editText = button.getEditText();

if (editText.requestFocus()) {
InputMethodManager imm = (InputMethodManager)
getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
imm.showSoftInput(view, InputMethodManager.SHOW_IMPLICIT);
}

return true;
}
}


But execution just blows right through the
showSoftInput
and exits the method without showing anything, and certainly doesn't give any opportunity to enter a character.

What would be the best way to implement this?

Answer Source

I would do it this way.

Create a custom view that contains a Button and an EditText.

public class MyView extends RelativeLayout {


public MyView(Context context, AttributeSet attrs) {
    super(context, attrs);
    addViews();
}

public MyView(Context context) {
    super(context);
    addViews();
}

private void addViews() {
    View view = inflate(getContext(), R.layout.my_layout, null);
    addView(view);
}
}

my_layout.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<EditText
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/editText"
    android:layout_gravity="center_horizontal"
    android:visibility="gone"
    android:singleLine="true"/>

<TextView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:text="Some Text"
    android:id="@+id/textView"
    android:layout_gravity="center_horizontal"
    android:textAlignment="center"
    android:textStyle="bold"
    android:textSize="30sp" />

</RelativeLayout>

and change onLongClickListener like this

 private class MyLongClickListener implements View.OnLongClickListener {
  EditText editText;
  TextView textView ;
 @Override
        public boolean onLongClick(View view) {
            editText =(EditText) view.findViewById(R.id.editText);
            textView =(TextView) view.findViewById(R.id.textView);
            editText.bringToFront();
            textView.setVisibility(View.INVISIBLE);
            editText.setVisibility(View.VISIBLE);
            if (editText.requestFocus()) {
                InputMethodManager imm = (InputMethodManager)
                        getApplicationContext().getSystemService(Context.INPUT_METHOD_SERVICE);
                imm.showSoftInput(editText, InputMethodManager.SHOW_IMPLICIT);

            }
            textView.setText(editText.getText().toString());
            editText.setOnEditorActionListener(new TextView.OnEditorActionListener() {
                @Override
                public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
                    if(actionId== EditorInfo.IME_ACTION_DONE){
                        editText.setVisibility(View.INVISIBLE);
                        textView.bringToFront();
                        textView.setVisibility(View.VISIBLE);
                        textView.setText(editText.getText().toString());
                    }
                    return false;
                }
            });

            return true;
        }
}

Hope this helps.