由於公司業務要求,對車牌號輸入和密碼有特殊要求,而之前的輸入呢有不合適,所以需重新定義,然而最氣人的是公司的項目開發工具又是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 ([email protected])
*/
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 [email protected]
* @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逛的比較多,但是寫文章還是很少寫的,不足之處請各位老鐵多多指正。