由于公司业务要求,对车牌号输入和密码有特殊要求,而之前的输入呢有不合适,所以需重新定义,然而最气人的是公司的项目开发工具又是eclipse,很尴尬,用惯啦Android studio的我开始有点茫然,想着如何才能将这样子一个功能封装成一个JAR,这样子以后我就安逸啦。说做就做呀。
APP的UI效果图:
参考github大神的代码:https://github.com/yoojia/NextKeyboard
网上相关案例也比较多,但是都没有封装成jar来使用的,可能是由于业务需求太多啦吧,瞎猜的,哈哈哈。多的不说,上代码(我老觉得说问题不贴代码就是耍流氓)我是个乖孩子哦!
下面是主要代码及布局:
1.布局,main,密码,车牌号
1.1 main
<LinearLayout 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:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
android:orientation="vertical"
tools:context="com.github.yoojia.keyboard.app.MainActivity">
<TextView
android:id="@+id/display"
android:text="DISPLAY"
android:gravity="center"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<Button
android:id="@+id/vehicle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="车牌号专用键盘" />
<Button
android:id="@+id/number"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="密码键盘" />
</LinearLayout>
1.2 密码 keyboard_password
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout
android:orientation="horizontal"
android:background="@color/keyboard_background"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@id/keyboard_number_0"
style="@style/KeyboardInputNumber.Password"
/>
<TextView
android:id="@id/keyboard_number_1"
style="@style/KeyboardInputNumber.Password"
/>
<TextView
android:id="@id/keyboard_number_2"
style="@style/KeyboardInputNumber.Password"
/>
<TextView
android:id="@id/keyboard_number_3"
style="@style/KeyboardInputNumber.Password"
/>
<TextView
android:id="@id/keyboard_number_4"
style="@style/KeyboardInputNumber.Password"
/>
<TextView
android:id="@id/keyboard_number_5"
style="@style/KeyboardInputNumber.Password"
/>
</LinearLayout>
<android.inputmethodservice.KeyboardView
android:id="@+id/keyboard_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:focusable="true"
android:focusableInTouchMode="true"
android:shadowRadius="0"
android:background="@color/keyboard_background"
android:keyBackground="@drawable/keyboard_bg_key"
android:keyTextColor="@color/keyboard_key_text"
android:paddingBottom="1dp"
/>
</LinearLayout>
1.3 车牌号键盘输入 keyboard_vehicle_plate
<?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="wrap_content"
android:orientation="vertical">
<LinearLayout
android:orientation="horizontal"
android:background="@android:color/white"
android:padding="3dp"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@id/keyboard_number_0"
style="@style/KeyboardInputNumber"
android:textSize="14sp"
/>
<TextView
android:id="@id/keyboard_number_1"
style="@style/KeyboardInputNumber"
android:textSize="14sp"
/>
<TextView
android:id="@id/keyboard_number_2"
style="@style/KeyboardInputNumber"
android:textSize="14sp"
/>
<TextView
android:id="@id/keyboard_number_3"
style="@style/KeyboardInputNumber"
android:textSize="14sp"
/>
<TextView
android:id="@id/keyboard_number_4"
style="@style/KeyboardInputNumber"
android:textSize="14sp"
/>
<TextView
android:id="@id/keyboard_number_5"
style="@style/KeyboardInputNumber"
android:textSize="14sp"
/>
<TextView
android:id="@id/keyboard_number_6"
style="@style/KeyboardInputNumber"
android:textSize="14sp"
/>
<Button
android:id="@+id/keyboard_commit"
style="@style/KeyboardInputNumber"
android:text="完成"
android:textSize="14sp"
android:layout_weight="1.5"
/>
</LinearLayout>
<android.inputmethodservice.KeyboardView
android:id="@+id/keyboard_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:focusable="true"
android:focusableInTouchMode="true"
android:shadowRadius="0"
android:background="@color/keyboard_background"
android:keyBackground="@drawable/keyboard_bg_key"
android:keyTextColor="@color/keyboard_key_text"
android:paddingBottom="1dp"
/>
</LinearLayout>
2. 密码输入逻辑处理 PasswordKeyboard .class
/**
* 6位的弹出密码键盘
* @author YOOJIA.CHEN (yoojia.chen@gmail.com)
*/
public class PasswordKeyboard extends AbstractKeyboard{
private final KeyboardView mKeyboardView;
private final Keyboard mNumberKeyboard;
private final TextView[] mNumbersTextView = new TextView[6];
private TextView mSelectedTextView;
public PasswordKeyboard(Context context, OnKeyActionListener commitListener) {
super(context, commitListener);
final View contentView = putContentView(R.layout.keyboard_password);
mNumbersTextView[0] = (TextView) contentView.findViewById(R.id.keyboard_number_0);
mNumbersTextView[1] = (TextView) contentView.findViewById(R.id.keyboard_number_1);
mNumbersTextView[2] = (TextView) contentView.findViewById(R.id.keyboard_number_2);
mNumbersTextView[3] = (TextView) contentView.findViewById(R.id.keyboard_number_3);
mNumbersTextView[4] = (TextView) contentView.findViewById(R.id.keyboard_number_4);
mNumbersTextView[5] = (TextView) contentView.findViewById(R.id.keyboard_number_5);
final View.OnClickListener listener = createNumberListener();
for (TextView view : mNumbersTextView) {
// 关闭点击声效
view.setSoundEffectsEnabled(false);
view.setOnClickListener(listener);
}
mNumberKeyboard = new Keyboard(context, R.xml.keyboard_numbers);
mKeyboardView = (KeyboardView) contentView.findViewById(R.id.keyboard_view);
mKeyboardView.setOnKeyboardActionListener(new OnKeyboardActionHandler() {
@Override
public void onKey(int charCode, int[] keyCodes) {
mSelectedTextView.setText(Character.toString((char) charCode));
nextNumber();
}
});
mKeyboardView.setPreviewEnabled(false);// !!! Must be false
mKeyboardView.setKeyboard(mNumberKeyboard);
}
@Override
protected void onShow() {
mNumbersTextView[0].performClick();
}
private void nextNumber(){
final String number = getInput(mNumbersTextView);
final int viewId = mSelectedTextView.getId();
if (viewId == R.id.keyboard_number_0) {
mOnKeyActionListener.onProcess(number);
mNumbersTextView[1].performClick();
} else if (viewId == R.id.keyboard_number_1) {
mOnKeyActionListener.onProcess(number);
mNumbersTextView[2].performClick();
} else if (viewId == R.id.keyboard_number_2) {
mOnKeyActionListener.onProcess(number);
mNumbersTextView[3].performClick();
} else if (viewId == R.id.keyboard_number_3) {
mOnKeyActionListener.onProcess(number);
mNumbersTextView[4].performClick();
} else if (viewId == R.id.keyboard_number_4) {
mOnKeyActionListener.onProcess(number);
mNumbersTextView[5].performClick();
} else if (viewId == R.id.keyboard_number_5) {
// 输入最后一位密码,自动提交
if (number.length() == mNumbersTextView.length){
mOnKeyActionListener.onFinish(number);
dismiss();
}
}
}
private View.OnClickListener createNumberListener() {
return new View.OnClickListener() {
@Override
public void onClick(View view) {
if (mSelectedTextView != null){
mSelectedTextView.setActivated(false);
}
mSelectedTextView = (TextView) view;
mSelectedTextView.setActivated(true);
}
};
}
public static void show(Activity context, OnKeyActionListener listener) {
View v= context.getWindow().getDecorView().getRootView();
new PasswordKeyboard(context, listener).show(v);
}
public static PasswordKeyboard create(Context context, OnKeyActionListener listener) {
return new PasswordKeyboard(context, listener);
}
}
3.键盘输入逻辑处理 VehiclePlateKeyboard .class
/**
* 中国民用
*
* @author yoojia.chen@gmail.com
* @version version 2015-04-24
* @since 1.0
*/
public class VehiclePlateKeyboard extends AbstractKeyboard{
private static final int NUMBER_LENGTH = 7;
public static final String WJ_PREFIX = "WJ";
private static final String PROVINCE_CHINESE = "@京津晋冀蒙辽吉黑沪苏浙皖闽赣鲁豫鄂湘粤桂琼渝川贵云藏陕甘青宁新武";
public static final String EXTRA_CHINESE = "@港澳警学挂";
private final KeyboardView mKeyboardView;
private final TextView[] mNumbersTextView = new TextView[NUMBER_LENGTH];
private View mCommitButton;
private int mShowingKeyboard = 0;
private TextView mSelectedTextView;
private Keyboard mProvinceKeyboard_1;
private Keyboard mProvinceKeyboard_0;
private Keyboard mCityCodeKeyboard;
private Keyboard mNumberKeyboard;
private Keyboard mNumberExtraKeyboard;
private String mDefaultPlateNumber;
public VehiclePlateKeyboard(Context context, OnKeyActionListener keyActionListener) {
super(context, keyActionListener);
final View contentView = putContentView(R.layout.keyboard_vehicle_plate);
mNumbersTextView[0] = (TextView) contentView.findViewById(R.id.keyboard_number_0);
mNumbersTextView[1] = (TextView) contentView.findViewById(R.id.keyboard_number_1);
mNumbersTextView[2] = (TextView) contentView.findViewById(R.id.keyboard_number_2);
mNumbersTextView[3] = (TextView) contentView.findViewById(R.id.keyboard_number_3);
mNumbersTextView[4] = (TextView) contentView.findViewById(R.id.keyboard_number_4);
mNumbersTextView[5] = (TextView) contentView.findViewById(R.id.keyboard_number_5);
mNumbersTextView[6] = (TextView) contentView.findViewById(R.id.keyboard_number_6);
final View.OnClickListener listener = createNumberListener();
for (TextView view : mNumbersTextView) {
view.setSoundEffectsEnabled(false);
view.setOnClickListener(listener);
}
mProvinceKeyboard_1 = new Keyboard(context, R.xml.keyboard_vehicle_province_1);
mProvinceKeyboard_0 = new Keyboard(context, R.xml.keyboard_vehicle_province_0);
mCityCodeKeyboard = new Keyboard(context, R.xml.keyboard_vehicle_code);
mNumberKeyboard = new Keyboard(context, R.xml.keyboard_vehicle_number);
mNumberExtraKeyboard = new Keyboard(context, R.xml.keyboard_vehicle_number_extra);
mKeyboardView = (KeyboardView) contentView.findViewById(R.id.keyboard_view);
mKeyboardView.setOnKeyboardActionListener(new OnKeyboardActionHandler(){
@Override
public void onKey(int charCode, int[] keyCodes) {
// 在键盘XML文件中,40x为省份文字使用的编码,50x为特定尾号文字的编码
if (400 < charCode && charCode < 500){ // 400 See keyboard xml
charCode = PROVINCE_CHINESE.charAt(charCode - 400);
}else if (500 < charCode) {
charCode = EXTRA_CHINESE.charAt(charCode - 500);
}
mSelectedTextView.setText(Character.toString((char) charCode));
nextNumber();
}
});
mKeyboardView.setPreviewEnabled(false);// !!! Must be false
mCommitButton = contentView.findViewById(R.id.keyboard_commit);
mCommitButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
final String number = getInput(mNumbersTextView);
if (number.length() == mNumbersTextView.length){
mOnKeyActionListener.onFinish(number);
dismiss();
}
}
});
}
public void setDefaultPlateNumber(String number) {
if (!TextUtils.isEmpty(number)) {
if (number.startsWith(WJ_PREFIX)) {
mDefaultPlateNumber = "武" + number.substring(number.length() > 2 ? 2 : 0);
}else{
mDefaultPlateNumber = number;
}
}
}
@Override
public void show(View anchorView) {
if ( ! TextUtils.isEmpty(mDefaultPlateNumber)){
final char[] numbers = mDefaultPlateNumber.toUpperCase().toCharArray();
final int limited = Math.min(NUMBER_LENGTH, numbers.length);
for (int i = 0;i< limited;i++){
mNumbersTextView[i].setText(Character.toString(numbers[i]));
}
}
super.show(anchorView);
}
@Override
protected void onShow() {
mNumbersTextView[0].performClick();
}
private void nextNumber(){
final String number = getInput(mNumbersTextView);
mOnKeyActionListener.onProcess(number);
final int viewId = mSelectedTextView.getId();
if (viewId == R.id.keyboard_number_0) {
mNumbersTextView[1].performClick();
} else if (viewId == R.id.keyboard_number_1) {
mNumbersTextView[2].performClick();
} else if (viewId == R.id.keyboard_number_2) {
mNumbersTextView[3].performClick();
} else if (viewId == R.id.keyboard_number_3) {
mNumbersTextView[4].performClick();
} else if (viewId == R.id.keyboard_number_4) {
mNumbersTextView[5].performClick();
} else if (viewId == R.id.keyboard_number_5) {
mNumbersTextView[6].performClick();
} else if (viewId == R.id.keyboard_number_6) {
mCommitButton.performClick();
}
}
private View.OnClickListener createNumberListener() {
return new View.OnClickListener() {
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
@SuppressLint("NewApi")
@Override
public void onClick(View view) {
if (mSelectedTextView != null){
mSelectedTextView.setActivated(false);
}
mSelectedTextView = (TextView) view;
mSelectedTextView.setActivated(true);
int id = view.getId();
if (id == R.id.keyboard_number_0) {
if (mShowingKeyboard != R.xml.keyboard_vehicle_province_1) {
mShowingKeyboard = R.xml.keyboard_vehicle_province_1;
mKeyboardView.setKeyboard(mProvinceKeyboard_1);
}
} else if (id == R.id.keyboard_number_1) {
final String number = getInput(mNumbersTextView);
if (number.startsWith(WJ_PREFIX)) {
mShowingKeyboard = R.xml.keyboard_vehicle_province_0;
mKeyboardView.setKeyboard(mProvinceKeyboard_0);
}else{
if (mShowingKeyboard != R.xml.keyboard_vehicle_code) {
mShowingKeyboard = R.xml.keyboard_vehicle_code;
mKeyboardView.setKeyboard(mCityCodeKeyboard);
}
}
} else if (id == R.id.keyboard_number_6) {
if (mShowingKeyboard != R.xml.keyboard_vehicle_number_extra) {
mShowingKeyboard = R.xml.keyboard_vehicle_number_extra;
mKeyboardView.setKeyboard(mNumberExtraKeyboard);
}
} else {
if (mShowingKeyboard != R.xml.keyboard_vehicle_number) {
mShowingKeyboard = R.xml.keyboard_vehicle_number;
mKeyboardView.setKeyboard(mNumberKeyboard);
}
}
mKeyboardView.invalidateAllKeys();
mKeyboardView.invalidate();
}
};
}
@Override
protected String getInput(TextView[] inputs) {
final String number = super.getInput(inputs);
return number.replace("武", WJ_PREFIX);
}
public static void show(Activity activity, OnKeyActionListener listener) {
new VehiclePlateKeyboard(activity, listener).show(activity.getWindow().getDecorView().getRootView());
}
public static VehiclePlateKeyboard create(Context context, OnKeyActionListener listener) {
return new VehiclePlateKeyboard(context, listener);
}
}
4.到这里剩下的就是监听和回填啦哈。
5.下面是两个接口:
6.最后是相关的XML文件啦。xml文件就有点多,这里就不一一贴出来,请移步去下载源码看呗。
调用:将jar包导入项目,然后 如下调用
源码及jar包地址:https://download.csdn.net/download/anshaoyang/10473786
虽然CSDN逛的比较多,但是写文章还是很少写的,不足之处请各位老铁多多指正。