add pin key keyboard

This commit is contained in:
ahmeddatexpay 2025-09-24 20:11:47 +03:00
parent 2f8234e241
commit f95fac9f6e
28 changed files with 1481 additions and 13 deletions

BIN
app/app.keystore Normal file

Binary file not shown.

View File

@ -7,18 +7,32 @@ android {
compileSdk 35
signingConfigs {
// release {
// storeFile file('new-keystore.jks')
// storePassword 'MPOS73356xDp'
// keyPassword 'MPOS73356xDp'
// keyAlias 'mulberrypos'
// }
// debug {
// storeFile file('new-keystore.jks')
// storePassword 'MPOS73356xDp'
// keyPassword 'MPOS73356xDp'
// keyAlias 'mulberrypos'
// }
release {
storeFile file('new-keystore.jks')
storePassword 'MPOS73356xDp'
keyPassword 'MPOS73356xDp'
keyAlias 'mulberrypos'
storeFile file('app.keystore')
storePassword 'dspread'
keyPassword 'dspread'
keyAlias 'gundam_wing'
}
debug {
storeFile file('new-keystore.jks')
storePassword 'MPOS73356xDp'
keyPassword 'MPOS73356xDp'
keyAlias 'mulberrypos'
storeFile file('app.keystore')
storePassword 'dspread'
keyPassword 'dspread'
keyAlias 'gundam_wing'
}
}

View File

@ -18,11 +18,18 @@ import com.test.cardreadtest.posAPI.PaymentResult;
import com.test.cardreadtest.posAPI.PaymentServiceCallback;
import com.test.cardreadtest.utils.TRACE;
import com.test.cardreadtest.payment.pinkeyboard.KeyboardUtil;
import com.test.cardreadtest.payment.pinkeyboard.MyKeyboardView;
import com.test.cardreadtest.payment.pinkeyboard.PinPadDialog;
import com.test.cardreadtest.payment.pinkeyboard.PinPadView;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
public class PaymentActivity extends AppCompatActivity {
private static final String TAG = "PaymentActivity";
private String amount;
@ -30,6 +37,13 @@ public class PaymentActivity extends AppCompatActivity {
private PaymentViewModel viewModel;
private ActivityPaymentBinding binding;
private PaymentServiceCallback paymentServiceCallback;
private KeyboardUtil keyboardUtil;
private int timeOfPinInput;
public PinPadDialog pinPadDialog;
private int changePinTimes;
private boolean isPinBack = false;
private boolean isChangePin = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
@ -151,6 +165,41 @@ public class PaymentActivity extends AppCompatActivity {
@Override
public void onQposRequestPinResult(List<String> dataList, int offlineTime) {
TRACE.d("onQposRequestPinResult = " + dataList + "\nofflineTime: " + offlineTime);
if (POSManager.getInstance().isDeviceReady()) {
viewModel.setWaitingStatus(false);
viewModel.showPinpad.set(true);
boolean onlinePin = POSManager.getInstance().isOnlinePin();
if (keyboardUtil != null) {
keyboardUtil.hide();
}
if (isChangePin) {
if (timeOfPinInput == 1) {
} else if (timeOfPinInput == 2) {
timeOfPinInput = 0;
}
} else {
if (onlinePin) {
} else {
int cvmPinTryLimit = POSManager.getInstance().getCvmPinTryLimit();
TRACE.d("PinTryLimit:" + cvmPinTryLimit);
if (cvmPinTryLimit == 1) {
} else {
}
}
}
}
binding.pinpadEditText.setText("");
MyKeyboardView.setKeyBoardListener(value -> {
if (POSManager.getInstance().isDeviceReady()) {
POSManager.getInstance().pinMapSync(value, 20);
}
});
if (POSManager.getInstance().isDeviceReady()) {
keyboardUtil = new KeyboardUtil(PaymentActivity.this, binding.scvText, dataList);
keyboardUtil.initKeyboard(MyKeyboardView.KEYBOARDTYPE_Only_Num_Pwd, binding.pinpadEditText);//Random keyboard
}
}
@Override

View File

@ -1,5 +1,7 @@
package com.test.cardreadtest.payment;
import androidx.databinding.ObservableBoolean;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
@ -11,6 +13,7 @@ public class PaymentViewModel extends ViewModel {
private MutableLiveData<String> cardInfo = new MutableLiveData<>("Card: --");
private MutableLiveData<Boolean> showProgress = new MutableLiveData<>(false);
private MutableLiveData<Boolean> showResults = new MutableLiveData<>(false);
public ObservableBoolean showPinpad = new ObservableBoolean(false);
public PaymentViewModel() {
super();
@ -36,10 +39,6 @@ public class PaymentViewModel extends ViewModel {
return showProgress;
}
public MutableLiveData<Boolean> getShowResults() {
return showResults;
}
public void displayAmount(String amountValue) {
amount.postValue("Amount: $" + amountValue);
}
@ -63,6 +62,14 @@ public class PaymentViewModel extends ViewModel {
}
}
public LiveData<Boolean> getShowResults() {
return showResults;
}
public void setShowResults(Boolean value) {
showResults.setValue(value);
}
public void showTransactionResults(boolean show) {
showResults.postValue(show);
}

View File

@ -0,0 +1,10 @@
package com.test.cardreadtest.payment.pinkeyboard;
/**
* Time:2020/4/26
* Author:Qianmeng Chen
* Description:
*/
public interface KeyBoardNumInterface {
void getNumberValue(String Value);
}

View File

@ -0,0 +1,66 @@
package com.test.cardreadtest.payment.pinkeyboard;
import android.app.Activity;
import android.content.Context;
import android.view.MotionEvent;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
/**
* ****************************************************************
* File Name: KeyboardTool
* File Description: Keyboard Tool
* ****************************************************************
*/
public class KeyboardTool {
/**
* hide keyboard
*
* @param v The focus view
* @param views Input box
* @return true means the focus is on edit
*/
public static boolean isFocusEditText(View v, View... views) {
if (v instanceof EditText && views != null && views.length > 0) {
for (View view : views) {
if (v == view) {
return true;
}
}
}
return false;
}
/*
* whether touch specified view
**/
public static boolean isTouchView(View[] views, MotionEvent ev) {
if (views == null || views.length == 0) {
return false;
}
int[] location = new int[2];
for (View view : views) {
view.getLocationOnScreen(location);
int x = location[0];
int y = location[1];
if (ev.getX() > x && ev.getX() < (x + view.getWidth()) && ev.getY() > y && ev.getY() < (y + view.getHeight())) {
return true;
}
}
return false;
}
/**
* hide soft keyboard
*/
public static void hideInputForce(Activity activity, View currentFocusView) {
if (activity == null || currentFocusView == null) {
return;
}
InputMethodManager imm = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE);
if (imm != null) {
imm.hideSoftInputFromWindow(currentFocusView.getWindowToken(), 0);
}
}
}

View File

@ -0,0 +1,225 @@
package com.test.cardreadtest.payment.pinkeyboard;
import android.app.Activity;
import android.graphics.Rect;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.PopupWindow;
import com.test.cardreadtest.R;
import java.lang.reflect.Method;
import java.util.List;
/**
* ****************************************************************
* File Name: KeyboardUtil
* File Description: Keyboard Util
* ****************************************************************
*/
public class KeyboardUtil {
private Activity mActivity;
private View mParent;
private PopupWindow mWindow;
private MyKeyboardView mKeyboardView;
private boolean needInit;
private boolean mScrollTo = false;//whether the interface moves up
// private int mEditTextHeight;//edit text height 44dp
private int mKeyboardHeight;//keyboard height 260dp
private int mHeightPixels;//screen height
private int mKeyBoardMarginEditTextTopHeight;//the minimum distance between the keyboard and the top of the edit text
private List<String> dataList;
public static EditText pinpadEditText;
public KeyboardUtil(Activity context, View parent, List<String> dataList) {
this.dataList = dataList;
this.mActivity = context;
this.mParent = parent;
LinearLayout mIncludeKeyboardview = (LinearLayout) LayoutInflater.from(context).inflate(R.layout.include_keyboardview, null);
// RelativeLayout mKeyboardTopView = (RelativeLayout) mIncludeKeyboardview.findViewById(R.id.keyboard_top_rl);
mKeyboardView = (MyKeyboardView) mIncludeKeyboardview.findViewById(R.id.keyboard_view);
mWindow = new PopupWindow(mIncludeKeyboardview, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT, false);
// mWindow.setAnimationStyle(R.style.AnimBottom); //Animation style
mWindow.setOnDismissListener(mOnDismissListener);
mWindow.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);//prevent being blocked by the bottom toolbar
int mEditTextHeight = dp2px(44);//44dp edit text height
mKeyboardHeight = dp2px(260);//260dp
mKeyBoardMarginEditTextTopHeight = mEditTextHeight * 2;
mHeightPixels = context.getResources().getDisplayMetrics().heightPixels;
//need to add the Status bar height
Rect rect = new Rect();
context.getWindow().getDecorView().getWindowVisibleDisplayFrame(rect);
mHeightPixels = rect.bottom;
}
public KeyboardUtil(Activity context, List<String> dataList) {
LinearLayout mIncludeKeyboardview = (LinearLayout) LayoutInflater.from(context).inflate(R.layout.include_pinpad, null);
this.dataList = dataList;
this.mActivity = context;
this.mParent = mIncludeKeyboardview;
pinpadEditText = mIncludeKeyboardview.findViewById(R.id.pinpadEditText);
mKeyboardView = (MyKeyboardView) mIncludeKeyboardview.findViewById(R.id.keyboard_view);
mWindow = new PopupWindow(mIncludeKeyboardview, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT, false);
// mWindow.setAnimationStyle(R.style.AnimBottom); //Animation style
mWindow.setOnDismissListener(mOnDismissListener);
mWindow.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);//prevent being blocked by the bottom toolbar
int mEditTextHeight = dp2px(44);//44dp edit text height
mKeyboardHeight = dp2px(260);//260dp
mKeyBoardMarginEditTextTopHeight = mEditTextHeight * 2;
mHeightPixels = context.getResources().getDisplayMetrics().heightPixels;
initKeyboard(MyKeyboardView.KEYBOARDTYPE_Only_Num_Pwd, pinpadEditText);
}
public void initKeyboard(EditText... editTexts) {
initKeyboard(MyKeyboardView.KEYBOARDTYPE_Num_Pwd, editTexts);
}
/**
* init keyboard
*
* @param keyBoardType keyboard type
* @param editTexts edit text
*/
@SuppressWarnings("all")
public void initKeyboard(final int keyBoardType, EditText... editTexts) {
for (final EditText editText : editTexts) {
hideSystemSofeKeyboard(editText);
show(keyBoardType, editText);
// editText.setOnTouchListener(new View.OnTouchListener() {
// @Override
// public boolean onTouch(View v, MotionEvent event) {
// if (event.getAction() == MotionEvent.ACTION_UP) {
// show(keyBoardType, editText);
// }
// return false;
// }
// });
}
}
/**
* Set edittext that does not need to use this keyboard
*
* @param edittexts
*/
@SuppressWarnings("all")
public void setOtherEdittext(EditText... editTexts) {
for (EditText editText : editTexts) {
editText.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_UP) {
//prevent situations where the keyboard is not hidden new Handler().postDelayed(new Runnable())
hide();
}
return false;
}
});
}
}
public void show(int keyBoardType, EditText editText) {
//hide system
KeyboardTool.hideInputForce(mActivity, editText);
//init keyboard
mKeyboardView.setHeight(mHeightPixels);
if (mKeyboardView.getEditText() != editText || needInit) {
mKeyboardView.init(editText, mWindow, keyBoardType, dataList);
}
//display custom keyboard
if (mWindow != null && !mWindow.isShowing()) {
mWindow.showAtLocation(mParent, Gravity.BOTTOM, 0, 0);
} else {
// mWindow = null;
}
//modify the position of the parent control
int nKeyBoardToTopHeight = mHeightPixels - mKeyboardHeight;//screen height-keyboard height
int[] editLocal = new int[2];
editText.getLocationOnScreen(editLocal);
ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams) mParent.getLayoutParams();
if (editLocal[1] + mKeyBoardMarginEditTextTopHeight > nKeyBoardToTopHeight) {
int height = editLocal[1] - lp.topMargin - nKeyBoardToTopHeight;
int mScrollToValue = height + mKeyBoardMarginEditTextTopHeight;
lp.topMargin = 0 - mScrollToValue;
mParent.setLayoutParams(lp);
mScrollTo = true;
}
// getLocation(mKeyboardView);
}
public boolean hide() {
if (mWindow != null && mWindow.isShowing()) {
mWindow.dismiss();
needInit = true;
return true;
}
return false;
}
/**
* hide system keyboard
*
* @param editText
*/
private static void hideSystemSofeKeyboard(EditText editText) {
//SDK_INT >= 11
try {
Class<EditText> cls = EditText.class;
Method setShowSoftInputOnFocus;
setShowSoftInputOnFocus = cls.getMethod("setShowSoftInputOnFocus", boolean.class);
setShowSoftInputOnFocus.setAccessible(true);
setShowSoftInputOnFocus.invoke(editText, false);
} catch (SecurityException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
private int dp2px(float dpValue) {
float scale = mActivity.getResources().getDisplayMetrics().density;
return (int) (dpValue * scale + 0.5f);
}
//keyboard dismiss,recover parent control
private PopupWindow.OnDismissListener mOnDismissListener = new PopupWindow.OnDismissListener() {
@Override
public void onDismiss() {
if (mScrollTo) {
mActivity.runOnUiThread(new Runnable() {
@Override
public void run() {
mScrollTo = false;
ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams) mParent.getLayoutParams();
lp.topMargin = 0;
mParent.setLayoutParams(lp);
}
});
}
}
};
/*
* The minimum height of the keyboard from the top of the edit text
**/
public void setKeyBoardMarginEditTextTopHeight(int mKeyBoardMarginEditTextTopHeight) {
this.mKeyBoardMarginEditTextTopHeight = mKeyBoardMarginEditTextTopHeight;
}
}

