web-dev-qa-db-ja.com

FragmentでのonKeyPreIme(int keyCode、KeyEvent event)の実装

FragmentonKeyPreIme(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やStackOverflowで何も見つかりませんでした。戻るキーを押してソフトキーボードを上げた状態でアクションを実行したいのですが。 onKeyListenersにEditTextを設定しても、KeyEvent.KEYCODE_BACKは、ソフトキーボードが起動しているときは呼び出されません。ヘルプとソースコードに感謝します。

13
Max

キーボード入力に関連するEditTextビューをサブクラス化することで、onKeyPreImeを実装できました。目標は、ユーザーがパスコードを入力するか、アプリケーションを終了する必要があるカスタムロック画面を作成することです。ユーザーが「キーボードダウン」ボタンをタップしても、キーボードは消えません。

サブクラス化されたEditText用に別の.Javaファイルを作成してください。さらに、以下のコードでコンストラクターを使用してください(AttrubuteSetを渡す必要があります)。

OnKeyPreImeの実装があなたの実装と一致しない可能性があることは理解していますが、InputMethodManagerが実行する前にキーボードイベントをインターセプトする方法を示しています。

これがお役に立てば幸いです。

スクリーンショットUserLockActivity enter image description here

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>
20
i2097i

これは私の解決策であり、私にとっては非常にうまく機能しますが、ニーズは人によって異なります。

最初に私は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.
    }
});
21
Deminetix

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);
                }   
            }
        }
    });
1
Max

これは、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;
    }
}
0
Shimon Doodkin