【问题标题】:Implementing onKeyPreIme(int keyCode, KeyEvent event) in Fragment在 Fragment 中实现 onKeyPreIme(int keyCode, KeyEvent event)
【发布时间】:2012-11-15 11:22:49
【问题描述】:

我不知道如何在 Fragment 中实现 onKeyPreIme(int keyCode, KeyEvent event)

@Override
public boolean onKeyPreIme(int keyCode, KeyEvent event) {
    if (keyCode == KeyEvent.KEYCODE_BACK && 
        event.getAction() == KeyEvent.ACTION_UP) {
            // do your stuff
            return false;
    }
    return super.dispatchKeyEvent(event);
}

我尝试了很多,但没有任何效果。另外,我在 Google 或 Stack Overflow 上找不到任何东西。我想在按下返回键并且软键盘启动时执行一个操作。在我的EditTexts 上设置onKeyListener 不起作用,因为当软键盘启动时不会调用KeyEvent.KEYCODE_BACK。感谢任何帮助和源代码。

【问题讨论】:

  • 感谢您的代码,了解返回 super.dispatchKeyEvent(event); 活动的后退按钮将起作用,这很有帮助!

标签: android fragment android-softkeyboard


【解决方案1】:

这是我的解决方案,对我来说效果很好,但每个人的需求不同。

首先,我将 EditText 子类化并连接了一个侦听器(Google 应该将其设为默认值)

public class ListenerEditText extends EditText {

    private KeyImeChange keyImeChangeListener;

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

    public void setKeyImeChangeListener(KeyImeChange listener){
        keyImeChangeListener = listener;
    }

    public interface KeyImeChange {
        public void onKeyIme(int keyCode, KeyEvent event);
    }

    @Override
    public boolean onKeyPreIme (int keyCode, KeyEvent event){
        if(keyImeChangeListener != null){
            keyImeChangeListener.onKeyIme(keyCode, event);
        }        
        return false;
    }
}

然后你可以像这样从任何地方附加一个监听器:

myListenerEditText.setKeyImeChangeListener(new KeyImeChange() {

    @Override
    public void onKeyIme(int keyCode, KeyEvent event) {
        // All keypresses with the keyboard open will come through here!
        // You could also bubble up the true/false if you wanted 
        // to disable propagation.
    }
});

【讨论】:

  • 这看起来是最好的答案,因为它实际上可以覆盖 onKeyPreIme。我不想问,但我在让它工作时遇到了问题。我扩展了 AutoCompleteTextView 并在我的活动(您的第二个代码块)中的 onKeyIme(...) 中添加了一个返回语句。除此之外,我已经完全复制了您的代码,并在“return”语句和新类中的每个方法上设置了断点。调用 setKeyImeChangeListener 并初始化 keyImeChangeListener,但是,按下键时永远不会调用 onKeyIme()。有什么想法可以从哪里开始进行故障排除?
  • 好的,我想我明白了。这些键盘事件适用于物理键盘,而不是软键盘。任何人都可以确认吗?谢谢。
  • 顺便说一句,我仍然是 Android 的学生,所以感谢这段代码。我能够使用它来覆盖 onFilterComplete 方法。 Android 不为这些事件提供侦听器似乎有点愚蠢。
  • 我也没有看到我的 onKeyIme 方法被调用。这对软键盘有用吗?
【解决方案2】:

我能够通过对与键盘输入相关的 EditText 视图进行子类化来实现 onKeyPreIme。目标是制作用户必须输入密码或离开应用程序的自定义锁屏。当用户点击“键盘向下”按钮时,键盘不会消失。

确保为子类 EditText 创建一个单独的 .java 文件。另外,请务必使用下面代码中的构造函数(必须通过 AttrubuteSet)。

我意识到我的 onKeyPreIme 实现可能与您的不匹配,但它确实演示了如何在 InputMethodManager 执行此操作之前拦截键盘事件。

我希望这会有所帮助。

屏幕截图 UserLockActivity

EditText 子类

public class LockEditText extends EditText {
    /* Must use this constructor in order for the layout files to instantiate the class properly */
    public LockEditText(Context context, AttributeSet attrs) 
    {
        super(context, attrs);
        // TODO Auto-generated constructor stub
    }

    @Override
    public boolean onKeyPreIme (int keyCode, KeyEvent event)
    {
        // Return true if I handle the event:
            // In my case i want the keyboard to not be dismissible so i simply return true
            // Other people might want to handle the event differently
        System.out.println("onKeyPreIme " +event);
        return true;
    }

}

UserLockActivity.java

