android的键盘各式各样,但未必能够满足我们充满创意的产品。为了让我们很好的配合产品,做个不与产品撕13的技术,在合理打造一款自定义的键盘。
先上代码吧,工具类代码如下
package com.binaryknight.customkeyboard;
import android.app.Activity;
import android.content.Context;
import android.inputmethodservice.Keyboard;
import android.inputmethodservice.KeyboardView;
import android.text.Editable;
import android.view.View;
import android.widget.EditText;
/**
* Created by ${BinaryKnight} on 2017/8/31.
*/
public class KeyboardUtil {
private Context ctx;
private Activity act;
private KeyboardView keyboardView;
private Keyboard keyboard;// 字母键盘
private boolean isShowing = false;//键盘是否显示
private EditText ed;
public KeyboardUtil(Activity act, Context ctx, EditText edit) {
this.act = act;
this.ctx = ctx;
this.ed = edit;
keyboard = new Keyboard(ctx, R.xml.keyboard);
keyboardView = (KeyboardView) act.findViewById(R.id.keyboard_view);
keyboardView.setKeyboard(keyboard);
keyboardView.setEnabled(true);
keyboardView.setPreviewEnabled(true);
keyboardView.setOnKeyboardActionListener(listener);
}
private KeyboardView.OnKeyboardActionListener listener = new KeyboardView.OnKeyboardActionListener() {
@Override
public void swipeUp() {
}
@Override
public void swipeRight() {
}
@Override
public void swipeLeft() {
}
@Override
public void swipeDown() {
}
@Override
public void onText(CharSequence text) {
}
@Override
public void onRelease(int primaryCode) {
}
@Override
public void onPress(int primaryCode) {
}
@Override
public void onKey(int primaryCode, int[] keyCodes) {
Editable editable = ed.getText();
int start = ed.getSelectionStart();
if (primaryCode == Keyboard.KEYCODE_DONE) {// 完成
hideKeyboard();
} else if (primaryCode == Keyboard.KEYCODE_DELETE) {// 回退
if (editable != null && editable.length() > 0) {
if (start > 0) {
editable.delete(start - 1, start);
}
}
} else if (primaryCode == 57419) { // go left
if (start > 0) {
ed.setSelection(start - 1);
}
} else if (primaryCode == 57421) { // go right
if (start < ed.length()) {
ed.setSelection(start + 1);
}
} else {
editable.insert(start, Character.toString((char) primaryCode));
}
}
};
public void showKeyboard() {
int visibility = keyboardView.getVisibility();
if (visibility == View.GONE || visibility == View.INVISIBLE) {
keyboardView.setVisibility(View.VISIBLE);
isShowing = true;
}
}
public void hideKeyboard() {
int visibility = keyboardView.getVisibility();
if (visibility == View.VISIBLE) {
keyboardView.setVisibility(View.INVISIBLE);
isShowing = false;
}
}
public boolean isShowing() {
if (keyboardView.getVisibility() == View.VISIBLE) {
return true;
} else if (keyboardView.getVisibility() == View.GONE || keyboardView.getVisibility() == View.INVISIBLE) {
return false;
}
return false;
}
}
以上
代码不难理解,就是创建一个构造函数,传入上下文,还有该activity实体,以及KeyboardView类的监听,当然还得准备配置我们的xml键盘实体展示。接下来是如何调用了,现在在activity如何调用它呢,方法也很简单:
第一步:我们的布局
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
android:id="@+id/rv_all"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:context="com.binaryknight.customkeyboard.MainActivity"
tools:showIn="@layout/activity_main">
<EditText
android:id="@+id/editText"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<FrameLayout
android:layout_width="match_parent"
android:id="@+id/frame_layout"
android:layout_height="match_parent"/>
<android.inputmethodservice.KeyboardView
android:id="@+id/keyboard_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:background="@color/keyboard_bg"
android:focusable="true"
android:focusableInTouchMode="true"
android:keyBackground="@color/keyboard_bg"
android:keyPreviewLayout="@layout/keyboard_preview"
android:keyTextColor="@color/keyboard_text_color"
android:shadowColor="@color/keyboard_bg"
android:shadowRadius="0.0"
android:visibility="visible"/>
</RelativeLayout>
第二步:
package com.binaryknight.customkeyboard;
import android.os.Build;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import android.view.ViewGroup;
import android.widget.EditText;
import java.lang.reflect.Method;
public class MainActivity extends AppCompatActivity {
private EditText editText;
private KeyboardUtil keyboardUtil;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
initView();
editListener();
}
private void initView() {
editText = (EditText) findViewById(R.id.editText);
setupUI(findViewById(R.id.frame_layout));//判断点击外部键盘消失
}
private void editListener() {
//Android.EditText点击时,隐藏系统弹出的键盘,显示出光标 (系统版本>5.0)
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
}
}
editText.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
int inputback = editText.getInputType();
Log.d("inputback", "inputback" + inputback);
// editVin.setInputType(InputType.TYPE_NULL);
keyboardUtil = new KeyboardUtil(MainActivity.this, getApplicationContext(), editText);
keyboardUtil.showKeyboard();
// inputFilterSpace(editText);
editText.setInputType(inputback);
return false;
}
});
}
//手机键盘显示
public void setupUI(View view) {
//Set up touch listener for non-text box views to hide keyboard.
if (!(view instanceof EditText)) {
view.setOnTouchListener(new View.OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
if (isKeyboardShowing()) {
closeKeyboard();
}
return false;
}
});
}
//If a layout container, iterate over children and seed recursion.
if (view instanceof ViewGroup) {
for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) {
View innerView = ((ViewGroup) view).getChildAt(i);
setupUI(innerView);
}
}
}
public boolean isKeyboardShowing() {
if (keyboardUtil != null) {
return keyboardUtil.isShowing();
}
return false;
}
//键盘的收起
public void closeKeyboard() {
if (keyboardUtil != null) {
keyboardUtil.hideKeyboard();
}
}
}
相信聪明的你,一定很简单的就能看懂怎么操作了,我们已经完成了一次伟大的键盘定义了,让我们看看效果图吧:
不知道是不是你喜欢符合你的自定义键盘呢,下一节我们将写一个用dialog伪装的自定义键盘吧