Adding * and # key to the soft keyboard

[亡魂溺海] 提交于 2021-02-18 12:45:11

问题


1) PROBLEM:

I have an EditText in which the user has to enter USSD code.

Problem is, for entering USSD code the user has to switch to symbol keyboard (two to three times) which creates a very bad user experience.

USSD Code Examples: *345*77#, *333*25#, *123*678# etc.

<EditText
        android:id="@+id/field_code"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:imeActionId="@integer/imo_action_search"
        android:imeOptions="actionSearch"
        android:inputType="phone" /> 

2) What I need: How can I replace the highlighted buttons (below image) with * and # buttons without using a custom keyboard?

3) What I have tried!!!

1) All InputTypes for EditText.

2) Google the issue, the only solution I have found is a custom keyboard but I want to know is there any simple solution.


回答1:


Each keyboard app has its own layout and you can't change it. For example android:inputType="phone" has different layouts on Gboard and SwiftKey.

Solution:
You should implement a custom InAppKeyboard and show it to the user instead of the system keyboard."Creating an In-App Keyboard for your Android Apps" is a good tutorial that describes how to develop a custom InAppKeyboard like this but you can design your desired layout and use it in your app easily.



Update:
For Using InAppKeyboard with dialog, I have an idea. I developed a custom DialogFragment which has 2 parts:
1. The dialog content part
2. The custom keyboard part named CustomKeyboardDialog.
You can extend this class and create your custom dialog. Both setContentView and findViewById methods are available and you can use them to manage your dialog UI. You must override onCreate method in your custom dialog implementation and call setContentView there. Then override onCreateView method, call findViewById there and find your EditText and attach it custom keyboard by calling attachToCustomKeyboard method. CustomKeyboardDialog.java

public abstract class CustomKeyboardDialog extends DialogFragment {

    private View mRootView;
    private int mContentLayoutResID;
    private View mContentView;
    private CustomKeyboardView mCustomKeyboardView;

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Override
    public void onStart() {
        super.onStart();
        Dialog dialog = getDialog();
        if (dialog != null) {
            dialog.getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
            dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
        }
    }

    @Nullable
    @Override
    final public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        super.onCreateView(inflater, container, savedInstanceState);
        mRootView = inflater.inflate(R.layout.dialog_custom_keyboard, container, false);

        ViewGroup contentViewContainer = mRootView.findViewById(R.id.content_view_container);
        mContentView = inflater.inflate(mContentLayoutResID, contentViewContainer, true);

        this.mCustomKeyboardView = mRootView.findViewById(R.id.keyboard_view);

        this.onCreateView(mContentView);

        return mRootView;
    }

    public View findViewById(int id) {
        return mContentView.findViewById(id);
    }

    public void setContentView(@LayoutRes int layoutResID) {
        this.mContentLayoutResID = layoutResID;
    }

    public void showKeyboard(InputConnection inputConnection) {
        mCustomKeyboardView.setInputConnection(inputConnection);
        mCustomKeyboardView.setVisibility(View.VISIBLE);
        mCustomKeyboardView.animate().translationY(0).setListener(new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(Animator animation) {

            }

            @Override
            public void onAnimationEnd(Animator animation) {
                updateContentViewSize(true);
            }

            @Override
            public void onAnimationCancel(Animator animation) {

            }

            @Override
            public void onAnimationRepeat(Animator animation) {

            }
        });
    }

    public void hideKeyboard() {
        updateContentViewSize(false);
        mCustomKeyboardView.animate().translationY(mCustomKeyboardView.getMeasuredHeight()).setListener(null);
    }

    private void updateContentViewSize(boolean keyboardVisible) {
        ConstraintLayout.LayoutParams layoutParams = (ConstraintLayout.LayoutParams) mContentView.getLayoutParams();
        if(keyboardVisible) {
            layoutParams.bottomToTop = R.id.keyboard_view;
            layoutParams.bottomToBottom = ConstraintLayout.LayoutParams.UNSET;
        } else {
            layoutParams.bottomToBottom = ConstraintLayout.LayoutParams.PARENT_ID;
            layoutParams.bottomToTop = ConstraintLayout.LayoutParams.UNSET;
        }
        mContentView.setLayoutParams(layoutParams);
    }

    public void onCreateView(View contentView) {

    }

    @Override
    public void onResume() {
        super.onResume();
        getDialog().setOnKeyListener(new DialogInterface.OnKeyListener()
        {
            @Override
            public boolean onKey(android.content.DialogInterface dialog, int keyCode,android.view.KeyEvent event) {
                if ((keyCode ==  android.view.KeyEvent.KEYCODE_BACK))
                {
                    if(mCustomKeyboardView.getVisibility() == View.VISIBLE)
                        hideKeyboard();
                    return true;
                }
                else
                    return false;
            }
        });
    }

    @Override
    public void onPause() {
        super.onPause();
        getDialog().setOnKeyListener(null);
    }

    public void attachToCustomKeyboard(EditText editText) {
        editText.setShowSoftInputOnFocus(false);
        editText.setOnFocusChangeListener(new View.OnFocusChangeListener() {
            @Override
            public void onFocusChange(View v, boolean hasFocus) {
                if (hasFocus) {
                    showKeyboard(editText.onCreateInputConnection(new EditorInfo()));
                }
            }
        });
        editText.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                showKeyboard(editText.onCreateInputConnection(new EditorInfo()));
            }
        });
    }

    public void detachFromCustomKeyboard(EditText editText) {
        editText.setShowSoftInputOnFocus(true);
        editText.setOnFocusChangeListener(null);
        editText.setOnClickListener(null);
    }
}

dialog_custom_keyboard.xml