View File

@ -0,0 +1,331 @@
package com.test.cardreadtest.payment.pinkeyboard;
import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
import android.inputmethodservice.Keyboard;
import android.inputmethodservice.KeyboardView;
import android.text.Editable;
import android.util.AttributeSet;
import android.util.Log;
import android.widget.EditText;
import android.widget.PopupWindow;
import com.test.cardreadtest.utils.QPOSUtil;
import com.test.cardreadtest.R;
import java.util.ArrayList;
import java.util.List;
/**
* ****************************************************************
* File Name: MyKeyboardView
* File Description: Keyboard View
* ****************************************************************
*/
public class MyKeyboardView extends KeyboardView {
public static final int KEYBOARDTYPE_Num = 0;//Number keyboard
public static final int KEYBOARDTYPE_Num_Pwd = 1;//Number type keyboard(password)
public static final int KEYBOARDTYPE_ABC = 2;//letter keyboard
public static final int KEYBOARDTYPE_Symbol = 4;//symbol keyboard
public static final int KEYBOARDTYPE_Only_Num_Pwd = 5;//only number keyboard
private final String strLetter = "abcdefghijklmnopqrstuvwxyz";//letter
private EditText mEditText;
private PopupWindow mWindow;
private Activity mActivity;
private Keyboard keyboardNum;
private Keyboard keyboardNumPwd;
private Keyboard keyboardOnlyNumPwd;
private Keyboard keyboardABC;
private Keyboard keyboardSymbol;
private int mHeightPixels;//screen height
public boolean isSupper = false;//whether the letter keyboard is capitalized
public boolean isPwd = false;//whether the numbers on the number keyboard are random
private int keyBoardType;//keyboard type
private List<String> dataList = new ArrayList<>();
public MyKeyboardView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MyKeyboardView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public void setHeight(int mHeightPixels) {
this.mHeightPixels = mHeightPixels;
}
public void setContext(Activity mActivity) {
this.mActivity = mActivity;
}
public void init(EditText editText, PopupWindow window, int keyBoardType, List<String> dataList) {
this.dataList = dataList;
this.mEditText = editText;
this.mWindow = window;
this.keyBoardType = keyBoardType;
if (keyBoardType == KEYBOARDTYPE_Num_Pwd || keyBoardType == KEYBOARDTYPE_Only_Num_Pwd) {
isPwd = true;
}
setEnabled(true);
setPreviewEnabled(false);
setOnKeyboardActionListener(mOnKeyboardActionListener);
setKeyBoardType(keyBoardType);
}
public EditText getEditText() {
return mEditText;
}
/**
* set keyboard type
*/
public void setKeyBoardType(int keyBoardType) {
switch (keyBoardType) {
case KEYBOARDTYPE_Num:
if (keyboardNum == null) {
keyboardNum = new Keyboard(getContext(), R.xml.keyboard_number);
}
setKeyboard(keyboardNum);
break;
case KEYBOARDTYPE_ABC:
// if (keyboardABC == null) {
// keyboardABC = new Keyboard(getContext(), R.xml.keyboard_abc);
// }
// setKeyboard(keyboardABC);
break;
case KEYBOARDTYPE_Num_Pwd:
if (keyboardNumPwd == null) {
keyboardNumPwd = new Keyboard(getContext(), R.xml.keyboard_number);
}
randomKey(keyboardNumPwd);
setKeyboard(keyboardNumPwd);
break;
case KEYBOARDTYPE_Symbol:
if (keyboardSymbol == null) {
keyboardSymbol = new Keyboard(getContext(), R.xml.keyboard_symbol);
}
setKeyboard(keyboardSymbol);
break;
case KEYBOARDTYPE_Only_Num_Pwd:
if (keyboardOnlyNumPwd == null) {
keyboardOnlyNumPwd = new Keyboard(getContext(), R.xml.keyboard_only_number);
}
randomKey(keyboardOnlyNumPwd);
setKeyboard(keyboardOnlyNumPwd);
break;
}
}
private OnKeyboardActionListener mOnKeyboardActionListener = new OnKeyboardActionListener() {
@Override
public void onPress(int primaryCode) {
// List<Keyboard.Key> keys = keyboardOnlyNumPwd.getKeys();
// for(int i = 0 ; i < keys.size(); i++){
// Keyboard.Key key = keys.get(i);
//// key.
// new FancyShowCaseView.Builder(mActivity)
// .focusOn()
// .title("Focus on View")
// .build()
// .show();
// }
}
@Override
public void onRelease(int primaryCode) {
}
@Override
public void onKey(int primaryCode, int[] keyCodes) {
Editable editable = mEditText.getText();
int start = mEditText.getSelectionStart();
switch (primaryCode) {
case Keyboard.KEYCODE_DELETE://go back
if (editable != null && editable.length() > 0) {
if (start > 0) {
editable.delete(start - 1, start);
}
}
break;
case Keyboard.KEYCODE_SHIFT://switch uppercase or lowercase
changeKey();
setKeyBoardType(KEYBOARDTYPE_ABC);
break;
case Keyboard.KEYCODE_CANCEL:// hide
case Keyboard.KEYCODE_DONE:// confirm
mWindow.dismiss();
break;
case 123123://switch number keyboard
if (isPwd) {
setKeyBoardType(KEYBOARDTYPE_Num_Pwd);
} else {
setKeyBoardType(KEYBOARDTYPE_Num);
}
break;
case 456456://switch letter keyboard
if (isSupper)//if the current keyboard is uppercase, change to lowercase
{
changeKey();
}
setKeyBoardType(KEYBOARDTYPE_ABC);
break;
case 789789://switch symbol keyboard
setKeyBoardType(KEYBOARDTYPE_Symbol);
break;
case 666666:// name Delimiter"·"
editable.insert(start, "·");
break;
default://input symbol
editable.insert(start, "*");
// editable.insert(start, Character.toString((char) primaryCode));
}
}
@Override
public void onText(CharSequence text) {
}
@Override
public void swipeLeft() {
}
@Override
public void swipeRight() {
}
@Override
public void swipeDown() {
}
@Override
public void swipeUp() {
}
};
/**
* switch keyboard uppercase or lowercase
*/
private void changeKey() {
List<Keyboard.Key> keylist = keyboardABC.getKeys();
if (isSupper) {// switch uppercase to lowercase
for (Keyboard.Key key : keylist) {
if (key.label != null && strLetter.contains(key.label.toString().toLowerCase())) {
key.label = key.label.toString().toLowerCase();
key.codes[0] = key.codes[0] + 32;
}
}
} else {// Switch lowercase to uppercase
for (Keyboard.Key key : keylist) {
if (key.label != null && strLetter.contains(key.label.toString().toLowerCase())) {
key.label = key.label.toString().toUpperCase();
key.codes[0] = key.codes[0] - 32;
}
}
}
isSupper = !isSupper;
}
public static KeyBoardNumInterface keyBoardNumInterface;
/**
* random number keyboard
* code 48-57 (0-9)
*/
public void randomKey(Keyboard pLatinKeyboard) {
int[] ayRandomKey = new int[13];
if(dataList.size() == 0){
ayRandomKey = new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9, -3, 0, -4, -5};
// Random random = new Random();
// for (int i = 0; i < ayRandomKey.length; i++) {
// int a = random.nextInt(ayRandomKey.length);
// int temp = ayRandomKey[i];
// ayRandomKey[i] = ayRandomKey[a];
// ayRandomKey[a] = temp;
// }
}else {
for (int i = 0; i < dataList.size(); i++) {
ayRandomKey[i] = Integer.valueOf(dataList.get(i), 16);
}
}
List<Keyboard.Key> pKeyLis = pLatinKeyboard.getKeys();
int index = 0;
int sy = mHeightPixels - pLatinKeyboard.getHeight();
// int sy = mHeightPixels-80*5-8*4;//D20 is 60 and 6D1000 is 80 and 8
// Tip.i("sy = "+sy);
StringBuilder s = new StringBuilder();
for (int i = 0; i < pKeyLis.size(); i++) {
// if(i == 0){
// sy = mHeightPixels-pKeyLis.get(i).height*5-pKeyLis.get(i).x*6;//calculate interval value
// }
int code = pKeyLis.get(i).codes[0];
int y = sy + pKeyLis.get(i).y;
int x = pKeyLis.get(i).x;
int rit = x + pKeyLis.get(i).width;
int riby = y + pKeyLis.get(i).height;
String label;
if (code >= 0) {//number value
pKeyLis.get(i).label = ayRandomKey[index] + "";
pKeyLis.get(i).codes[0] = 48 + ayRandomKey[index];
String locationStr = QPOSUtil.byteArray2Hex(QPOSUtil.intToByteArray(ayRandomKey[index])) + QPOSUtil.byteArray2Hex(QPOSUtil.intToByteArray(x)) + QPOSUtil.byteArray2Hex(QPOSUtil.intToByteArray(y))
+ QPOSUtil.byteArray2Hex(QPOSUtil.intToByteArray(rit)) + QPOSUtil.byteArray2Hex(QPOSUtil.intToByteArray(riby));
s.append(locationStr);
index++;
} else {
if (code == -3) {
label = QPOSUtil.byteArray2Hex(QPOSUtil.intToByteArray(13));
} else if (code == -4) {
label = QPOSUtil.byteArray2Hex(QPOSUtil.intToByteArray(15));
} else {
label = QPOSUtil.byteArray2Hex(QPOSUtil.intToByteArray(14));
}
String locationStr = label + QPOSUtil.byteArray2Hex(QPOSUtil.intToByteArray(x)) + QPOSUtil.byteArray2Hex(QPOSUtil.intToByteArray(y))
+ QPOSUtil.byteArray2Hex(QPOSUtil.intToByteArray(rit)) + QPOSUtil.byteArray2Hex(QPOSUtil.intToByteArray(riby));
s.append(locationStr);
}
}
keyBoardNumInterface.getNumberValue(s.toString());
}
public static void setKeyBoardListener(KeyBoardNumInterface mkeyBoardNumInterface) {
keyBoardNumInterface = mkeyBoardNumInterface;
}
@Override
public void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (keyBoardType == KEYBOARDTYPE_Only_Num_Pwd) {//only number keyboard
List<Keyboard.Key> keys = getKeyboard().getKeys();
for (Keyboard.Key key : keys) {
if (key.codes[0] == -5) {//delete button
Drawable dr = getContext().getResources().getDrawable(R.drawable
.keyboard_white);
dr.setBounds(key.x, key.y, key.x + key.width, key.y + key.height);
dr.draw(canvas);
int drawableX = key.x + (key.width - key.icon.getIntrinsicWidth()) / 2;
int drawableY = key.y + (key.height - key.icon.getIntrinsicHeight()) / 2;
key.icon.setBounds(drawableX, drawableY, drawableX + key.icon
.getIntrinsicWidth(), drawableY + key.icon.getIntrinsicHeight());
key.icon.draw(canvas);
Log.i("test", "drawableX: " + drawableX + " drawableY: " + drawableY);
}
// Log.i("test","x: " +key.x+" y: "+key.y+" wi:"+key.width+" he:"+key.height);
}
}
}
}