public class UserLockActivity extends Activity 
{
    private LockEditText editText1;
    private LockEditText editText2;
    private LockEditText editText3;
    private LockEditText editText4;
    @Override
    protected void onCreate(Bundle savedInstanceState) 
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_user_lock);
        editText1 = (LockEditText) findViewById(R.id.lock_text_1);
        editText2 = (LockEditText) findViewById(R.id.lock_text_2);
        editText3 = (LockEditText) findViewById(R.id.lock_text_3);
        editText4 = (LockEditText) findViewById(R.id.lock_text_4);
        setupTextChangedListener(editText1);
        setupTextChangedListener(editText2);
        setupTextChangedListener(editText3);
        setupTextChangedListener(editText4);
        // A method to bring out the keyboard when the view appears
        setFocusOnEditText(editText1);
    }

    public void setFocusOnEditText(LockEditText editText)
    {
        editText.clearFocus();
        editText.requestFocus();
        InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);

        imm.toggleSoftInput(InputMethodManager.SHOW_FORCED,0);
    }
    public void setupTextChangedListener(LockEditText editText)
    {
        editText.addTextChangedListener(new TextWatcher() 
        {
            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) 
            {

            }

            @Override
            public void afterTextChanged(Editable arg0) 
            {
                // TODO Auto-generated method stub
            }

            @Override
            public void beforeTextChanged(CharSequence arg0, int arg1,int arg2, int arg3) 
            {
                // TODO Auto-generated method stub
            }
        });
    }
}

activity_user_lock.xml 布局文件

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    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"
    tools:context=".UserLockActivity" >

    <TextView
        android:id="@+id/main_lock_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_alignParentTop="true"
        android:paddingTop="60dp"
        android:paddingBottom="20dp"
        android:text="@string/enter_passcode"
        android:textAppearance="?android:attr/textAppearanceLarge" />

    <LinearLayout
        android:id="@+id/lock_input_layout"
        android:layout_width="match_parent"
        android:layout_height="60dp"
        android:layout_below="@+id/main_lock_text"
        android:orientation="horizontal" >

        <com.yourpackage.yourappname.LockEditText
            android:id="@+id/lock_text_1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            android:layout_weight="1"
            android:ems="10"
            android:inputType="numberPassword"
            android:textSize="30sp"
            android:gravity="center_horizontal"
            android:textStyle="bold" >
        </com.yourpackage.yourappname.LockEditText>
        <com.yourpackage.yourappname.LockEditText
            android:id="@+id/lock_text_2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            android:layout_weight="1"
            android:ems="10"
            android:inputType="numberPassword"
            android:textSize="30sp"
            android:gravity="center_horizontal"
            android:textStyle="bold" >
        </com.yourpackage.yourappname.LockEditText>
        <com.yourpackage.yourappname.LockEditText
            android:id="@+id/lock_text_3"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            android:layout_weight="1"
            android:ems="10"
            android:inputType="numberPassword"
            android:textSize="30sp" 
            android:gravity="center_horizontal"
            android:textStyle="bold">
        </com.yourpackage.yourappname.LockEditText>
        <com.yourpackage.yourappname.LockEditText
            android:id="@+id/lock_text_4"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            android:layout_weight="1"
            android:ems="10"
            android:inputType="numberPassword"
            android:textSize="30sp"
            android:gravity="center_horizontal"
            android:textStyle="bold" >
        </com.yourpackage.yourappname.LockEditText>
    </LinearLayout>

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/lock_input_layout"
        android:layout_centerHorizontal="true"
        android:text="text" />

</RelativeLayout>

【讨论】:

  • 它与我的意图不符,但你的想法很有创意,所以我会接受你的回答
  • 精湛的@i2097i。谢谢哥们:)
  • @i2097i 我有一个问题。 android中是否有任何方法可以以编程方式从EditText 移除焦点
  • 此解决方案效果很好,但它适用于活动。要添加到 Fragment,您必须在实例化 InputMethodManager 时获取活动。所以对于这一行: InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);添加一个getActivity。在 getSystemService 之前。所以它看起来像这样: InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
【解决方案3】:

我无法弄清楚如何实现 onKeyPreIME,但我能够在键盘消失后使用以下代码执行操作:

您需要更改比较 heightDiff > 200。这个比较对我有用,因为我有一个滚动视图。

fragmentView.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {

        @Override
        public void onGlobalLayout() {
            if(getView() != null){
                int heightDiff = getView().getRootView().getHeight() - getView().getHeight();
                if (heightDiff < 200) { 
                    rlupdate.setVisibility(RelativeLayout.VISIBLE);
                }
                else {
                    rlupdate.setVisibility(RelativeLayout.GONE);
                }   
            }
        }
    });