<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <LinearLayout
        android:id="@+id/content_view_container"
        android:background="@android:color/transparent"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toTopOf="@id/keyboard_view"
        android:orientation="vertical"
        android:gravity="center">
    </LinearLayout>

    <mirm.test.testapp.dialog.CustomKeyboardView
        android:id="@+id/keyboard_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_constraintBottom_toBottomOf="parent"
        android:background="#eee"
        />

</androidx.constraintlayout.widget.ConstraintLayout>

CustomKeyboardView.java

public class CustomKeyboardView extends LinearLayout implements View.OnClickListener {

    private Button button1, button2, button3, button4,
            button5, button6, button7, button8,
            button9, button0, buttonDelete, buttonEnter, buttonSharp, buttonStar;

    private SparseArray<String> keyValues = new SparseArray<>();
    private InputConnection inputConnection;

    public CustomKeyboardView(Context context) {
        this(context, null, 0);
    }

    public CustomKeyboardView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public CustomKeyboardView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context, attrs);
    }

    private void init(Context context, AttributeSet attrs) {
        setOrientation(VERTICAL);
        LayoutInflater.from(context).inflate(R.layout.custom_keyboard_layout, this, true);
        button1 = (Button) findViewById(R.id.button_1);
        button1.setOnClickListener(this);
        button2 = (Button) findViewById(R.id.button_2);
        button2.setOnClickListener(this);
        button3 = (Button) findViewById(R.id.button_3);
        button3.setOnClickListener(this);
        button4 = (Button) findViewById(R.id.button_4);
        button4.setOnClickListener(this);
        button5 = (Button) findViewById(R.id.button_5);
        button5.setOnClickListener(this);
        button6 = (Button) findViewById(R.id.button_6);
        button6.setOnClickListener(this);
        button7 = (Button) findViewById(R.id.button_7);
        button7.setOnClickListener(this);
        button8 = (Button) findViewById(R.id.button_8);
        button8.setOnClickListener(this);
        button9 = (Button) findViewById(R.id.button_9);
        button9.setOnClickListener(this);
        button0 = (Button) findViewById(R.id.button_0);
        button0.setOnClickListener(this);
        buttonDelete = (Button) findViewById(R.id.button_delete);
        buttonDelete.setOnClickListener(this);
        buttonEnter = (Button) findViewById(R.id.button_enter);
        buttonEnter.setOnClickListener(this);
        buttonSharp = (Button) findViewById(R.id.button_sharp);
        buttonSharp.setOnClickListener(this);
        buttonStar = (Button) findViewById(R.id.button_star);
        buttonStar.setOnClickListener(this);

        keyValues.put(R.id.button_1, "1");
        keyValues.put(R.id.button_2, "2");
        keyValues.put(R.id.button_3, "3");
        keyValues.put(R.id.button_4, "4");
        keyValues.put(R.id.button_5, "5");
        keyValues.put(R.id.button_6, "6");
        keyValues.put(R.id.button_7, "7");
        keyValues.put(R.id.button_8, "8");
        keyValues.put(R.id.button_9, "9");
        keyValues.put(R.id.button_0, "0");
        keyValues.put(R.id.button_enter, "\n");
        keyValues.put(R.id.button_sharp, "#");
        keyValues.put(R.id.button_star, "*");
    }

    @Override
    public void onClick(View view) {
        if (inputConnection == null)
            return;

        if (view.getId() == R.id.button_delete) {
            CharSequence selectedText = inputConnection.getSelectedText(0);

            if (TextUtils.isEmpty(selectedText)) {
                inputConnection.deleteSurroundingText(1, 0);
            } else {
                inputConnection.commitText("", 1);
            }
        } else {
            String value = keyValues.get(view.getId());
            inputConnection.commitText(value, 1);
        }
    }

    public void setInputConnection(InputConnection ic) {
        inputConnection = ic;
    }
}

custom_keyboard_layout.xml

<merge xmlns:android="http://schemas.android.com/apk/res/android">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">
        <Button
            android:id="@+id/button_1"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="1"/>

        <Button
            android:id="@+id/button_2"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="2"/>

        <Button
            android:id="@+id/button_3"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="3"/>

        <Button
            android:id="@+id/button_4"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="4"/>

        <Button
            android:id="@+id/button_5"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="5"/>

    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <Button
            android:id="@+id/button_6"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="6"/>

        <Button
            android:id="@+id/button_7"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="7"/>

        <Button
            android:id="@+id/button_8"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="8"/>

        <Button
            android:id="@+id/button_9"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="9"/>

        <Button
            android:id="@+id/button_0"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="0"/>
    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <Button
            android:id="@+id/button_sharp"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="#"/>

        <Button
            android:id="@+id/button_star"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="*"/>

        <Button
            android:id="@+id/button_delete"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1.3"
            android:text="Delete"/>

        <Button
            android:id="@+id/button_enter"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1.7"
            android:text="Enter"/>

    </LinearLayout>
</merge>

Here is an example of custom dialog implementation:
SampleDialog.java

public class SampleDialog extends CustomKeyboardDialog {

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.sample_dialog);
    }

    @Nullable
    @Override
    public void onCreateView(View contentView) {
        EditText editText = (EditText) findViewById(R.id.edittext);
        attachToCustomKeyboard(editText);
    }
}

sample_dialog.xm

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginRight="50dp"
    android:layout_marginLeft="50dp"
    android:background="#eee">

    <LinearLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="32dp">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Enter Code"></TextView>

    <EditText
        android:id="@+id/edittext"
        android:hint="example: *455*415#"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

        <Button
            android:text="Send"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>

    </LinearLayout>
</LinearLayout>

and it looks like this:



来源:https://stackoverflow.com/questions/60023835/adding-and-key-to-the-soft-keyboard

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!