软键盘添加*和#键

2024-01-12

1)问题:

我有一个EditText用户必须在其中输入USSD code.

Problem是,用于输入USSD用户必须切换到的代码符号键盘(两到三次)这会造成非常糟糕的用户体验。

USSD 代码示例:*345*77#、*333*25#、*123*678#等

<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)我需要什么:我怎么能够replace突出显示的按钮(下图)与 * 和#按钮而不使用定制键盘?

3)我已经尝试过了!!!

1) EditText 的所有输入类型。

2)谷歌这个问题,我找到的唯一解决方案是定制键盘 但我想知道有什么简单的解决方案.


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.

enter image description here

解决方案:
您应该实现一个自定义的 InAppKeyboard 并将其显示给用户而不是系统键盘。”为您的 Android 应用程序创建应用程序内键盘 https://medium.com/@ssaurel/creating-an-in-app-keyboard-for-your-android-apps-a0a6c6e1e289” 是一个很好的教程,描述了如何开发这样的自定义 InAppKeyboard,但您可以设计所需的布局并在您的应用程序中轻松使用它。



Update:
对于将 InAppKeyboard 与对话框一起使用,我有一个想法。我开发了一个自定义对话框片段 https://developer.android.com/reference/androidx/fragment/app/DialogFragment它有 2 部分:
1.对话框内容部分
2.自定义键盘部分命名CustomKeyboardDialog.
您可以扩展此类并创建自定义对话框。两个都setContentView and findViewById方法可用,您可以使用它们来管理您的对话框 UI。您必须覆盖onCreate自定义对话框实现中的方法并调用setContentView那里。然后覆盖onCreateView方法,调用findViewById在那里找到你的 EditText 并通过调用附加它自定义键盘attachToCustomKeyboard方法。自定义键盘对话框.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);
    }
}

对话框_自定义_键盘.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>

自定义KeyboardView.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;
    }
}

自定义键盘布局.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>

以下是自定义对话框实现的示例:
示例对话框.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);
    }
}

样本对话框.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>

它看起来像这样:

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

软键盘添加*和#键 的相关文章

