Добавление клавиш * и # к программной клавиатуре - PullRequest
4 голосов
/ 02 февраля 2020

1) ПРОБЛЕМА:

У меня есть EditText , в котором пользователь должен ввести USSD код.

Проблема в том, что для ввода USSD кода пользователь должен переключиться на символьную клавиатуру (два-три раза), что создает очень плохой Пользовательский опыт.

Примеры кодов USSD: * 345 * 77 #, * 333 * 25 #, * 123 * 678 # et c.

<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" /> 

enter image description here

2) Что мне нужно: Как мне заменить выделенные кнопки (ниже) с кнопками * и # без использования пользовательской клавиатуры ?

enter image description here

3) Что я пробовал !!!

1) Все типы ввода для EditText.

2) Google проблема, единственное решение, которое я нашел, это пользовательская клавиатура , но я хочу знать, есть ли простое решение .

1 Ответ

3 голосов
/ 06 февраля 2020

Каждое приложение клавиатуры имеет собственную раскладку, и вы не можете ее изменить. Например, android:inputType="phone" имеет разные макеты на Gboard и SwiftKey. enter image description here

Решение: Вам следует реализовать пользовательскую InAppKeyboard и показать ее пользователю вместо системной клавиатуры. " Создание встроенной клавиатуры для ваших Android Apps " - хороший учебник, в котором описывается как разработать собственную InAppKeyboard, как это, но вы можете создать желаемый макет и легко использовать его в своем приложении.

enter image description here

Обновление: Для использования InAppKeyboard с диалогом у меня есть идея. Я разработал пользовательский DialogFragment , который состоит из 2 частей:
1. Часть содержимого диалога
2. Пользовательская часть клавиатуры с именем CustomKeyboardDialog.
Вы можете расширить этот класс и создать свой собственный диалог. Доступны оба метода setContentView и findViewById, и вы можете использовать их для управления диалоговым интерфейсом. Вы должны переопределить метод onCreate в своей пользовательской реализации диалога и вызвать setContentView там. Затем переопределите метод onCreateView, вызовите там findViewById, найдите ваш EditText и присоедините его к пользовательской клавиатуре, вызвав метод attachToCustomKeyboard. 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>

Вот пример реализации пользовательского диалога: 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>

и выглядит так:

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...