上一篇我们说了关于自定义软键盘实现的相关原理,把两个主要的类介绍了一下,并看了一下源码的内容,那么今天实现起来就不会有什么疑惑了,每一步都会清晰了。
好了,下面我们就把实现的具体步骤给大家介绍一下:首先在res下新建xml文件夹,在xml文件夹中新建symbols.xml文件,这个布局文件重要是实现软键盘的布局,每一个按键都有一个codes值,在类中就是通过codes值来监听每一个按钮,上一面已经说了,一些codes是固定,一些是自定义设置的,内如如下:
- <?xml version="1.0" encoding="utf-8"?>
- <keyboard xmlns:android="http://schemas.android.com/apk/res/android" android:keywidth="33%p" android:horizontalgap="0px" android:verticalgap="0px" android:keyheight="10%p">
- <row>
- <key android:codes="49" android:keylabel="1">
- <key android:codes="50" android:keylabel="2">
- <key android:codes="51" android:keylabel="3">
- </key></key></key></row>
- <row>
- <key android:codes="52" android:keylabel="4">
- <key android:codes="53" android:keylabel="5">
- <key android:codes="54" android:keylabel="6">
- </key></key></key></row>
- <row>
- <key android:codes="55" android:keylabel="7">
- <key android:codes="56" android:keylabel="8">
- <key android:codes="57" android:keylabel="9">
- </key></key></key></row>
- <row>
- <key android:codes="4896" android:keylabel="清空">
- <key android:codes="48" android:keylabel="0">
- <key android:codes="-5" android:keyicon="@drawable/sym_keyboard_delete">
- </key></key></key></row>
- </keyboard>
然后创建一个类,用于处理软键盘事件,文件名为KeyboardUtil.java,内容如下:
- package com.xinhui.ui;
- import com.xinhui.appsystem.R;
- import android.app.Activity;
- import android.content.Context;
- import android.inputmethodservice.Keyboard;
- import android.inputmethodservice.KeyboardView;
- import android.inputmethodservice.KeyboardView.OnKeyboardActionListener;
- import android.text.Editable;
- import android.view.View;
- import android.widget.EditText;
- public class KeyboardUtil {
- private KeyboardView keyboardView;
- private Keyboard k;// 数字键盘
- private EditText ed;
- public KeyboardUtil(Activity act, Context ctx, EditText edit) {
- this.ed = edit;
- k = new Keyboard(ctx, R.xml.symbols);
- keyboardView = (KeyboardView) act.findViewById(R.id.keyboard_view);
- keyboardView.setKeyboard(k);
- keyboardView.setEnabled(true);
- keyboardView.setPreviewEnabled(true);
- keyboardView.setVisibility(View.VISIBLE);
- keyboardView.setOnKeyboardActionListener(listener);
- }
- private OnKeyboardActionListener listener = new 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) {
- }
- //一些特殊操作按键的codes是固定的比如完成、回退等
- @Override
- public void onKey(int primaryCode, int[] keyCodes) {
- Editable editable = ed.getText();
- int start = ed.getSelectionStart();
- if (primaryCode == Keyboard.KEYCODE_DELETE) {// 回退
- if (editable != null && editable.length() > 0) {
- if (start > 0) {
- editable.delete(start - 1, start);
- }
- }
- }else if (primaryCode == 4896) {// 清空
- editable.clear();
- } 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);
- }
- }
- }
接下来就是实现activity的视图布局文件了,文件名为input_pwd.xml,内容如下:
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical"
- android:background="@drawable/viewbackground" >
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="40dip"
- android:gravity="center_vertical|center_horizontal"
- android:orientation="horizontal" >
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:textColor="@android:color/white"
- android:textSize="22sp"
- android:text="安全验证"/>
- </LinearLayout>
- <View
- android:layout_width="fill_parent"
- android:layout_height="1dip"
- android:background="#ff00ff66"
- />
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginTop="20dip"
- android:gravity="center_vertical|center_horizontal"
- android:orientation="horizontal">
- <ImageView
- android:id="@+id/iv_lock_app_icon"
- android:layout_width="48dip"
- android:layout_height="48dip"
- android:contentDescription="@string/hello_world"/>
- <TextView
- android:id="@+id/tv_lock_app_name"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginLeft="15dip"
- android:textColor="#ffbc04e5"
- android:text="@string/hello_world"/>
- </LinearLayout>
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginTop="20dip"
- android:orientation="horizontal" >
- <EditText
- android:id="@+id/et_lock_pwd"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginLeft="5dip"
- android:layout_marginRight="5dip"
- android:layout_marginTop="20dip"
- android:layout_weight="0.36"
- android:background="#cccccc"
- android:hint="输入密码"
- android:inputType="textPassword"
- android:textSize="40dp" />
- <Button
- android:id="@+id/btn_confirm"
- android:layout_width="78dp"
- android:layout_height="wrap_content"
- android:layout_marginTop="20dip"
- android:text="确定"
- android:textSize="20dp" />
- </LinearLayout>
- <android.inputmethodservice.KeyboardView
- android:id="@+id/keyboard_view"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:layout_marginTop="10dip"
- android:focusable="true"
- android:focusableInTouchMode="true"
- android:visibility="visible"
- />
- </LinearLayout>
- package com.xinhui.ui;
- import com.xinhui.appsystem.R;
- import com.xinhui.service.WatchAppService;
- import android.app.Activity;
- import android.content.SharedPreferences;
- import android.content.pm.ApplicationInfo;
- import android.content.pm.PackageManager.NameNotFoundException;
- import android.graphics.drawable.Drawable;
- import android.os.Bundle;
- import android.text.InputType;
- import android.text.TextUtils;
- import android.util.Log;
- import android.view.KeyEvent;
- import android.view.MotionEvent;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.view.View.OnTouchListener;
- import android.view.Window;
- import android.widget.Button;
- import android.widget.EditText;
- import android.widget.ImageView;
- import android.widget.TextView;
- import android.widget.Toast;
- /**
- * 类名称:LockAppActivity
- * 类描述:系统锁页面
- * 创建人:LXH
- * 创建时间:2013-10-21 上午10:30:00
- */
- public class LockAppActivity extends Activity implements OnClickListener,OnTouchListener{
- private ImageView ivLockAppIcon;
- private TextView tvLockAppName;
- private EditText etInputPwd;
- private Button btnConfirm;
- private String packageName;
- private String passWord;
- private SharedPreferences preferences;
- //public static boolean isLock;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- // TODO Auto-generated method stub
- super.onCreate(savedInstanceState);
- requestWindowFeature(Window.FEATURE_NO_TITLE);
- setContentView(R.layout.input_pwd);
- //WatchAppService.isLock = false;
- Log.e("test", "onCreate--->");
- ivLockAppIcon = (ImageView) findViewById(R.id.iv_lock_app_icon);
- tvLockAppName = (TextView) findViewById(R.id.tv_lock_app_name);
- etInputPwd = (EditText) findViewById(R.id.et_lock_pwd);
- etInputPwd.setOnTouchListener(this);
- btnConfirm = (Button) findViewById(R.id.btn_confirm);
- btnConfirm.setOnClickListener(this);
- packageName = getIntent().getStringExtra("packageName");
- try {
- //通过包名拿到applicationInfo
- ApplicationInfo appInfo = getPackageManager().getPackageInfo(packageName, 0).applicationInfo;
- //应用图标
- Drawable app_icon = appInfo.loadIcon(getPackageManager());
- //应用的名字
- String app_name = appInfo.loadLabel(getPackageManager()).toString();
- ivLockAppIcon.setImageDrawable(app_icon);
- tvLockAppName.setText(app_name);
- } catch (NameNotFoundException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- //不让用户按后退键
- @Override
- public boolean onKeyDown(int keyCode, KeyEvent event) {
- // TODO Auto-generated method stub
- //屏蔽后退键
- if(KeyEvent.KEYCODE_BACK == event.getKeyCode())
- {
- return true;//阻止事件继续向下分发
- }
- return super.onKeyDown(keyCode, event);
- }
- @Override
- public void onClick(View v) {
- // TODO Auto-generated method stub
- String input = etInputPwd.getText().toString().trim();
- preferences = getSharedPreferences("passWord", MODE_PRIVATE);
- passWord = preferences.getString("pwd", "");
- if(TextUtils.isEmpty(input))
- {
- Toast.makeText(this, "密码不能为空", Toast.LENGTH_SHORT).show();
- }
- else if(passWord.equals(input))
- {
- WatchAppService.lastRunningApp = WatchAppService.runningApp;//这里赋值,终于解决了反复弹出验证页面的BUG
- finish();
- }
- else
- {
- Toast.makeText(this, "密码错误", Toast.LENGTH_SHORT).show();
- etInputPwd.setText("");//置空
- }
- }
- @Override
- public boolean onTouch(View v, MotionEvent event) {
- // TODO Auto-generated method stub
- //这样是在触摸到控件时,软键盘才会显示出来
- int inputback = etInputPwd.getInputType();
- etInputPwd.setInputType(InputType.TYPE_NULL);
- new KeyboardUtil(this, this, etInputPwd).showKeyboard();
- etInputPwd.setInputType(inputback);
- return false;
- }
- }
由于我的这个activity是其他activity调用的,并不是主界面的activity。上面就把实现的整个过程写完了,一个自定义的数字软键盘就实现了。