【问题标题】:Disable keyboard on EditText在 EditText 上禁用键盘
【发布时间】:2012-05-25 02:00:46
【问题描述】:

我正在做一个计算器。 所以我用数字和函数制作了自己的Buttons。 必须计算的表达式在EditText 中,因为我希望用户也可以在表达式中间添加数字或函数,所以EditText 我有cursor。但是当用户单击EditText 时,我想禁用Keyboard。 我发现这个例子对于Android 2.3 是可以的,但是使用ICS 禁用Keyboard 和光标。

public class NoImeEditText extends EditText {

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

   @Override      
   public boolean onCheckIsTextEditor() {   
       return false;     
   }         
}

然后我在我的XML 文件中使用这个NoImeEditText

<com.my.package.NoImeEditText
      android:id="@+id/etMy"
 ....  
/>

如何使这个 EditText 与 ICS 兼容??? 谢谢。

【问题讨论】:

  • 您是如何制作每个按钮以将文本放置在 EditText 中的正确位置(在文本光标/插入符号上)?

标签: android keyboard android-edittext android-4.0-ice-cream-sandwich


【解决方案1】:

以下代码适用于 API >= 11 和 API

/**
 * Disable soft keyboard from appearing, use in conjunction with android:windowSoftInputMode="stateAlwaysHidden|adjustNothing"
 * @param editText
 */
public static void disableSoftInputFromAppearing(EditText editText) {
    if (Build.VERSION.SDK_INT >= 11) {
        editText.setRawInputType(InputType.TYPE_CLASS_TEXT);
        editText.setTextIsSelectable(true);
    } else {
        editText.setRawInputType(InputType.TYPE_NULL);
        editText.setFocusable(true);
    }
}

【讨论】:

  • 任何想法如何在使用此禁用方法后重新启用键盘?
  • 是的。这是个好问题@kort.es .. 请回答 Aleksey,怎么样?
  • 由于 API >= 11 很常见,同样可以通过xml参数实现:android:inputType="text" android:textIsSelectable="true"
  • 我使用editText.setRawInputType(editText.getInputType()); 而不是简单的editText.setRawInputType(InputType.TYPE_CLASS_TEXT); - 这可以确保维护XML 中的任何inputType 设置。
  • setRawInputType(...)setInputType(0) 好,因为它没有禁用光标。
【解决方案2】:

Here 是一个可以为您提供所需内容的网站

总而言之,它提供了来自 Android 开发者的 InputMethodManagerView 的链接。它将引用ViewhideSoftInputFromWindow() 内部的getWindowToken InputMethodManager

链接中给出了更好的答案,希望对您有所帮助。

这里是一个使用 onTouch 事件的例子:

editText_input_field.setOnTouchListener(otl);

private OnTouchListener otl = new OnTouchListener() {
  public boolean onTouch (View v, MotionEvent event) {
        return true; // the listener has consumed the event
  }
};

这是来自同一网站的另一个示例。这声称有效,但似乎是个坏主意,因为您的 EditBox 为 NULL,它将不再是编辑器:

MyEditor.setOnTouchListener(new OnTouchListener(){

  @Override
  public boolean onTouch(View v, MotionEvent event) {
    int inType = MyEditor.getInputType(); // backup the input type
    MyEditor.setInputType(InputType.TYPE_NULL); // disable soft input
    MyEditor.onTouchEvent(event); // call native handler
    MyEditor.setInputType(inType); // restore input type
    return true; // consume touch even
  }
});

希望这会为您指明正确的方向

【讨论】:

  • 第二个例子是解决方案 :D 谢谢!也适用于 ICS...其他示例仅适用于旧版本的 Android,如 2.3....
  • 不适用于 2.1 中的多行 EditText。经过这样的伎俩,观点扭曲了。滚动和光标也不起作用。
  • 对于这么简单的事情似乎有点破解。
  • 我不知道为什么,但是添加此代码后它不能与光标一起使用:-(
  • etSearchEnglish.setInputType(InputType.TYPE_NULL); // 禁用显示键盘,对我有用!
【解决方案3】:

您也可以直接在 API 21+ 上使用 setShowSoftInputOnFocus(boolean) 或通过 API 14+ 上的反射:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    editText.setShowSoftInputOnFocus(false);
} else {
    try {
        final Method method = EditText.class.getMethod(
                "setShowSoftInputOnFocus"
                , new Class[]{boolean.class});
        method.setAccessible(true);
        method.invoke(editText, false);
    } catch (Exception e) {
        // ignore
    }
}

【讨论】:

  • 这个想法很好,但是它不适用于 API 14-15,但适用于 16+。对于 API 15,可以使用名为“setSoftInputShownOnFocus”的方法。
  • 我对此赞不绝口!!!!感谢Android简单解决了很久的问题!
【解决方案4】:

将以下属性添加到布局文件中的 Edittext 控制器

<Edittext
   android:focusableInTouchMode="true"
   android:cursorVisible="false"
   android:focusable="false"  />

我一直在使用这个解决方案,它对我来说很好。

【讨论】:

  • 这是最快的方法:P
【解决方案5】:
editText.setShowSoftInputOnFocus(false);