随机推荐

  • JavaScript 可以从第三方域加载 XML 数据吗?

    JavaScript 可以从以下位置加载 RSS XML 提要吗Yahoo http finance yahoo com rss topstories 客户端JS是否允许访问第3方域 您可以使用我的博客文章中概述的技术雅虎查询语言不成文指南
  • IIS 中具有匿名身份验证的 FTP 网站需要用户名和密码

    我在 IIS 8 中有一个 FTP 网站 我想向公众 未经身份验证的访问者 公开该网站 该网站是使用以下设置进行配置的here http technet microsoft com en us library hh831655 aspx N
  • ViewModel - 在运行时观察 LiveData 时更改方法参数?

    我正在尝试弄清楚 MVVM 这对我来说非常新 并且我弄清楚了如何使用 Room 和 ViewModel 观察 LiveData 现在我面临一个问题 我有一个需要参数的 Room 查询 这就是我开始观察 MainActivity 中 onCr
  • 使用 CSS 控制
     中的制表符空间?                
                

    是否可以指定制表符空间占用多少像素等 pre 使用CSS 例如 假设我有一段代码出现在 pre 在网页上 function Image this Write function document write this ToString ret
  • 如何使用 MVC Azure AD 身份验证从 AD 获取角色?

    我设置了 MVC 4 应用程序 并添加了针对我们的 Azure AD 服务器的身份验证 如下所述 http msdn microsoft com en us library windowsazure dn151790 aspx http m
  • 如何创建真实的 .scn 文件?

    查看苹果示例 AR 应用程序 有许多看起来很逼真的物体 杯子 蜡烛等 然而 在 Xcode 上使用场景工具包编辑器时 很明显这仅允许您创建基本对象 我的问题是 什么软件 文件可以用来创建现实的scn物体 我确信有软件可以让您创建 3D 模型
  • Vue - 是否可以动态设置 html 元素的样式?

    简洁版本 In the data 在我的应用程序中 我定义了某些颜色 我想要html 元素的背景为这些颜色之一 基于switch陈述 长版 In the data 我有以下代码 data return item color1 color2
  • 使用 Shibboleth 进行单点登录

    我必须使用以下方法在我的 NET 3 5 项目中实现单点登录希博莱斯 详细要求是这样的 1 我使用 NET 3 5 开发了一个名为 abc com 的Web应用程序 2 有一些第三方应用程序将从 abc com 启动 3 如果我已经登录到
  • React 错误边界无法捕获错误

    我创建了我的反应应用程序vite在那里我有我的自定义反应错误边界组件从组件包装 事情是它无法捕获错误 我调试我的错误组件 但它无法接收任何值getDerivedStateFromError not componentDidCatch 这是我
  • python 修改方法内的字典

    是否可以在不将字典作为参数传递的情况下修改函数内字典的值 我不想返回字典 而只想修改它的值 这是可能的 但不一定是可取的 我无法想象为什么你不想传递或返回字典 如果你只是不想返回字典 但可以传递它 你可以修改它以反映在原始字典而不必返回它
  • 执行 Espresso 测试时更改区域设置

    我正在创建一个简单的布局 应该支持阿拉伯语言和 RTL 布局 一切正常 现在我想编写一个 Espresso 测试并断言它是否实际显示翻译后的文本 例如对于阿拉伯语 它应该显示阿拉伯语 strings xml 中的文本 到目前为止 我尝试了以
  • golang解码嵌套结构中的JSON请求并将其作为blob插入数据库

    我有一个嵌套结构 用于解码 JSON 请求 type Service struct ID string json id omitempty db id Name string json name db name Contract struc
  • Python随机播放列表不起作用[重复]

    这个问题在这里已经有答案了 我是Python新手 具有 C 背景的我很难理解这种语言的简单性 更不用说 IDLE 是如何工作的了 无论如何 我需要编写一个简单的函数 它接受一个列表并返回一个新列表 其中的元素已打乱顺序 这就是我到目前为止所
  • 如何在 lwuit TextField 或组合框中添加日历

    我正在使用 lwuit 创建一个应用程序 我想在组合框中添加日历 请尽快给我一个想法 您的意思是要在组合框值的末尾添加日历组件的选定日期还是在文本框中显示选定的日期 如果是这样 那么下面的代码将在文本框中显示日历组件的选定日期 Button
  • 检查当前线程是否为主线程

    Objective C 有没有办法检查当前线程是否是主线程 我想做这样的事情 void someMethod if IS THIS MAIN THREAD NSLog ok this is main thread else NSLog do
  • Android Studio 0.5.3 - 为什么“Make Project”不再运行构建?

    自从我升级到 0 5 3 以来 Android Studio 中的 Make Project 没有为我构建 apk 文件 有谁知道我怎样才能做到这一点 我已将 buildToolsVersion 更新为 19 0 3 这是最新版本 每次 A
  • 错误:未找到默认活动,但已声明它

    我遇到过两次奇怪的情况 我的主模块中有清单 igs main
  • Scala 特性 mixin order 和 super call

    我有这个代码 trait base def msg Unit println base trait foo extends base abstract override def msg Unit super msg println foo
  • 将数据帧拆分为分组块

    我想将数据帧分割成块 我创建了一个函数 它能够将数据帧分割成相同大小的块 但是我无法弄清楚如何按组分割 数据帧的每个分割必须包含分组变量的所有实例 我希望能够灵活地确定可以包含多少个组 因为它们相对较小 示例数据框 A 1 A 2 B 3
  • 软键盘添加*和#键

    1 问题 我有一个EditText用户必须在其中输入USSD code Problem是 用于输入USSD用户必须切换到的代码符号键盘 两到三次 这会造成非常糟糕的用户体验 USSD 代码示例 345 77 333 25 123 678 等