View File

@ -0,0 +1,56 @@
package com.test.cardreadtest.payment.pinkeyboard;
import android.app.AlertDialog;
import android.content.Context;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.Window;
import android.widget.LinearLayout;
import com.test.cardreadtest.R;
public class PinPadDialog {
private AlertDialog mDialog;
private Window window;
private Context mContext;
private int mThemeResId;
private View mDialogLayout;
public PinPadDialog(Context context) {
this.mContext = context;
// this.mThemeResId = R.style.dialog_pay_theme;
this.mDialogLayout = LayoutInflater.from(mContext).inflate(R.layout.view_paypass_dialog, null);
mDialog = new AlertDialog.Builder(mContext, mThemeResId).create();
mDialog.setCancelable(true);
mDialog.show();
mDialog.getWindow().setDimAmount(0.4f);
window = mDialog.getWindow();
window.setLayout(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
window.setContentView(mDialogLayout);
mDialog.setCanceledOnTouchOutside(false);
// window.setWindowAnimations(R.style.dialogOpenAnimation);
window.setGravity(Gravity.BOTTOM);
}
public PinPadView getPayViewPass() {
return mDialogLayout.findViewById(R.id.pay_View);
}
public void dismiss() {
if (mDialog != null && mDialog.isShowing()) {
mDialog.dismiss();
mDialog = null;
window = null;
}
}
}

View File

@ -0,0 +1,282 @@
package com.test.cardreadtest.payment.pinkeyboard;
import android.app.Activity;
import android.content.Context;
import android.util.AttributeSet;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.EditorInfo;
import android.widget.BaseAdapter;
import android.widget.EditText;
import android.widget.GridView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.Nullable;
import com.test.cardreadtest.R;
import com.mulberry.xpos.QPOSService;
import com.mulberry.xpos.Util;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* Custom payment password component
*/
public class PinPadView extends RelativeLayout {
private Activity mContext;
private GridView mGridView;
private String savePwd = "";
private List<Integer> listNumber;//1,2,3---0
private View mPassLayout;
private boolean isRandom;
private EditText mEtinputpin;
private QPOSService pos;
private String pinData = "";
public static interface OnPayClickListener {
void onCencel();
void onPaypass();
void onConfirm(String password);
}
private OnPayClickListener mPayClickListener;
public void setPayClickListener(QPOSService qPOSService, OnPayClickListener listener) {
pos = qPOSService;
mPayClickListener = listener;
}
public PinPadView(Context context) {
super(context);
}
public PinPadView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public PinPadView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
this.mContext = (Activity) context;
initView();
this.addView(mPassLayout);
}
private void initView() {
mPassLayout = LayoutInflater.from(mContext).inflate(R.layout.view_paypass_layout, null);
mEtinputpin = mPassLayout.findViewById(R.id.et_inputpin);
mGridView = mPassLayout.findViewById(R.id.gv_pass);
mEtinputpin.setOnEditorActionListener(new TextView.OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if (actionId == EditorInfo.IME_ACTION_UNSPECIFIED
|| actionId == EditorInfo.IME_ACTION_DONE) {
pinData = mEtinputpin.getText().toString().trim();
mPayClickListener.onConfirm(pinData);
return true;
}
return false;
}
});
initData();
}
/**
* Is isRandom enabled for random numbers
*/
private void initData() {
if (isRandom) {
listNumber = new ArrayList<>();
listNumber.clear();
for (int i = 0; i <= 10; i++) {
listNumber.add(i);
}
//This method is to disrupt the order
Collections.shuffle(listNumber);
for (int i = 0; i <= 10; i++) {
if (listNumber.get(i) == 10) {
listNumber.remove(i);
listNumber.add(9, 10);
}
}
listNumber.add(R.mipmap.ic_pay_del0);
listNumber.add(R.mipmap.ic_pay_del0);
listNumber.add(R.mipmap.ic_pay_del0);
listNumber.add(R.mipmap.ic_pay_del0);
} else {
listNumber = new ArrayList<>();
listNumber.clear();
for (int i = 1; i <= 9; i++) {
listNumber.add(i);
}
listNumber.add(10);
listNumber.add(0);
listNumber.add(R.mipmap.ic_pay_del0);
}
mGridView.setAdapter(adapter);
}
/**
* Adapters for GridView
*/
BaseAdapter adapter = new BaseAdapter() {
@Override
public int getCount() {
return listNumber.size();
}
@Override
public Object getItem(int position) {
return listNumber.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
final ViewHolder holder;
if (convertView == null) {
convertView = View.inflate(mContext, R.layout.view_paypass_gridview_item, null);
holder = new ViewHolder();
holder.btnNumber = (TextView) convertView.findViewById(R.id.btNumber);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.btnNumber.setText(listNumber.get(position) + "");
if (position == 10) {
holder.btnNumber.setBackgroundColor(mContext.getResources().getColor(me.goldze.mvvmhabit.R.color.gray));
}
if (position == 9) {
holder.btnNumber.setText("Delete");
holder.btnNumber.setTextSize(15);
holder.btnNumber.setBackgroundColor(mContext.getResources().getColor(me.goldze.mvvmhabit.R.color.gray));
}
if (position == 11) {
holder.btnNumber.setText("Clear");
holder.btnNumber.setTextSize(15);
holder.btnNumber.setBackgroundResource(listNumber.get(position));
}
if (position == 12) {
holder.btnNumber.setText("pass");
holder.btnNumber.setTextSize(15);
holder.btnNumber.setBackgroundColor(mContext.getResources().getColor(me.goldze.mvvmhabit.R.color.gray));
}
if (position == 13) {
holder.btnNumber.setText(R.string.select_dialog_cancel);
holder.btnNumber.setTextSize(15);
holder.btnNumber.setBackgroundColor(mContext.getResources().getColor(me.goldze.mvvmhabit.R.color.gray));
}
if (position == 14) {
holder.btnNumber.setText(R.string.select_dialog_confirm);
holder.btnNumber.setTextSize(15);
holder.btnNumber.setBackgroundColor(mContext.getResources().getColor(me.goldze.mvvmhabit.R.color.gray));
}
if (position == 11) {
holder.btnNumber.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (position == 11) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
holder.btnNumber.setBackgroundResource(R.mipmap.ic_pay_del1);
break;
case MotionEvent.ACTION_MOVE:
holder.btnNumber.setBackgroundResource(R.mipmap.ic_pay_del1);
break;
case MotionEvent.ACTION_UP:
holder.btnNumber.setBackgroundResource(R.mipmap.ic_pay_del0);
break;
}
}
return false;
}
});
}
holder.btnNumber.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (position < 11 && position != 9) {
if (savePwd.length() == 12) {
return;
} else {
String SavePwds = String.valueOf(listNumber.get(position));
if (pos.getCvmKeyList() != null && !("").equals(pos.getCvmKeyList())) {
String keyList = Util.convertHexToString(pos.getCvmKeyList());
for (int j = 0; j < keyList.length(); j++) {
if (keyList.charAt(j) == SavePwds.charAt(0)) {
savePwd = savePwd + Integer.toHexString(j);
break;
}
}
}
mEtinputpin.setText(savePwd);
}
} else if (position == 11) {
if (savePwd.length() > 0) {
savePwd = savePwd.substring(0, savePwd.length() - 1);
mEtinputpin.setText(savePwd);
}
}
if (position == 9) {
if (savePwd.length() > 0) {
savePwd = "";
mEtinputpin.setText("");
}
} else if (position == 12) {//paypass
mPayClickListener.onPaypass();
} else if (position == 13) {//cancel
mPayClickListener.onCencel();
} else if (position == 14) {//confirm
pinData = mEtinputpin.getText().toString().trim();
if (pinData.length() >= 4 && pinData.length() <= 12) {
mPayClickListener.onConfirm(pinData);
} else {
Toast.makeText(mContext, "The length just can input 4 - 12 digits", Toast.LENGTH_SHORT).show();
}
}
}
});
return convertView;
}
};
static class ViewHolder {
public TextView btnNumber;
}
/***
* Set random number
* @param israndom
*/
public PinPadView setRandomNumber(boolean israndom) {
isRandom = israndom;
initData();
adapter.notifyDataSetChanged();
return this;
}
}

