Android 应用内自定义随机布局输入法

来源:互联网 发布:mac进度条卡在一半黑屏 编辑:程序博客网 时间:2024/06/05 05:29

在使用银行等对安全性要求较高的应用时,为了防止第三方输入法搜集输入信息导致密码泄露,会使用到自定义的输入法。自定义输入法的实现也比较简单,Android为开发者提供了一个KeyboardView。

先看看效果图:
这里写图片描述

代码实现:

主界面布局

<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"    tools:context="${relativePackage}.${activityClass}" >    <!-- 使用自定义的输入法 -->    <EditText        android:id="@+id/editCustomIME"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:layout_alignParentTop="true"        android:layout_margin="8dp"        android:hint="Custom IME"        android:inputType="textPassword"        android:textColor="#ffffff" />    <!-- 使用默认的输入法 -->    <EditText        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:layout_below="@+id/editCustomIME"        android:layout_margin="8dp"        android:hint="System IME"        android:textColor="#ffffff" />    <android.inputmethodservice.KeyboardView        android:id="@+id/keyboardview"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:layout_alignParentBottom="true"        android:layout_centerHorizontal="true"        android:focusable="true"        android:focusableInTouchMode="true"        android:visibility="gone" /></RelativeLayout>

主界面代码

package com.demo.customime;import android.app.Activity;import android.inputmethodservice.KeyboardView;import android.os.Bundle;import android.view.WindowManager;import android.widget.EditText;public class MainActivity extends Activity {    private KeyboardBuilder builder;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        getWindow().setSoftInputMode(                WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);        KeyboardView keyboardView = (KeyboardView) findViewById(R.id.keyboardview);        builder = new KeyboardBuilder(this, keyboardView, R.xml.keys_layout);        EditText editCustomIME = (EditText) findViewById(R.id.editCustomIME);        builder.registerEditText(editCustomIME);    }    @Override    public void onBackPressed() {        if (builder != null && builder.isCustomKeyboardVisible()) {            builder.hideCustomKeyboard();        } else {            this.finish();        }    }}

键盘布局:

<?xml version="1.0" encoding="utf-8"?><Keyboard xmlns:android="http://schemas.android.com/apk/res/android"    android:keyHeight="10%p"    android:keyWidth="25%p" >    <Row>        <Key            android:codes="55"            android:keyEdgeFlags="left"            android:keyLabel="7" />        <Key            android:codes="56"            android:keyLabel="8" />        <Key            android:codes="57"            android:keyLabel="9" />        <!-- 删除按键长按时连续响应 -->        <Key            android:codes="60001"            android:isRepeatable="true"            android:keyLabel="DEL" />    </Row>    <Row>        <Key            android:codes="52"            android:keyEdgeFlags="left"            android:keyLabel="4" />        <Key            android:codes="53"            android:keyLabel="5" />        <Key            android:codes="54"            android:keyLabel="6" />        <Key            android:codes="48"            android:keyLabel="0" />    </Row>    <Row>        <Key            android:codes="49"            android:keyEdgeFlags="left"            android:keyLabel="1" />        <Key            android:codes="50"            android:keyLabel="2" />        <Key            android:codes="51"            android:keyLabel="3" />        <Key            android:codes="60002"            android:keyLabel="Cancel" />    </Row></Keyboard>

常量

和输入法布局codes对应

package com.demo.customime;public interface Constant {    int CodeDelete = 60001;    int CodeCancel = 60002;}

KeyboardBuilder