【讨论】:

    【解决方案4】:

    这是 Deminetix 提供的更完整的答案代码。

    我已经使用 Deminetix 的答案来过滤 android 上的手持条形码阅读器并得到结果。

    为了使它只能在带有按钮的屏幕上使用,我添加了一个带有 android:textColor="#FF000000" android:background="#00FFFFFF" android:enabled="false" 的 EditText 禁用的 EditText 仍会收到键盘事件。

    我可以选择使用以下方法隐藏软件键盘,但禁用 EditText 后就不需要了。

    //InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
    //imm.showSoftInput(textPatientId, InputMethodManager.HIDE_IMPLICIT_ONLY);
    

    MainActivity.java:

    package com.doodkin.keyboardtest;
    
    import com.doodkin.keyboardtest.ListenerEditText.KeyImeChange;
    
    import android.os.Bundle;
    import android.app.Activity;
    import android.text.Editable;
    import android.text.TextWatcher;
    import android.text.method.KeyListener;
    import android.util.Log;
    import android.view.InputDevice;
    import android.view.KeyEvent;
    import android.view.Menu;
    import android.view.View;
    import android.view.View.OnKeyListener;
    import android.widget.EditText;
    
    public class MainActivity extends Activity {
        private static final String TAG = "keyboard test";
        //private EditText editText1;
    
        ListenerEditText editText1=null;
        public String barcodebuffer="";
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            editText1 = (ListenerEditText) findViewById(R.id.editText1);
    
            editText1.setKeyImeChangeListener(new KeyImeChange() {
    
                @Override
                public boolean onKeyIme(int keyCode, KeyEvent event) {
                    String deviceName=event.getDevice().getName();
                    int keyboardType=event.getDevice().getKeyboardType();
                    int indexof=deviceName.indexOf("USB");
                    if(indexof!=-1 && keyboardType==InputDevice.KEYBOARD_TYPE_NON_ALPHABETIC)
                    {
                        if(event.getKeyCode()==KeyEvent.KEYCODE_ENTER)
                         {
                             if(barcodebuffer!="")
                             {
                                 Log.d(TAG, "filterBarcodeKeys Chars Flush: " + barcodebuffer );
                                 barcodebuffer="";
                             }
                         }
                         else
                         {
    
                             barcodebuffer+=Character.toString((char)event.getUnicodeChar());
                             //Log.d(TAG, "filterBarcodeKeys Char: " + Character.toString((char)event.getUnicodeChar()) );
                         }
                         return true;
                    }
                    return false;
                }
            });
    
    
        }
    
        @Override
        public boolean onCreateOptionsMenu(Menu menu) {
            // Inflate the menu; this adds items to the action bar if it is present.
            getMenuInflater().inflate(R.menu.main, menu);
            return true;
        }
    
    
    }
    

    activity_main.xml:

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        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"
        tools:context=".MainActivity" >
    
        <TextView
            android:id="@+id/textView1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/hello_world" />
    
        <com.doodkin.keyboardtest.ListenerEditText
            android:id="@+id/editText1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignLeft="@+id/textView1"
            android:layout_below="@+id/textView1"
            android:ems="10" >
    
            <requestFocus />
        </com.doodkin.keyboardtest.ListenerEditText>
    
        <Button
            android:id="@+id/button1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignLeft="@+id/editText1"
            android:layout_below="@+id/editText1"
            android:layout_marginTop="69dp"
            android:text="Button" />
    
    </RelativeLayout>
    

    ListenerEditText.java:

    package com.doodkin.keyboardtest;
    
    import android.content.Context;
    import android.util.AttributeSet;
    import android.view.KeyEvent;
    import android.widget.EditText;
    
    /*
     * example: 
    
     myListenerEditText.setKeyImeChangeListener(new KeyImeChange() {
    
        @Override
        public boolean onKeyIme(int keyCode, KeyEvent event) {
            // All keypresses with the keyboard open will come through here!
            // You could also bubble up the true/false if you wanted 
            // to disable propagation.
        }
    });
    
     */
    
    public class ListenerEditText extends EditText {
    
        private KeyImeChange keyImeChangeListener;
    
        public ListenerEditText(Context context, AttributeSet attrs) {
            super(context, attrs);
        }
    
        public void setKeyImeChangeListener(KeyImeChange listener){
            keyImeChangeListener = listener;
        }
    
        public interface KeyImeChange {
            public boolean onKeyIme(int keyCode, KeyEvent event);
        }
    
        @Override
        public boolean onKeyPreIme (int keyCode, KeyEvent event){
            if(keyImeChangeListener != null){
                return keyImeChangeListener.onKeyIme(keyCode, event);
            }        
            return false;
        }
    }
    

    【讨论】:

    • 我找不到 setKeyImeChangeListener 方法。
    • 它属于 - 公共类 ListenerEditText 扩展了 EditText。这是我开发的课程,您可以在上面看到。坦率地说,很久以前不知道我该如何帮助你。我不记得了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-25
    • 2013-01-20
    • 2011-05-19
    • 2013-02-22
    • 2014-08-25
    • 1970-01-01
    相关资源
    最近更新 更多