View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true">
<shape android:shape="rectangle">
<corners android:radius="4dp" />
<solid android:color="#D4D6D8" />
</shape>
</item>
<item>
<shape android:shape="rectangle">
<corners android:radius="4dp" />
<solid android:color="#FFFFFF" />
</shape>
</item>
</selector>

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="4dp" />
<solid android:color="@color/white" />
</shape>

View File

@ -43,6 +43,8 @@
android:text="@{viewModel.status}"
android:textSize="16sp"
android:layout_marginBottom="20dp"
android:visibility="@{viewModel.showProgress ? android.view.View.VISIBLE : android.view.View.GONE}"
tools:text="Status: Processing..." />
<!-- Progress Bar -->
@ -51,10 +53,12 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:visibility="@{viewModel.showProgress ? android.view.View.VISIBLE : android.view.View.GONE}"
android:layout_marginBottom="20dp" />
<!-- Transaction Results Section (Visible when transaction completes) -->
<LinearLayout
android:visibility="@{viewModel.showResults ? android.view.View.VISIBLE : android.view.View.GONE}"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
@ -92,6 +96,59 @@
</LinearLayout>
<ScrollView
android:id="@+id/scv_text"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:layout_margin="16dp"
android:layout_gravity="center">
<TextView
android:id="@+id/tv_receipt"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fontFamily="monospace"
android:padding="16dp"
android:textSize="16sp"
android:gravity="start"
android:textColor="@color/gray"
android:textIsSelectable="true"
android:textAlignment="viewStart"
android:text="@{viewModel.transactionResult}"
/>
</ScrollView>
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="16dp"
app:cardCornerRadius="8dp"
app:cardElevation="4dp"
android:visibility="@{viewModel.showPinpad ? android.view.View.VISIBLE : android.view.View.GONE}">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="16dp">
<EditText
android:id="@+id/pinpadEditText"
android:textCursorDrawable="@null"
android:focusable="false"
android:focusableInTouchMode="false"
android:cursorVisible="false"
android:clickable="false"
android:longClickable="false"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:textSize="20sp"
/>
</LinearLayout>
</androidx.cardview.widget.CardView>
<!-- Buttons Section -->
<LinearLayout
android:layout_width="match_parent"
@ -105,6 +162,7 @@
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Cancel"
android:visibility="@{viewModel.showResults ? android.view.View.VISIBLE : android.view.View.GONE}"
android:layout_marginEnd="10dp" />
<Button
@ -113,7 +171,8 @@
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Back to Main"
android:layout_marginStart="10dp" />
android:layout_marginStart="10dp"
android:visibility="@{viewModel.showResults ? android.view.View.VISIBLE : android.view.View.GONE}" />
</LinearLayout>