package com.demo.customime;import android.app.Activity;import android.inputmethodservice.Keyboard;import android.inputmethodservice.KeyboardView;import android.text.Editable;import android.text.InputType;import android.util.Log;import android.view.MotionEvent;import android.view.View;import android.view.inputmethod.InputMethodManager;import android.widget.EditText;public class KeyboardBuilder {    private static final String TAG = "KeyboardBuilder";    private Activity mActivity;    private KeyboardView mKeyboardView;    public KeyboardBuilder(Activity ac, KeyboardView keyboardView,            int keyBoardXmlResId) {        mActivity = ac;        mKeyboardView = keyboardView;        Keyboard mKeyboard = new Keyboard(mActivity, keyBoardXmlResId);        // Attach the keyboard to the view        mKeyboardView.setKeyboard(mKeyboard);        // Do not show the preview balloons        mKeyboardView.setPreviewEnabled(false);        KeyboardView.OnKeyboardActionListener keyboardListener = new KeyboardView.OnKeyboardActionListener() {            @Override            public void onKey(int primaryCode, int[] keyCodes) {                // Get the EditText and its Editable                View focusCurrent = mActivity.getWindow().getCurrentFocus();                if (focusCurrent == null || !(focusCurrent instanceof EditText)) {                    return;                }                EditText edittext = (EditText) focusCurrent;                Editable editable = edittext.getText();                int start = edittext.getSelectionStart();                // Handle key                if (primaryCode == Constant.CodeCancel) {                    hideCustomKeyboard();                } else if (primaryCode == Constant.CodeDelete) {                    if (editable != null && start > 0) {                        editable.delete(start - 1, start);                    }                } else {                    // Insert character                    editable.insert(start,                            Character.toString((char) primaryCode));                }            }            @Override            public void onPress(int arg0) {            }            @Override            public void onRelease(int primaryCode) {            }            @Override            public void onText(CharSequence text) {            }            @Override            public void swipeDown() {            }            @Override            public void swipeLeft() {            }            @Override            public void swipeRight() {            }            @Override            public void swipeUp() {            }        };        mKeyboardView.setOnKeyboardActionListener(keyboardListener);    }    // 绑定一个EditText    public void registerEditText(EditText editText) {        // Make the custom keyboard appear        editText.setOnFocusChangeListener(new View.OnFocusChangeListener() {            @Override            public void onFocusChange(View v, boolean hasFocus) {                if (hasFocus) {                    showCustomKeyboard(v);                } else {                    hideCustomKeyboard();                }            }        });        editText.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                Log.d(TAG, "onClick");                showCustomKeyboard(v);            }        });        editText.setOnTouchListener(new View.OnTouchListener() {            @Override            public boolean onTouch(View v, MotionEvent event) {                Log.d(TAG, "onTouch");                EditText edittext = (EditText) v;                int inType = edittext.getInputType(); // Backup the input type                edittext.setInputType(InputType.TYPE_NULL); // Disable standard                                                            // keyboard                edittext.onTouchEvent(event); // Call native handler                edittext.setInputType(inType); // Restore input type                edittext.setSelection(edittext.getText().length());                return true;            }        });    }    public void hideCustomKeyboard() {        mKeyboardView.setVisibility(View.GONE);        mKeyboardView.setEnabled(false);    }    public void showCustomKeyboard(View v) {        mKeyboardView.setVisibility(View.VISIBLE);        mKeyboardView.setEnabled(true);        if (v != null) {            ((InputMethodManager) mActivity                    .getSystemService(Activity.INPUT_METHOD_SERVICE))                    .hideSoftInputFromWindow(v.getWindowToken(), 0);        }    }    public boolean isCustomKeyboardVisible() {        return mKeyboardView.getVisibility() == View.VISIBLE;    }}

Update:随机布局

在xml里添加几个不同的键盘布局:
这里写图片描述

随机使用其中一个布局:

    private void initialKeyboard() {        KeyboardView keyboardView = (KeyboardView) findViewById(R.id.keyboardview);        int keyboardLayout = getResources().getIdentifier(                "keys_layout_" + new Random().nextInt(3), "xml",                getPackageName());        builder = new KeyboardBuilder(this, keyboardView, keyboardLayout);        EditText editCustomIME = (EditText) findViewById(R.id.editCustomIME);        builder.registerEditText(editCustomIME);    }

参考:Android development: Custom keyboard

0 0