menambahkan mdal pada screen emv
This commit is contained in:
parent
f403358554
commit
0af0e836b1
@ -9,7 +9,11 @@ import android.os.RemoteException;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.view.animation.Animation;
|
||||
import android.view.animation.AnimationUtils;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
@ -42,20 +46,29 @@ import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* EmvTransactionActivity - Handle card reading and EMV processing
|
||||
* EmvTransactionActivity - Handle card reading and EMV processing with Modal
|
||||
*/
|
||||
public class EmvTransactionActivity extends AppCompatActivity {
|
||||
private static final String TAG = "EmvTransaction";
|
||||
|
||||
// UI Components - SIMPLIFIED
|
||||
// UI Components - SIMPLIFIED + MODAL
|
||||
private LinearLayout mainContent;
|
||||
private FrameLayout modalOverlay;
|
||||
private TextView tvStatus;
|
||||
private TextView modalText;
|
||||
private ImageView modalIcon;
|
||||
private ProgressBar progressBar;
|
||||
private ImageView ivCardReader;
|
||||
|
||||
// Animation
|
||||
private Animation fadeIn;
|
||||
private Animation fadeOut;
|
||||
|
||||
// Transaction Data
|
||||
private String transactionAmount;
|
||||
private boolean isEMVMode;
|
||||
private boolean isProcessing = false;
|
||||
private boolean isModalShowing = false;
|
||||
|
||||
// EMV Components
|
||||
private EMVOptV2 mEMVOptV2;
|
||||
@ -85,6 +98,11 @@ public class EmvTransactionActivity extends AppCompatActivity {
|
||||
private static final int PIN_CLICK_CONFIRM = 52;
|
||||
private static final int PIN_CLICK_CANCEL = 53;
|
||||
private static final int PIN_ERROR = 54;
|
||||
|
||||
// Modal Display Messages
|
||||
private static final int SHOW_MODAL_SCAN_CARD = 101;
|
||||
private static final int SHOW_MODAL_PROCESSING = 102;
|
||||
private static final int HIDE_MODAL = 103;
|
||||
|
||||
private final Handler mHandler = new Handler(Looper.getMainLooper()) {
|
||||
@Override
|
||||
@ -110,10 +128,12 @@ public class EmvTransactionActivity extends AppCompatActivity {
|
||||
|
||||
case EMV_SHOW_PIN_PAD:
|
||||
android.util.Log.d(TAG, "Initializing PIN pad...");
|
||||
hideModal();
|
||||
initPinPad();
|
||||
break;
|
||||
|
||||
case EMV_ONLINE_PROCESS:
|
||||
showModalProcessing("Memproses Otorisasi Online...");
|
||||
mockOnlineProcess();
|
||||
break;
|
||||
|
||||
@ -149,6 +169,7 @@ public class EmvTransactionActivity extends AppCompatActivity {
|
||||
|
||||
Log.e(TAG, "EMV Transaction failed: " + errorDesc + " (Code: " + errorCode + ")");
|
||||
|
||||
hideModal();
|
||||
if (errorCode == -50009) {
|
||||
// EMV process conflict - reset and retry
|
||||
Log.d(TAG, "EMV process conflict detected - resetting...");
|
||||
@ -163,8 +184,22 @@ public class EmvTransactionActivity extends AppCompatActivity {
|
||||
|
||||
case EMV_TRANS_SUCCESS:
|
||||
// Navigate to results screen
|
||||
hideModal();
|
||||
navigateToResults();
|
||||
break;
|
||||
|
||||
case SHOW_MODAL_SCAN_CARD:
|
||||
showModalScanCard();
|
||||
break;
|
||||
|
||||
case SHOW_MODAL_PROCESSING:
|
||||
String processingMsg = (String) msg.obj;
|
||||
showModalProcessing(processingMsg);
|
||||
break;
|
||||
|
||||
case HIDE_MODAL:
|
||||
hideModal();
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -176,6 +211,7 @@ public class EmvTransactionActivity extends AppCompatActivity {
|
||||
|
||||
getIntentData();
|
||||
initViews();
|
||||
initAnimations();
|
||||
initEMVComponents();
|
||||
initEMVData();
|
||||
|
||||
@ -208,12 +244,96 @@ public class EmvTransactionActivity extends AppCompatActivity {
|
||||
}
|
||||
|
||||
// Initialize UI components
|
||||
mainContent = findViewById(R.id.main_content);
|
||||
modalOverlay = findViewById(R.id.modal_overlay);
|
||||
tvStatus = findViewById(R.id.tv_status);
|
||||
progressBar = findViewById(R.id.progress_bar);
|
||||
ivCardReader = findViewById(R.id.iv_card_reader);
|
||||
modalText = findViewById(R.id.modal_text);
|
||||
modalIcon = findViewById(R.id.modal_icon);
|
||||
|
||||
// Set initial state
|
||||
updateStatusUI("Initializing scanner...", true);
|
||||
|
||||
// Setup modal overlay click to close
|
||||
modalOverlay.setOnClickListener(v -> {
|
||||
// Optional: close modal when clicking outside
|
||||
// hideModal();
|
||||
});
|
||||
}
|
||||
|
||||
// ====== ANIMATION INITIALIZATION ======
|
||||
private void initAnimations() {
|
||||
// Create fade animations programmatically since we want to avoid new resources
|
||||
fadeIn = AnimationUtils.loadAnimation(this, android.R.anim.fade_in);
|
||||
fadeOut = AnimationUtils.loadAnimation(this, android.R.anim.fade_out);
|
||||
|
||||
// Set animation duration
|
||||
fadeIn.setDuration(300);
|
||||
fadeOut.setDuration(300);
|
||||
}
|
||||
|
||||
// ====== MODAL METHODS ======
|
||||
private void showModalScanCard() {
|
||||
if (isModalShowing) return;
|
||||
|
||||
runOnUiThread(() -> {
|
||||
modalText.setText("Silakan Tempelkan / Gesekkan / Masukkan Kartu ke Perangkat");
|
||||
modalIcon.setImageResource(R.drawable.ic_card_insert);
|
||||
|
||||
modalOverlay.setVisibility(View.VISIBLE);
|
||||
modalOverlay.startAnimation(fadeIn);
|
||||
|
||||
isModalShowing = true;
|
||||
|
||||
Log.d(TAG, "Modal scan card shown");
|
||||
});
|
||||
}
|
||||
|
||||
private void showModalProcessing(String message) {
|
||||
if (!isModalShowing) {
|
||||
runOnUiThread(() -> {
|
||||
modalText.setText(message);
|
||||
modalIcon.setImageResource(R.drawable.ic_card_insert);
|
||||
|
||||
modalOverlay.setVisibility(View.VISIBLE);
|
||||
modalOverlay.startAnimation(fadeIn);
|
||||
|
||||
isModalShowing = true;
|
||||
|
||||
Log.d(TAG, "Modal processing shown: " + message);
|
||||
});
|
||||
} else {
|
||||
// Just update text if modal already showing
|
||||
runOnUiThread(() -> {
|
||||
modalText.setText(message);
|
||||
Log.d(TAG, "Modal text updated: " + message);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void hideModal() {
|
||||
if (!isModalShowing) return;
|
||||
|
||||
runOnUiThread(() -> {
|
||||
fadeOut.setAnimationListener(new Animation.AnimationListener() {
|
||||
@Override
|
||||
public void onAnimationStart(Animation animation) {}
|
||||
|
||||
@Override
|
||||
public void onAnimationEnd(Animation animation) {
|
||||
modalOverlay.setVisibility(View.GONE);
|
||||
isModalShowing = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationRepeat(Animation animation) {}
|
||||
});
|
||||
|
||||
modalOverlay.startAnimation(fadeOut);
|
||||
|
||||
Log.d(TAG, "Modal hidden");
|
||||
});
|
||||
}
|
||||
|
||||
// ====== NEW METHOD TO UPDATE STATUS UI ======
|
||||
@ -314,6 +434,9 @@ public class EmvTransactionActivity extends AppCompatActivity {
|
||||
|
||||
updateStatusUI("Ready for card...\n\nPlease insert, swipe, or tap your card\n\nScanning will start automatically", true);
|
||||
|
||||
// Show modal for card scanning
|
||||
mHandler.obtainMessage(SHOW_MODAL_SCAN_CARD).sendToTarget();
|
||||
|
||||
// Start scanning automatically
|
||||
startCardCheck();
|
||||
}
|
||||
@ -396,6 +519,9 @@ public class EmvTransactionActivity extends AppCompatActivity {
|
||||
updateStatusUI("Scan error: " + errorMessage + "\n\nRetrying in 2 seconds...", false);
|
||||
showToast(errorMessage);
|
||||
|
||||
// Hide modal on error
|
||||
hideModal();
|
||||
|
||||
// Auto-restart scanning after error
|
||||
restartAutoScanning();
|
||||
}
|
||||
@ -460,39 +586,65 @@ public class EmvTransactionActivity extends AppCompatActivity {
|
||||
@Override
|
||||
public void findMagCard(Bundle info) throws RemoteException {
|
||||
android.util.Log.d(TAG, "Simple Mode: findMagCard callback triggered");
|
||||
runOnUiThread(() -> handleSimpleCardResult(info, "MAGNETIC"));
|
||||
runOnUiThread(() -> {
|
||||
showModalProcessing("Kartu Ditemukan - Memproses...");
|
||||
new Handler(Looper.getMainLooper()).postDelayed(() -> {
|
||||
handleSimpleCardResult(info, "MAGNETIC");
|
||||
}, 1500);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void findICCard(String atr) throws RemoteException {
|
||||
Bundle info = new Bundle();
|
||||
info.putString("atr", atr);
|
||||
runOnUiThread(() -> handleSimpleCardResult(info, "IC"));
|
||||
runOnUiThread(() -> {
|
||||
showModalProcessing("Kartu IC Ditemukan - Memproses...");
|
||||
new Handler(Looper.getMainLooper()).postDelayed(() -> {
|
||||
handleSimpleCardResult(info, "IC");
|
||||
}, 1500);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void findRFCard(String uuid) throws RemoteException {
|
||||
Bundle info = new Bundle();
|
||||
info.putString("uuid", uuid);
|
||||
runOnUiThread(() -> handleSimpleCardResult(info, "NFC"));
|
||||
runOnUiThread(() -> {
|
||||
showModalProcessing("Kartu NFC Ditemukan - Memproses...");
|
||||
new Handler(Looper.getMainLooper()).postDelayed(() -> {
|
||||
handleSimpleCardResult(info, "NFC");
|
||||
}, 1500);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(int code, String message) throws RemoteException {
|
||||
runOnUiThread(() -> {
|
||||
showToast("Card error: " + message);
|
||||
hideModal();
|
||||
stopCardCheck();
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void findICCardEx(Bundle info) throws RemoteException {
|
||||
runOnUiThread(() -> handleSimpleCardResult(info, "IC"));
|
||||
runOnUiThread(() -> {
|
||||
showModalProcessing("Kartu IC Ditemukan - Memproses...");
|
||||
new Handler(Looper.getMainLooper()).postDelayed(() -> {
|
||||
handleSimpleCardResult(info, "IC");
|
||||
}, 1500);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void findRFCardEx(Bundle info) throws RemoteException {
|
||||
runOnUiThread(() -> handleSimpleCardResult(info, "NFC"));
|
||||
runOnUiThread(() -> {
|
||||
showModalProcessing("Kartu NFC Ditemukan - Memproses...");
|
||||
new Handler(Looper.getMainLooper()).postDelayed(() -> {
|
||||
handleSimpleCardResult(info, "NFC");
|
||||
}, 1500);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -500,6 +652,7 @@ public class EmvTransactionActivity extends AppCompatActivity {
|
||||
runOnUiThread(() -> {
|
||||
String msg = info.getString("message", "Unknown error");
|
||||
showToast("Card error: " + msg);
|
||||
hideModal();
|
||||
stopCardCheck();
|
||||
});
|
||||
}
|
||||
@ -509,26 +662,38 @@ public class EmvTransactionActivity extends AppCompatActivity {
|
||||
private final CheckCardCallbackV2 mEMVCheckCardCallback = new CheckCardCallbackV2.Stub() {
|
||||
@Override
|
||||
public void findMagCard(Bundle info) throws RemoteException {
|
||||
runOnUiThread(() -> handleSimpleCardResult(info, "MAGNETIC"));
|
||||
runOnUiThread(() -> {
|
||||
showModalProcessing("Kartu Magnetik Ditemukan - Memproses...");
|
||||
new Handler(Looper.getMainLooper()).postDelayed(() -> {
|
||||
handleSimpleCardResult(info, "MAGNETIC");
|
||||
}, 1500);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void findICCard(String atr) throws RemoteException {
|
||||
MyApplication.app.basicOptV2.buzzerOnDevice(1, 2750, 200, 0);
|
||||
mCardType = AidlConstantsV2.CardType.IC.getValue();
|
||||
runOnUiThread(() -> startEMVTransactionProcess());
|
||||
runOnUiThread(() -> {
|
||||
showModalProcessing("Kartu IC Ditemukan - Memulai EMV...");
|
||||
startEMVTransactionProcess();
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void findRFCard(String uuid) throws RemoteException {
|
||||
mCardType = AidlConstantsV2.CardType.NFC.getValue();
|
||||
runOnUiThread(() -> startEMVTransactionProcess());
|
||||
runOnUiThread(() -> {
|
||||
showModalProcessing("Kartu NFC Ditemukan - Memulai EMV...");
|
||||
startEMVTransactionProcess();
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(int code, String message) throws RemoteException {
|
||||
runOnUiThread(() -> {
|
||||
showToast("EMV Error: " + message);
|
||||
hideModal();
|
||||
stopCardCheck();
|
||||
});
|
||||
}
|
||||
@ -536,13 +701,19 @@ public class EmvTransactionActivity extends AppCompatActivity {
|
||||
@Override
|
||||
public void findICCardEx(Bundle info) throws RemoteException {
|
||||
mCardType = AidlConstantsV2.CardType.IC.getValue();
|
||||
runOnUiThread(() -> startEMVTransactionProcess());
|
||||
runOnUiThread(() -> {
|
||||
showModalProcessing("Kartu IC Ditemukan - Memulai EMV...");
|
||||
startEMVTransactionProcess();
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void findRFCardEx(Bundle info) throws RemoteException {
|
||||
mCardType = AidlConstantsV2.CardType.NFC.getValue();
|
||||
runOnUiThread(() -> startEMVTransactionProcess());
|
||||
runOnUiThread(() -> {
|
||||
showModalProcessing("Kartu NFC Ditemukan - Memulai EMV...");
|
||||
startEMVTransactionProcess();
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -550,6 +721,7 @@ public class EmvTransactionActivity extends AppCompatActivity {
|
||||
runOnUiThread(() -> {
|
||||
String msg = info.getString("message", "Unknown error");
|
||||
showToast("EMV Error: " + msg);
|
||||
hideModal();
|
||||
stopCardCheck();
|
||||
});
|
||||
}
|
||||
@ -601,12 +773,14 @@ public class EmvTransactionActivity extends AppCompatActivity {
|
||||
bundle.putInt("cardType", mCardType);
|
||||
|
||||
updateStatusUI("EMV processing started...\nReading card data...", true);
|
||||
showModalProcessing("Memproses Data Kartu EMV...");
|
||||
|
||||
Log.d(TAG, "Starting transactProcessEx with reset EMV");
|
||||
mEMVOptV2.transactProcessEx(bundle, mEMVListener);
|
||||
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "Error in delayed EMV start: " + e.getMessage(), e);
|
||||
hideModal();
|
||||
resetScanningState();
|
||||
showToast("Error starting EMV: " + e.getMessage());
|
||||
}
|
||||
@ -615,6 +789,7 @@ public class EmvTransactionActivity extends AppCompatActivity {
|
||||
} catch (Exception e) {
|
||||
android.util.Log.e(TAG, "Error starting EMV transaction: " + e.getMessage());
|
||||
e.printStackTrace();
|
||||
hideModal();
|
||||
resetScanningState();
|
||||
showToast("Error starting EMV transaction: " + e.getMessage());
|
||||
}
|
||||
@ -628,6 +803,7 @@ public class EmvTransactionActivity extends AppCompatActivity {
|
||||
android.util.Log.d(TAG, "onWaitAppSelect isFirstSelect:" + isFirstSelect);
|
||||
mProcessStep = EMV_APP_SELECT;
|
||||
String[] candidateNames = getCandidateNames(appNameList);
|
||||
runOnUiThread(() -> hideModal());
|
||||
mHandler.obtainMessage(EMV_APP_SELECT, candidateNames).sendToTarget();
|
||||
}
|
||||
|
||||
@ -751,6 +927,7 @@ public class EmvTransactionActivity extends AppCompatActivity {
|
||||
String displayText = "Card Number Detected:\n" + maskCardNumber(mCardNo) +
|
||||
"\n\nConfirming automatically...";
|
||||
updateStatusUI(displayText, true);
|
||||
showModalProcessing("Mengkonfirmasi Nomor Kartu...");
|
||||
|
||||
// Auto-confirm after short delay
|
||||
new Handler(Looper.getMainLooper()).postDelayed(() -> {
|
||||
@ -767,6 +944,7 @@ public class EmvTransactionActivity extends AppCompatActivity {
|
||||
String displayText = "Certificate Verification:\n" + mCertInfo +
|
||||
"\n\nProcessing automatically...";
|
||||
updateStatusUI(displayText, true);
|
||||
showModalProcessing("Memverifikasi Sertifikat...");
|
||||
|
||||
// Auto-confirm after short delay
|
||||
new Handler(Looper.getMainLooper()).postDelayed(() -> {
|
||||
@ -793,7 +971,7 @@ public class EmvTransactionActivity extends AppCompatActivity {
|
||||
PinPadConfigV2 pinPadConfig = new PinPadConfigV2();
|
||||
pinPadConfig.setPinPadType(0);
|
||||
pinPadConfig.setPinType(mPinType);
|
||||
pinPadConfig.setOrderNumKey(true);
|
||||
pinPadConfig.setOrderNumKey(true); // Set to true for normal order, false for random
|
||||
|
||||
String panForPin = mCardNo.substring(mCardNo.length() - 13, mCardNo.length() - 1);
|
||||
byte[] panBytes = panForPin.getBytes("US-ASCII");
|
||||
@ -837,6 +1015,7 @@ public class EmvTransactionActivity extends AppCompatActivity {
|
||||
|
||||
runOnUiThread(() -> {
|
||||
updateStatusUI("PIN confirmed, processing...", true);
|
||||
showModalProcessing("PIN Dikonfirmasi - Memproses...");
|
||||
});
|
||||
|
||||
if (pinBlock != null) {
|
||||
@ -855,6 +1034,7 @@ public class EmvTransactionActivity extends AppCompatActivity {
|
||||
|
||||
runOnUiThread(() -> {
|
||||
updateStatusUI("PIN input cancelled", false);
|
||||
hideModal();
|
||||
});
|
||||
|
||||
mHandler.obtainMessage(PIN_CLICK_CANCEL).sendToTarget();
|
||||
@ -867,6 +1047,7 @@ public class EmvTransactionActivity extends AppCompatActivity {
|
||||
|
||||
runOnUiThread(() -> {
|
||||
updateStatusUI("PIN error: " + msg, false);
|
||||
hideModal();
|
||||
});
|
||||
|
||||
mHandler.obtainMessage(PIN_ERROR, code, code, msg).sendToTarget();
|
||||
@ -926,6 +1107,7 @@ public class EmvTransactionActivity extends AppCompatActivity {
|
||||
mProcessStep = 0;
|
||||
|
||||
updateStatusUI("Ready for card...\n\nPlease insert, swipe, or tap your card", true);
|
||||
hideModal();
|
||||
}
|
||||
|
||||
// ====== HELPER METHODS ======
|
||||
@ -1066,6 +1248,8 @@ public class EmvTransactionActivity extends AppCompatActivity {
|
||||
isProcessing = false;
|
||||
mProcessStep = 0;
|
||||
|
||||
hideModal();
|
||||
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "Error cleaning up on back press: " + e.getMessage());
|
||||
}
|
||||
@ -1092,6 +1276,8 @@ public class EmvTransactionActivity extends AppCompatActivity {
|
||||
mEMVOptV2.initEmvProcess();
|
||||
}
|
||||
|
||||
hideModal();
|
||||
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "Error cleaning up EMV: " + e.getMessage());
|
||||
}
|
||||
|
10
app/src/main/res/anim/slide_down.xml
Normal file
10
app/src/main/res/anim/slide_down.xml
Normal file
@ -0,0 +1,10 @@
|
||||
<set xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<translate
|
||||
android:duration="300"
|
||||
android:fromYDelta="0%p"
|
||||
android:toYDelta="50%p" />
|
||||
<alpha
|
||||
android:duration="300"
|
||||
android:fromAlpha="1.0"
|
||||
android:toAlpha="0.0" />
|
||||
</set>
|
10
app/src/main/res/anim/slide_up.xml
Normal file
10
app/src/main/res/anim/slide_up.xml
Normal file
@ -0,0 +1,10 @@
|
||||
<set xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<translate
|
||||
android:duration="300"
|
||||
android:fromYDelta="50%p"
|
||||
android:toYDelta="0%p" />
|
||||
<alpha
|
||||
android:duration="300"
|
||||
android:fromAlpha="0.0"
|
||||
android:toAlpha="1.0" />
|
||||
</set>
|
@ -1,35 +1,123 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:background="@color/colorBackground"
|
||||
tools:context=".kredit.EmvTransactionActivity">
|
||||
|
||||
<!-- Toolbar -->
|
||||
<androidx.appcompat.widget.Toolbar
|
||||
android:id="@+id/toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?attr/actionBarSize"
|
||||
android:background="@color/primary_blue"
|
||||
android:theme="@style/CustomToolbarTheme"
|
||||
app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
|
||||
|
||||
<!-- Main Content Container with Center Alignment -->
|
||||
<!-- Main Content -->
|
||||
<LinearLayout
|
||||
android:id="@+id/main_content"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:gravity="center"
|
||||
android:padding="24dp">
|
||||
android:orientation="vertical">
|
||||
|
||||
<!-- Status Modal Card - Centered and Compact -->
|
||||
<!-- Toolbar -->
|
||||
<androidx.appcompat.widget.Toolbar
|
||||
android:id="@+id/toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?attr/actionBarSize"
|
||||
android:background="@color/primary_blue"
|
||||
android:theme="@style/CustomToolbarTheme"
|
||||
app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
|
||||
|
||||
<!-- Main Content Container with Center Alignment -->
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:gravity="center"
|
||||
android:padding="24dp">
|
||||
|
||||
<!-- Status Modal Card - Centered and Compact -->
|
||||
<androidx.cardview.widget.CardView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
app:cardCornerRadius="16dp"
|
||||
app:cardElevation="8dp"
|
||||
app:cardBackgroundColor="@android:color/white">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:padding="32dp"
|
||||
android:gravity="center">
|
||||
|
||||
<!-- Header Title -->
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Card Scanner"
|
||||
style="@style/HeaderTextStyle"
|
||||
android:layout_marginBottom="24dp" />
|
||||
|
||||
<!-- Card Reader Animation/Icon -->
|
||||
<ImageView
|
||||
android:id="@+id/iv_card_reader"
|
||||
android:layout_width="120dp"
|
||||
android:layout_height="120dp"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginBottom="24dp"
|
||||
android:src="@drawable/ic_card_insert"
|
||||
android:scaleType="centerInside"
|
||||
app:tint="@color/primary_blue" />
|
||||
|
||||
<!-- Status Text -->
|
||||
<TextView
|
||||
android:id="@+id/tv_status"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Ready for card scanning..."
|
||||
style="@style/StatusTextStyle"
|
||||
android:layout_marginBottom="24dp" />
|
||||
|
||||
<!-- Progress Indicator -->
|
||||
<ProgressBar
|
||||
android:id="@+id/progress_bar"
|
||||
style="?android:attr/progressBarStyle"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
android:layout_gravity="center"
|
||||
android:visibility="visible"
|
||||
android:indeterminateTint="@color/primary_blue"
|
||||
android:layout_marginBottom="16dp" />
|
||||
|
||||
<!-- Instructions Text -->
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Please insert, tap, or swipe your card\nScanning will start automatically"
|
||||
style="@style/HintTextStyle"
|
||||
android:gravity="center" />
|
||||
|
||||
</LinearLayout>
|
||||
</androidx.cardview.widget.CardView>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<!-- Modal Overlay with Blur Effect -->
|
||||
<FrameLayout
|
||||
android:id="@+id/modal_overlay"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="#80000000"
|
||||
android:visibility="gone"
|
||||
android:clickable="true"
|
||||
android:focusable="true">
|
||||
|
||||
<!-- Modal Content -->
|
||||
<androidx.cardview.widget.CardView
|
||||
android:id="@+id/modal_card"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:layout_margin="32dp"
|
||||
app:cardCornerRadius="16dp"
|
||||
app:cardElevation="8dp"
|
||||
app:cardBackgroundColor="@android:color/white">
|
||||
@ -41,67 +129,32 @@
|
||||
android:padding="32dp"
|
||||
android:gravity="center">
|
||||
|
||||
<!-- Header Title -->
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Card Scanner"
|
||||
android:textSize="24sp"
|
||||
android:textStyle="bold"
|
||||
android:textColor="#2E3A47"
|
||||
android:gravity="center"
|
||||
android:fontFamily="@font/inter"
|
||||
android:layout_marginBottom="24dp" />
|
||||
|
||||
<!-- Card Reader Animation/Icon -->
|
||||
<!-- Card Icon -->
|
||||
<ImageView
|
||||
android:id="@+id/iv_card_reader"
|
||||
android:layout_width="120dp"
|
||||
android:layout_height="120dp"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginBottom="24dp"
|
||||
android:id="@+id/modal_icon"
|
||||
android:layout_width="80dp"
|
||||
android:layout_height="80dp"
|
||||
android:src="@drawable/ic_card_insert"
|
||||
android:scaleType="centerInside"
|
||||
android:layout_marginBottom="24dp"
|
||||
android:scaleType="fitCenter"
|
||||
android:adjustViewBounds="true"
|
||||
app:tint="@color/primary_blue" />
|
||||
|
||||
<!-- Status Text -->
|
||||
<!-- Main Text -->
|
||||
<TextView
|
||||
android:id="@+id/tv_status"
|
||||
android:layout_width="match_parent"
|
||||
android:id="@+id/modal_text"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Ready for card scanning..."
|
||||
android:textSize="16sp"
|
||||
android:textColor="#5A6C7D"
|
||||
android:text="Silakan Tempelkan / Gesekkan / Masukkan Kartu ke Perangkat"
|
||||
style="@style/StatusTextStyle"
|
||||
android:textAlignment="center"
|
||||
android:gravity="center"
|
||||
android:lineSpacingExtra="4dp"
|
||||
android:fontFamily="@font/inter"
|
||||
android:layout_marginBottom="24dp" />
|
||||
|
||||
<!-- Progress Indicator -->
|
||||
<ProgressBar
|
||||
android:id="@+id/progress_bar"
|
||||
style="?android:attr/progressBarStyle"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
android:layout_gravity="center"
|
||||
android:visibility="visible"
|
||||
android:indeterminateTint="@color/primary_blue"
|
||||
android:layout_marginBottom="16dp" />
|
||||
|
||||
<!-- Instructions Text -->
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Please insert, tap, or swipe your card\nScanning will start automatically"
|
||||
android:textSize="14sp"
|
||||
android:textColor="#8A9BAE"
|
||||
android:gravity="center"
|
||||
android:lineSpacingExtra="2dp"
|
||||
android:fontFamily="@font/inter" />
|
||||
android:lineSpacingExtra="4dp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.cardview.widget.CardView>
|
||||
|
||||
</LinearLayout>
|
||||
</FrameLayout>
|
||||
|
||||
</LinearLayout>
|
||||
</FrameLayout>
|
Loading…
x
Reference in New Issue
Block a user