【讨论】:

  • 这个答案比其他答案更好,因为我需要我的 EditText 对其他触摸事件有效,比如“setError”消息。禁用焦点也会禁用所有触摸事件。
  • 最后唯一有效的答案。而且就这么简单……
【解决方案6】:

试试:android:editable="false"android:inputType="none"

【讨论】:

    【解决方案7】:

    禁用键盘(API 11 到当前)

    这是迄今为止我找到的禁用键盘的最佳答案(我见过很多)。

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { // API 21
        editText.setShowSoftInputOnFocus(false);
    } else { // API 11-20
        editText.setTextIsSelectable(true);
    }
    

    无需使用反射或将InputType设置为null。

    重新启用键盘

    如果需要,您可以通过以下方式重新启用键盘。

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { // API 21
        editText.setShowSoftInputOnFocus(true);
    } else { // API 11-20
        editText.setTextIsSelectable(false);
        editText.setFocusable(true);
        editText.setFocusableInTouchMode(true);
        editText.setClickable(true);
        editText.setLongClickable(true);
        editText.setMovementMethod(ArrowKeyMovementMethod.getInstance());
        editText.setText(editText.getText(), TextView.BufferType.SPANNABLE);
    }
    

    请参阅此问答,了解为什么需要复杂的 pre API 21 版本来撤消setTextIsSelectable(true)

    这个答案需要更彻底的测试。

    我已经在更高的 API 设备上测试了setShowSoftInputOnFocus,但是在下面@androiddeveloper 的评论之后,我发现这需要进行更彻底的测试。

    这里有一些剪切和粘贴代码来帮助测试这个答案。如果您可以确认它是否适用于 API 11 到 20,请发表评论。我没有任何 API 11-20 设备,而且我的模拟器有问题。

    activity_main.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/activity_main"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:paddingBottom="@dimen/activity_vertical_margin"
        android:paddingLeft="@dimen/activity_horizontal_margin"
        android:paddingRight="@dimen/activity_horizontal_margin"
        android:paddingTop="@dimen/activity_vertical_margin"
        android:orientation="vertical"
        android:background="@android:color/white">
    
        <EditText
            android:id="@+id/editText"
            android:textColor="@android:color/black"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>
    
        <Button
            android:text="enable keyboard"
            android:onClick="enableButtonClick"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>
    
        <Button
            android:text="disable keyboard"
            android:onClick="disableButtonClick"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>
    </LinearLayout>
    

    MainActivity.java

    public class MainActivity extends AppCompatActivity {
    
        EditText editText;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            editText = (EditText) findViewById(R.id.editText);
        }
    
        // when keyboard is hidden it should appear when editText is clicked
        public void enableButtonClick(View view) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { // API 21
                editText.setShowSoftInputOnFocus(true);
            } else { // API 11-20
                editText.setTextIsSelectable(false);
                editText.setFocusable(true);
                editText.setFocusableInTouchMode(true);
                editText.setClickable(true);
                editText.setLongClickable(true);
                editText.setMovementMethod(ArrowKeyMovementMethod.getInstance());
                editText.setText(editText.getText(), TextView.BufferType.SPANNABLE);
            }
        }
    
        // when keyboard is hidden it shouldn't respond when editText is clicked
        public void disableButtonClick(View view) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { // API 21
                editText.setShowSoftInputOnFocus(false);
            } else { // API 11-20
                editText.setTextIsSelectable(true);
            }
        }
    }
    

    【讨论】:

    • 对于旧版本,使用 "setTextIsSelectable" 似乎是一个奇怪的选择。它的名字并不意味着它应该以这种方式工作。你在很多设备上测试过吗?
    • @androiddeveloper,我没有在很多设备上测试它。我现在正在尝试在较低的 API 上对其进行测试,但我的模拟器遇到了问题。如果您或其他任何人可以确认它是否有效,请留下另一条评论。
    • 它在我测试过的少数设备上运行良好,但我发现的反射方法也是如此(写在这里:stackoverflow.com/a/45274277/878126)。一般来说,反射被认为是一种危险的东西,但反射函数的名称比“setTextIsSelectable”更好。
    • @androiddeveloper,具体来说您使用哪个 pre API 21 设备测试setTextIsSelectable
    • 我觉得其中一个叫“Samsung Galaxy Young”。
    【解决方案8】:

    在StackOverflow这里从多个地方收集解决方案,我想下一个总结一下:

    如果您不需要在活动的任何位置显示键盘,您可以简单地使用用于对话框的下一个标志(来自here):

        getWindow().setFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM, WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
    

    如果您不希望它只用于特定的 EditText,您可以使用它(来自 here):

    public static boolean disableKeyboardForEditText(@NonNull EditText editText) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            editText.setShowSoftInputOnFocus(false);
            return true;
        }
        if (Build.VERSION.SDK_INT > Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1)
            try {
                final Method method = EditText.class.getMethod("setShowSoftInputOnFocus", new Class[]{boolean.class});
                method.setAccessible(true);
                method.invoke(editText, false);
                return true;
            } catch (Exception ignored) {
            }
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2)
            try {
                Method method = TextView.class.getMethod("setSoftInputShownOnFocus", boolean.class);
                method.setAccessible(true);
                method.invoke(editText, false);
                return true;
            } catch (Exception ignored) {
            }
        return false;
    }
    

    或者这个(取自here):

     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
               editText.setShowSoftInputOnFocus(false);
           else
               editText.setTextIsSelectable(true); 
    

    【讨论】:

    • 我将尝试更多地测试标志解决方案。您已经在哪些 API 级别上对其进行了测试?
    • “如果你不想要它只是为了......”:我想你的意思是说,“如果你只想要它......”
    • 这是“不想要的”,因为它会阻止键盘显示。不想显示键盘 => 不会显示键盘。
    • 关于 API 级别,我在 Android 6.0.x、4.2.x 和 5.x 上尝试过(具体不记得了)。
    • 好的,我把“它”的意思是禁用,但现在我明白你的意思是键盘。
    【解决方案9】:

    添加到 Alex Kucherenko 解决方案:调用 setInputType(0) 后光标消失的问题是由于 ICS(和 JB)上的框架错误。

    错误记录在这里:https://code.google.com/p/android/issues/detail?id=27609

    要解决此问题,请在调用 setInputType 之后立即调用 setRawInputType(InputType.TYPE_CLASS_TEXT)

    要阻止键盘出现,只需覆盖 EditText 的 OnTouchListener 并返回 true(吞下触摸事件):

    ed.setOnTouchListener(new OnTouchListener() {
    
                @Override
                public boolean onTouch(View v, MotionEvent event) {
    
                    return true;
                }
            });
    

    光标出现在 GB 设备上而不是 ICS+ 上的原因让我把头发扯了几个小时,所以我希望这可以节省一些人的时间。

    【讨论】:

    • setInputType+setRawInputType 不起作用,因为它仍然会显示键盘。使用触摸事件聚焦时。以您所做的方式添加 setOnTouchListener 将解决此问题,但它不允许更改插入符号的位置或文本选择。
    【解决方案10】:

    我找到了适合我的解决方案。当单击 EditText 时,它还会将光标放置在正确的位置。

    EditText editText = (EditText)findViewById(R.id.edit_mine);
    // set OnTouchListener to consume the touch event
    editText.setOnTouchListener(new OnTouchListener() {
    
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                v.onTouchEvent(event);   // handle the event first
                InputMethodManager imm = (InputMethodManager)v.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
                if (imm != null) {
                    imm.hideSoftInputFromWindow(v.getWindowToken(), 0);  // hide the soft keyboard 
                }                
                return true;
            }
        });
    

    【讨论】:

    • 这个实现减慢了我的 Nexus 10 上触摸后的光标反应(大约 1 秒延迟)
    【解决方案11】:
    // only if you completely want to disable keyboard for 
    // that particular edit text
    your_edit_text = (EditText) findViewById(R.id.editText_1);
    your_edit_text.setInputType(InputType.TYPE_NULL);
    

    【讨论】:

    • 由于框架错误,这会导致光标在 ICS+ 设备上消失。请参阅下面的答案以获取可能的解决方案。
    【解决方案12】:

    刚刚设置:

     NoImeEditText.setInputType(0);
    

    或在构造函数中:

       public NoImeEditText(Context context, AttributeSet attrs) { 
              super(context, attrs);   
              setInputType(0);
           } 
    

    【讨论】:

    • 在 Android 2.1-2.3 上这没问题,但在 ICS 中它也会禁用光标 =( 我不知道为什么... =(
    • 我已经检查了我的一个应用程序,你是对的。感谢您的评论
    【解决方案13】:

    这对我有用。 首先将此android:windowSoftInputMode="stateHidden" 添加到您的 android 清单文件中,在您的活动下。如下:

    <activity ... android:windowSoftInputMode="stateHidden">
    

    然后在你的activity的onCreate方法中,添加如下代码:

    EditText editText = (EditText)findViewById(R.id.edit_text);
    edit_text.setOnTouchListener(new OnTouchListener() {
    
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            v.onTouchEvent(event);
            InputMethodManager inputMethod = (InputMethodManager)v.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
            if (inputMethod!= null) {
                inputMethod.hideSoftInputFromWindow(v.getWindowToken(), 0);
            }                
            return true;
        }
    });
    

    然后,如果您希望指针可见,请将其添加到您的 xml android:textIsSelectable="true"

    这将使指针可见。 这样,当您的活动开始时键盘不会弹出,并且当您单击编辑文本时也会隐藏。

    【讨论】:

      【解决方案14】:

      只需将此行放在清单中的活动标记内 android:windowSoftInputMode="stateHidden"

      【讨论】:

        【解决方案15】:

        我不知道这个答案是否更好,但我找到了一个可能更快的解决方案。在 XML 上,只需在 EditText 上加上这个属性:

        android:focusable="true"
        android:focusableInTouchMode="false"
        

        然后用 onClickListener 做你需要做的事情。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-04-20
          • 2017-08-15
          • 2012-09-12
          • 2019-12-14
          • 1970-01-01
          • 2013-09-17
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多