View File

@ -0,0 +1,51 @@
<?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:background="#e5e5e5"
android:orientation="vertical">
<RelativeLayout
android:id="@+id/keyboard_top_rl"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="SECURE PIN PAD"
android:textColor="#666666"
android:textSize="18dp"
android:textStyle="bold" />
<!-- <TextView-->
<!-- android:layout_width="wrap_content"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:layout_alignParentEnd="true"-->
<!-- android:layout_alignParentRight="true"-->
<!-- android:layout_centerVertical="true"-->
<!-- android:padding="10dp"-->
<!-- android:text="Cancel"-->
<!-- android:textStyle="bold"-->
<!-- android:textSize="16dp"-->
<!-- android:textColor="#0080f3"/>-->
</RelativeLayout>
<com.test.cardreadtest.payment.pinkeyboard.MyKeyboardView
android:id="@+id/keyboard_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:keyBackground="@color/gray"
android:keyPreviewOffset="0dp"
android:keyTextColor="@color/white"
android:background="@color/black"
android:keyTextSize="20dp"
android:focusable="true"
android:paddingBottom="6dp"
android:shadowColor="#FFFFFF"
android:shadowRadius="0.0" />
</LinearLayout>

View File

@ -0,0 +1,56 @@
<?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:background="#e5e5e5"
android:orientation="vertical">
<RelativeLayout
android:id="@+id/keyboard_top_rl"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="SECURE PIN PAD"
android:textColor="#666666"
android:textSize="18dp"
android:textStyle="bold" />
<!-- <TextView-->
<!-- android:layout_width="wrap_content"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:layout_alignParentEnd="true"-->
<!-- android:layout_alignParentRight="true"-->
<!-- android:layout_centerVertical="true"-->
<!-- android:padding="10dp"-->
<!-- android:text="Cancel"-->
<!-- android:textStyle="bold"-->
<!-- android:textSize="16dp"-->
<!-- android:textColor="#0080f3"/>-->
</RelativeLayout>
<EditText
android:id="@+id/pinpadEditText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:textSize="20sp"
/>
<com.test.cardreadtest.payment.pinkeyboard.MyKeyboardView
android:id="@+id/keyboard_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:keyBackground="@drawable/payview_stroke_gray_shape"
android:keyPreviewOffset="0dp"
android:keyTextColor="@color/white"
android:background="@color/black"
android:keyTextSize="20dp"
android:focusable="true"
android:paddingBottom="6dp"
android:shadowColor="#FFFFFF"
android:shadowRadius="0.0" />
</LinearLayout>

