您的位置:首页 > 移动开发 > Android开发

【android开发】自定义数字软键盘的设计与实现(2)

2013-10-27 19:38 691 查看
    上一篇我们说了关于自定义软键盘实现的相关原理,把两个主要的类介绍了一下,并看了一下源码的内容,那么今天实现起来就不会有什么疑惑了,每一步都会清晰了。



       好了,下面我们就把实现的具体步骤给大家介绍一下:首先在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>

最后就在你要执行activity,添加一些代码就行了,剩下的就和其他控件使用方式一样了,类名为LockAppActivity.java,内容如下:

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。上面就把实现的整个过程写完了,一个自定义的数字软键盘就实现了。

源码下载http://download.csdn.net/detail/lixinhuixin/6462065
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