add pin key keyboard
This commit is contained in:
parent
2f8234e241
commit
f95fac9f6e
Binary file not shown.
|
@ -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'
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -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 6,D1000 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);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
|
@ -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>
|
||||
|
|
@ -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>
|
|
@ -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>
|
|
@ -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 |
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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="&" />
|
||||
<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=""" />
|
||||
<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="<" />
|
||||
<!-->-->
|
||||
<Key
|
||||
android:codes="62"
|
||||
android:keyLabel=">" />
|
||||
<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>
|
Loading…
Reference in New Issue