View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:ywl="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<com.test.cardreadtest.payment.pinkeyboard.PinPadView
android:id="@+id/pay_View"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>

View File

@ -0,0 +1,23 @@
<?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:padding="@dimen/dp_3"
xmlns:toosl="http://schemas.android.com/tools">
<!--<LinearLayout-->
<!--android:layout_width="match_parent"-->
<!--android:layout_height="wrap_content">-->
<Button
android:id="@+id/btNumber"
android:layout_width="match_parent"
android:layout_height="55dp"
toosl:text="1"
android:textSize="26sp"
android:textColor="@color/black"
android:background="@drawable/payview_btn_selector"/>
<!--</LinearLayout>-->
</LinearLayout>

View File

@ -0,0 +1,49 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:background="@color/gray"
android:orientation="vertical">
<!--==============pass=================-->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="@dimen/dp_3"
android:gravity="center"
android:orientation="horizontal"
>
<EditText
android:id="@+id/et_inputpin"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:inputType="textPassword"
android:textSize="30dp"
android:background="@color/graye3"
android:cursorVisible="false"
></EditText>
</LinearLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/white">
<GridView
android:id="@+id/gv_pass"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:horizontalSpacing="@dimen/dp_line"
android:verticalSpacing="@dimen/dp_line"
android:numColumns="3"
android:listSelector="@color/white" />
</RelativeLayout>
</LinearLayout>
</RelativeLayout>

