package com.example.bdkipoc; import android.animation.AnimatorSet; import android.animation.ObjectAnimator; import android.content.Intent; import android.graphics.Color; import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.os.Looper; import android.text.TextUtils; import android.view.View; import android.view.Window; import android.view.WindowManager; import android.view.animation.AccelerateDecelerateInterpolator; import android.widget.Button; import android.widget.EditText; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; import android.widget.Toast; import androidx.appcompat.app.AppCompatActivity; public class PaymentActivity extends AppCompatActivity { // Views private EditText editTextAmount; private Button confirmButton; private LinearLayout backNavigation; private ImageView backArrow; private TextView toolbarTitle; // Numpad buttons private TextView btn1, btn2, btn3, btn4, btn5, btn6, btn7, btn8, btn9, btn0, btn000; private ImageView btnDelete; // Data private StringBuilder currentAmount = new StringBuilder(); private static final int MAX_AMOUNT_LENGTH = 12; // Animation private Handler animationHandler = new Handler(Looper.getMainLooper()); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Set status bar color programmatically setStatusBarColor(); setContentView(R.layout.activity_payment); initializeViews(); setupClickListeners(); setupInitialStates(); // REMOVED: addAnimations() - No more card sliding animation } private void setStatusBarColor() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { Window window = getWindow(); window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS); window.setStatusBarColor(Color.parseColor("#E31937")); // Red color // Make status bar icons white (for dark red background) if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { View decorView = window.getDecorView(); decorView.setSystemUiVisibility(0); // Clear light status bar flag } } } private void initializeViews() { // Main views editTextAmount = findViewById(R.id.editTextAmount); confirmButton = findViewById(R.id.confirmButton); backNavigation = findViewById(R.id.back_navigation); backArrow = findViewById(R.id.backArrow); toolbarTitle = findViewById(R.id.toolbarTitle); // Numpad buttons btn1 = findViewById(R.id.btn1); btn2 = findViewById(R.id.btn2); btn3 = findViewById(R.id.btn3); btn4 = findViewById(R.id.btn4); btn5 = findViewById(R.id.btn5); btn6 = findViewById(R.id.btn6); btn7 = findViewById(R.id.btn7); btn8 = findViewById(R.id.btn8); btn9 = findViewById(R.id.btn9); btn0 = findViewById(R.id.btn0); btn000 = findViewById(R.id.btn000); btnDelete = findViewById(R.id.btnDelete); } private void setupClickListeners() { // Back navigation - entire LinearLayout is clickable backNavigation.setOnClickListener(v -> { addClickAnimation(v); navigateBack(); }); // Individual back arrow (for additional touch area) backArrow.setOnClickListener(v -> { addClickAnimation(v); navigateBack(); }); // Toolbar title (also clickable for back navigation) toolbarTitle.setOnClickListener(v -> { addClickAnimation(v); navigateBack(); }); // Numpad listeners btn1.setOnClickListener(v -> handleNumpadClick(v, "1")); btn2.setOnClickListener(v -> handleNumpadClick(v, "2")); btn3.setOnClickListener(v -> handleNumpadClick(v, "3")); btn4.setOnClickListener(v -> handleNumpadClick(v, "4")); btn5.setOnClickListener(v -> handleNumpadClick(v, "5")); btn6.setOnClickListener(v -> handleNumpadClick(v, "6")); btn7.setOnClickListener(v -> handleNumpadClick(v, "7")); btn8.setOnClickListener(v -> handleNumpadClick(v, "8")); btn9.setOnClickListener(v -> handleNumpadClick(v, "9")); btn0.setOnClickListener(v -> handleNumpadClick(v, "0")); btn000.setOnClickListener(v -> handleNumpadClick(v, "000")); // Delete button btnDelete.setOnClickListener(v -> { addClickAnimation(v); deleteLastDigit(); }); // Confirm button confirmButton.setOnClickListener(v -> { if (confirmButton.isEnabled()) { addButtonClickAnimation(v); handleConfirmPayment(); } }); } private void navigateBack() { // Simple back navigation without card animation finish(); } private void handleNumpadClick(View view, String digit) { addClickAnimation(view); addDigit(digit); } private void setupInitialStates() { // Set initial amount display editTextAmount.setText(""); // Set initial button state updateButtonState(); // Disable EditText input (only numpad input allowed) editTextAmount.setFocusable(false); editTextAmount.setClickable(false); editTextAmount.setCursorVisible(false); } // REMOVED: addAnimations() method - No card sliding animation on startup private void addDigit(String digit) { // Validate input length if (currentAmount.length() >= MAX_AMOUNT_LENGTH) { showToast("Maksimal " + MAX_AMOUNT_LENGTH + " digit"); return; } // Handle leading zeros if (currentAmount.length() == 0) { if (digit.equals("000")) { // Don't allow 000 as first input return; } currentAmount.append(digit); } else if (currentAmount.length() == 1 && currentAmount.toString().equals("0")) { if (!digit.equals("000")) { // Replace single 0 with new digit currentAmount = new StringBuilder(digit); } else { return; } } else { currentAmount.append(digit); } updateAmountDisplay(); updateButtonState(); addInputFeedback(); } private void deleteLastDigit() { if (currentAmount.length() > 0) { String current = currentAmount.toString(); // If current ends with 000, remove all three digits if (current.endsWith("000") && current.length() >= 3) { currentAmount.delete(currentAmount.length() - 3, currentAmount.length()); } else { currentAmount.deleteCharAt(currentAmount.length() - 1); } updateAmountDisplay(); updateButtonState(); addDeleteFeedback(); } } private void updateAmountDisplay() { String amount = currentAmount.toString(); if (amount.isEmpty() || amount.equals("0")) { editTextAmount.setText(""); } else { String formattedAmount = formatCurrency(amount); editTextAmount.setText(formattedAmount); } } private String formatCurrency(String amount) { if (TextUtils.isEmpty(amount) || amount.equals("0")) { return ""; } try { long number = Long.parseLong(amount); return String.format("%,d", number).replace(',', '.'); } catch (NumberFormatException e) { return amount; } } private void updateButtonState() { boolean hasValidAmount = currentAmount.length() > 0 && !currentAmount.toString().equals("0") && !currentAmount.toString().isEmpty(); confirmButton.setEnabled(hasValidAmount); if (hasValidAmount) { // Active state confirmButton.setBackgroundResource(R.drawable.button_active_background); confirmButton.setTextColor(Color.WHITE); confirmButton.setAlpha(1.0f); } else { // Inactive state confirmButton.setBackgroundResource(R.drawable.button_inactive_background); confirmButton.setTextColor(Color.parseColor("#999999")); confirmButton.setAlpha(0.6f); } } private void handleConfirmPayment() { String amount = currentAmount.toString(); if (TextUtils.isEmpty(amount) || amount.equals("0")) { showToast("Masukkan jumlah pembayaran"); return; } try { long amountValue = Long.parseLong(amount); // Validate minimum amount if (amountValue < 1000) { showToast("Minimal pembayaran Rp 1.000"); return; } // Validate maximum amount if (amountValue > 999999999L) { showToast("Maksimal pembayaran Rp 999.999.999"); return; } // Process payment processPayment(amountValue); } catch (NumberFormatException e) { showToast("Format jumlah tidak valid"); } } private void processPayment(long amount) { // Show loading state confirmButton.setText("Memproses..."); confirmButton.setEnabled(false); // Simulate payment processing animationHandler.postDelayed(() -> { // Show success message showToast("Pembayaran berhasil! Jumlah: Rp " + formatCurrency(String.valueOf(amount))); // Reset state and go back resetPaymentState(); navigateBack(); }, 2000); } private void resetPaymentState() { currentAmount = new StringBuilder(); updateAmountDisplay(); updateButtonState(); confirmButton.setText("Konfirmasi"); } // Animation methods (only for numpad interactions) private void addClickAnimation(View view) { ObjectAnimator scaleX = ObjectAnimator.ofFloat(view, "scaleX", 1f, 0.95f, 1f); ObjectAnimator scaleY = ObjectAnimator.ofFloat(view, "scaleY", 1f, 0.95f, 1f); AnimatorSet animatorSet = new AnimatorSet(); animatorSet.playTogether(scaleX, scaleY); animatorSet.setDuration(150); animatorSet.start(); } private void addButtonClickAnimation(View view) { ObjectAnimator scaleX = ObjectAnimator.ofFloat(view, "scaleX", 1f, 0.98f, 1f); ObjectAnimator scaleY = ObjectAnimator.ofFloat(view, "scaleY", 1f, 0.98f, 1f); AnimatorSet animatorSet = new AnimatorSet(); animatorSet.playTogether(scaleX, scaleY); animatorSet.setDuration(200); animatorSet.start(); } private void addInputFeedback() { ObjectAnimator fadeIn = ObjectAnimator.ofFloat(editTextAmount, "alpha", 0.7f, 1f); fadeIn.setDuration(200); fadeIn.start(); } private void addDeleteFeedback() { ObjectAnimator shake = ObjectAnimator.ofFloat(editTextAmount, "translationX", 0f, -10f, 10f, 0f); shake.setDuration(300); shake.start(); } // Utility methods private void showToast(String message) { Toast.makeText(this, message, Toast.LENGTH_SHORT).show(); } @Override public void onBackPressed() { navigateBack(); } @Override protected void onDestroy() { super.onDestroy(); if (animationHandler != null) { animationHandler.removeCallbacksAndMessages(null); } } // Public methods for testing public String getCurrentAmount() { return currentAmount.toString(); } public boolean isConfirmButtonEnabled() { return confirmButton.isEnabled(); } }