Binary file not shown.

After

Width:  |  Height:  |  Size: 600 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@ -1,3 +1,5 @@
<resources>
<string name="app_name">CardReadTest</string>
<string name="select_dialog_cancel">Cancle</string>
<string name="select_dialog_confirm">OK</string>
</resources>

View File

@ -0,0 +1 @@
<?xml version="1.0" encoding="utf-8"?> <Keyboard xmlns:android="http://schemas.android.com/apk/res/android" android:horizontalGap="4dp" android:keyWidth="120dp" android:keyHeight="50dp" android:verticalGap="4dp">         <Row>              <Key android:codes="49" android:keyLabel="1" />                 <Key android:codes="50" android:keyLabel="2" />                 <Key android:codes="51" android:keyLabel="3" /> </Row>         <Row>              <Key android:codes="52" android:keyLabel="4" />                 <Key android:codes="53" android:keyLabel="5" />                 <Key android:codes="54" android:keyLabel="6" />  </Row>         <Row>            <Key android:codes="55" android:keyLabel="7" />                 <Key android:codes="56" android:keyLabel="8" />                 <Key android:codes="57" android:keyLabel="9" /> </Row>         <Row android:rowEdgeFlags="bottom"> <Key android:codes="-3" android:keyHeight="104dp" android:keyEdgeFlags="left" android:keyLabel="Cancel" /> <Key android:codes="48" android:keyLabel="0" /> <Key android:codes="-4" android:keyHeight="104dp" android:keyEdgeFlags="right" android:keyLabel="Confirm" /> </Row> <Row> <Key android:horizontalGap="108dp" android:codes="-5" android:keyWidth="104dp" android:keyIcon="@mipmap/icon_delete" /> </Row> </Keyboard>

View File

@ -0,0 +1 @@
<?xml version="1.0" encoding="utf-8"?> <Keyboard xmlns:android="http://schemas.android.com/apk/res/android" android:horizontalGap="2.875%p" android:keyWidth="29.5%p" android:keyHeight="8%p" android:verticalGap="10dp">         <Row>              <Key android:codes="49" android:keyLabel="1" />                 <Key android:codes="50" android:keyLabel="2" />                 <Key android:codes="51" android:keyLabel="3" /> </Row>         <Row>              <Key android:codes="52" android:keyLabel="4" />                 <Key android:codes="53" android:keyLabel="5" />                 <Key android:codes="54" android:keyLabel="6" />  </Row>         <Row>            <Key android:codes="55" android:keyLabel="7" />                 <Key android:codes="56" android:keyLabel="8" />                 <Key android:codes="57" android:keyLabel="9" /> </Row>         <Row android:rowEdgeFlags="bottom"> <Key android:codes="-3" android:keyHeight="17%p" android:keyEdgeFlags="left" android:keyLabel="Cancel" /> <Key android:codes="48" android:keyLabel="0" /> <Key android:codes="-4" android:keyHeight="17%p" android:keyEdgeFlags="right" android:keyLabel="Confirm" /> </Row> <Row> <Key android:horizontalGap="35.25%p" android:codes="-5" android:keyWidth="29.5%p" android:keyIcon="@mipmap/icon_delete" /> </Row> </Keyboard>

View File

@ -0,0 +1,150 @@
<?xml version="1.0" encoding="UTF-8"?>
<Keyboard xmlns:android="http://schemas.android.com/apk/res/android"
android:horizontalGap="4dp"
android:keyWidth="33dp"
android:keyHeight="44dp"
android:verticalGap="10dp">
<Row>
<Key
android:codes="33"
android:horizontalGap="6dp"
android:keyEdgeFlags="left"
android:keyLabel="!" />
<Key
android:codes="64"
android:keyLabel="\@" />
<Key
android:codes="35"
android:keyLabel="#" />
<Key
android:codes="36"
android:keyLabel="$" />
<Key
android:codes="37"
android:keyLabel="%" />
<Key
android:codes="94"
android:keyLabel="^" />
<!--&-->
<Key
android:codes="38"
android:keyLabel="&#038;" />
<Key
android:codes="42"
android:keyLabel="*" />
<Key
android:codes="40"
android:keyLabel="(" />
<Key
android:codes="41"
android:keyLabel=")" />
</Row>
<Row>
<Key
android:codes="39"
android:horizontalGap="6dp"
android:keyEdgeFlags="left"
android:keyLabel="'" />
<!--"-->
<Key
android:codes="34"
android:keyLabel="&#034;" />
<Key
android:codes="61"
android:keyLabel="=" />
<Key
android:codes="95"
android:keyLabel="_" />
<Key
android:codes="58"
android:keyLabel=":" />
<Key
android:codes="59"
android:keyLabel=";" />
<Key
android:codes="63"
android:keyLabel="\?" />
<Key
android:codes="126"
android:keyLabel="~" />
<Key
android:codes="124"
android:keyLabel="|" />
<Key
android:codes="666666"
android:keyLabel="·" />
</Row>
<Row>
<Key
android:codes="43"
android:horizontalGap="6dp"
android:keyLabel="+" />
<Key
android:codes="45"
android:keyLabel="-" />
<Key
android:codes="92"
android:keyLabel="\\" />
<Key
android:codes="47"
android:keyLabel="/" />
<Key
android:codes="91"
android:keyLabel="[" />
<Key
android:codes="93"
android:keyLabel="]" />
<Key
android:codes="123"
android:keyLabel="{" />
<Key
android:codes="125"
android:keyLabel="}" />
<Key
android:codes="-5"
android:isRepeatable="true"
android:keyWidth="70dp"
android:keyEdgeFlags="right"
android:keyIcon="@mipmap/icon_delete_1" />
</Row>
<Row android:rowEdgeFlags="bottom">
<Key
android:codes="123123"
android:horizontalGap="6dp"
android:keyWidth="51dp"
android:keyEdgeFlags="left"
android:keyLabel="123" />
<Key
android:codes="44"
android:keyLabel="," />
<Key
android:codes="46"
android:keyLabel="." />
<!--<-->
<Key
android:codes="60"
android:keyLabel="&#060;" />
<!-->-->
<Key
android:codes="62"
android:keyLabel="&#062;" />
<Key
android:codes="8364"
android:keyLabel="€" />
<Key
android:codes="163"
android:keyLabel="£" />
<Key
android:codes="165"
android:keyLabel="¥" />
<Key
android:codes="456456"
android:keyWidth="52dp"
android:keyEdgeFlags="right"
android:keyLabel="ABC" />
</Row>
</Keyboard>