Implement HistoryActivity
This commit is contained in:
parent
3ac3598359
commit
597921e32b
@ -68,11 +68,11 @@
|
||||
android:exported="false" />
|
||||
|
||||
<activity
|
||||
android:name=".HistoryActivity"
|
||||
android:name=".histori.HistoryActivity"
|
||||
android:exported="false" />
|
||||
|
||||
<activity
|
||||
android:name=".HistoryDetailActivity"
|
||||
android:name=".histori.HistoryListActivity"
|
||||
android:exported="false" />
|
||||
|
||||
<activity
|
||||
|
@ -22,6 +22,8 @@ import com.google.android.material.button.MaterialButton;
|
||||
import com.example.bdkipoc.cetakulang.ReprintActivity;
|
||||
import com.example.bdkipoc.cetakulang.ReprintAdapterActivity;
|
||||
|
||||
import com.example.bdkipoc.histori.HistoryActivity;
|
||||
|
||||
import com.example.bdkipoc.R;
|
||||
import com.example.bdkipoc.transaction.CreateTransactionActivity;
|
||||
import com.example.bdkipoc.transaction.ResultTransactionActivity;
|
||||
|
@ -1,4 +1,4 @@
|
||||
package com.example.bdkipoc;
|
||||
package com.example.bdkipoc.histori;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.AsyncTask;
|
||||
@ -32,6 +32,8 @@ import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import com.example.bdkipoc.R;
|
||||
|
||||
public class HistoryActivity extends AppCompatActivity {
|
||||
|
||||
private TextView tvTotalAmount;
|
||||
@ -47,6 +49,7 @@ public class HistoryActivity extends AppCompatActivity {
|
||||
private static List<HistoryItem> fullHistoryData = new ArrayList<>();
|
||||
|
||||
private String API_URL;
|
||||
private String SUMMARY_API_URL;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
@ -57,17 +60,18 @@ public class HistoryActivity extends AppCompatActivity {
|
||||
setupRecyclerView();
|
||||
buildApiUrl();
|
||||
fetchApiData();
|
||||
fetchSummaryData(); // Add this line to fetch summary data
|
||||
setupClickListeners();
|
||||
}
|
||||
|
||||
private void buildApiUrl() {
|
||||
// Option 1: Get today's date (current implementation)
|
||||
// SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault());
|
||||
// String todayDate = dateFormat.format(new Date());
|
||||
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault());
|
||||
String todayDate = dateFormat.format(new Date());
|
||||
|
||||
// Option 2: Set specific date (uncomment and modify if needed)
|
||||
String specificDate = "2025-06-27"; // Format: yyyy-MM-dd
|
||||
String todayDate = specificDate;
|
||||
// String specificDate = "2025-06-27"; // Format: yyyy-MM-dd
|
||||
// String todayDate = specificDate;
|
||||
|
||||
// Option 3: Set date using Calendar for specific date
|
||||
// Calendar calendar = Calendar.getInstance();
|
||||
@ -77,6 +81,10 @@ public class HistoryActivity extends AppCompatActivity {
|
||||
// Build API URL with date as both from_date and to_date, and limit=10
|
||||
API_URL = "https://be-edc.msvc.app/transactions?page=0&limit=10&sortOrder=DESC&from_date="
|
||||
+ todayDate + "&to_date=" + todayDate + "&location_id=0&merchant_id=0&tid=&mid=&sortColumn=id";
|
||||
|
||||
// Build Summary API URL for getting total amount and transaction count
|
||||
SUMMARY_API_URL = "https://be-edc.msvc.app/transactions/list?from_date="
|
||||
+ todayDate + "&to_date=" + todayDate + "&location_id=0&merchant_id=0";
|
||||
}
|
||||
|
||||
private void initViews() {
|
||||
@ -108,7 +116,7 @@ public class HistoryActivity extends AppCompatActivity {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
try {
|
||||
Intent intent = new Intent(HistoryActivity.this, HistoryDetailActivity.class);
|
||||
Intent intent = new Intent(HistoryActivity.this, HistoryListActivity.class);
|
||||
startActivity(intent);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
@ -125,14 +133,15 @@ public class HistoryActivity extends AppCompatActivity {
|
||||
new ApiTask().execute(API_URL);
|
||||
}
|
||||
|
||||
private void fetchSummaryData() {
|
||||
new SummaryApiTask().execute(SUMMARY_API_URL);
|
||||
}
|
||||
|
||||
private void processApiData(JSONArray dataArray) {
|
||||
try {
|
||||
historyList.clear();
|
||||
fullHistoryData.clear(); // Clear static data
|
||||
|
||||
final long[] totalAmountArray = {0};
|
||||
final int[] totalTransactionsArray = {0};
|
||||
|
||||
for (int i = 0; i < dataArray.length(); i++) {
|
||||
JSONObject item = dataArray.getJSONObject(i);
|
||||
|
||||
@ -164,15 +173,11 @@ public class HistoryActivity extends AppCompatActivity {
|
||||
// Add to both lists (since we're limiting to 10 in API call)
|
||||
historyList.add(historyItem);
|
||||
fullHistoryData.add(historyItem);
|
||||
|
||||
totalAmountArray[0] += (long) amountValue;
|
||||
totalTransactionsArray[0]++;
|
||||
}
|
||||
|
||||
runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
updateSummary(totalAmountArray[0], totalTransactionsArray[0]);
|
||||
adapter.notifyDataSetChanged();
|
||||
}
|
||||
});
|
||||
@ -189,6 +194,51 @@ public class HistoryActivity extends AppCompatActivity {
|
||||
}
|
||||
}
|
||||
|
||||
private void processSummaryData(JSONArray dataArray) {
|
||||
try {
|
||||
long totalAmount = 0;
|
||||
int totalTransactions = 0;
|
||||
|
||||
for (int i = 0; i < dataArray.length(); i++) {
|
||||
JSONObject item = dataArray.getJSONObject(i);
|
||||
|
||||
String amount = item.getString("amount");
|
||||
|
||||
// Parse amount safely
|
||||
double amountValue = 0;
|
||||
try {
|
||||
amountValue = Double.parseDouble(amount);
|
||||
} catch (NumberFormatException e) {
|
||||
amountValue = 0;
|
||||
}
|
||||
|
||||
totalAmount += (long) amountValue;
|
||||
totalTransactions++;
|
||||
}
|
||||
|
||||
final long finalTotalAmount = totalAmount;
|
||||
final int finalTotalTransactions = totalTransactions;
|
||||
|
||||
runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
updateSummary(finalTotalAmount, finalTotalTransactions);
|
||||
}
|
||||
});
|
||||
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Toast.makeText(HistoryActivity.this, "Error parsing summary data", Toast.LENGTH_SHORT).show();
|
||||
// Set default values if summary fails
|
||||
updateSummary(0, 0);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void updateSummary(long totalAmount, int totalTransactions) {
|
||||
tvTotalAmount.setText("RP " + formatCurrency(totalAmount));
|
||||
tvTotalTransactions.setText(String.valueOf(totalTransactions));
|
||||
@ -234,12 +284,16 @@ public class HistoryActivity extends AppCompatActivity {
|
||||
|
||||
private String formatChannelName(String channelCode) {
|
||||
switch (channelCode) {
|
||||
case "DEBIT":
|
||||
case "DEBIT_CARD":
|
||||
return "Debit";
|
||||
case "CREDIT_CARD":
|
||||
return "Kredit";
|
||||
case "QRIS":
|
||||
return "QRIS";
|
||||
case "E_MONEY":
|
||||
return "E-Money";
|
||||
case "OTHER":
|
||||
return "Kredit";
|
||||
return "Lainnya";
|
||||
default:
|
||||
return channelCode.substring(0, 1).toUpperCase() +
|
||||
channelCode.substring(1).toLowerCase();
|
||||
@ -280,7 +334,7 @@ public class HistoryActivity extends AppCompatActivity {
|
||||
return new ArrayList<>(fullHistoryData);
|
||||
}
|
||||
|
||||
// AsyncTask for API call
|
||||
// AsyncTask for main API call (transaction list with limit)
|
||||
private class ApiTask extends AsyncTask<String, Void, String> {
|
||||
@Override
|
||||
protected String doInBackground(String... urls) {
|
||||
@ -333,6 +387,59 @@ public class HistoryActivity extends AppCompatActivity {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// AsyncTask for summary API call (all transactions for totals)
|
||||
private class SummaryApiTask extends AsyncTask<String, Void, String> {
|
||||
@Override
|
||||
protected String doInBackground(String... urls) {
|
||||
try {
|
||||
URL url = new URL(urls[0]);
|
||||
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
||||
connection.setRequestMethod("GET");
|
||||
connection.setConnectTimeout(10000);
|
||||
connection.setReadTimeout(10000);
|
||||
|
||||
int responseCode = connection.getResponseCode();
|
||||
if (responseCode == HttpURLConnection.HTTP_OK) {
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
|
||||
StringBuilder response = new StringBuilder();
|
||||
String line;
|
||||
|
||||
while ((line = reader.readLine()) != null) {
|
||||
response.append(line);
|
||||
}
|
||||
reader.close();
|
||||
return response.toString();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(String result) {
|
||||
if (result != null) {
|
||||
try {
|
||||
JSONObject jsonResponse = new JSONObject(result);
|
||||
if (jsonResponse.getInt("status") == 200) {
|
||||
JSONArray dataArray = jsonResponse.getJSONArray("data");
|
||||
processSummaryData(dataArray);
|
||||
} else {
|
||||
Toast.makeText(HistoryActivity.this, "Summary API Error", Toast.LENGTH_SHORT).show();
|
||||
updateSummary(0, 0);
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
Toast.makeText(HistoryActivity.this, "Summary JSON Parse Error", Toast.LENGTH_SHORT).show();
|
||||
updateSummary(0, 0);
|
||||
}
|
||||
} else {
|
||||
Toast.makeText(HistoryActivity.this, "Summary Network Error", Toast.LENGTH_SHORT).show();
|
||||
updateSummary(0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// HistoryItem class - enhanced with more fields
|
||||
|
@ -1,204 +0,0 @@
|
||||
package com.example.bdkipoc;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import java.text.NumberFormat;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
public class HistoryDetailActivity extends AppCompatActivity {
|
||||
|
||||
private RecyclerView recyclerView;
|
||||
private HistoryDetailAdapter adapter;
|
||||
private List<HistoryItem> detailList;
|
||||
private ImageView btnBack;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_history_detail);
|
||||
|
||||
initViews();
|
||||
setupRecyclerView();
|
||||
loadData();
|
||||
setupClickListeners();
|
||||
}
|
||||
|
||||
private void initViews() {
|
||||
recyclerView = findViewById(R.id.recycler_view);
|
||||
btnBack = findViewById(R.id.btn_back);
|
||||
detailList = new ArrayList<>();
|
||||
}
|
||||
|
||||
private void setupRecyclerView() {
|
||||
adapter = new HistoryDetailAdapter(detailList);
|
||||
recyclerView.setLayoutManager(new LinearLayoutManager(this));
|
||||
recyclerView.setAdapter(adapter);
|
||||
}
|
||||
|
||||
private void setupClickListeners() {
|
||||
btnBack.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
finish();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void loadData() {
|
||||
try {
|
||||
// Get data from HistoryActivity
|
||||
List<HistoryItem> fullData = HistoryActivity.getFullHistoryData();
|
||||
|
||||
if (fullData != null && !fullData.isEmpty()) {
|
||||
detailList.clear();
|
||||
detailList.addAll(fullData);
|
||||
adapter.notifyDataSetChanged();
|
||||
} else {
|
||||
loadSampleDetailData();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
loadSampleDetailData();
|
||||
}
|
||||
}
|
||||
|
||||
private void loadSampleDetailData() {
|
||||
detailList.clear();
|
||||
|
||||
// Create sample detail data
|
||||
HistoryItem[] sampleData = {
|
||||
new HistoryItem("03:44", "11-05-2025", 2018619, "Kredit", "FAILED", "197870"),
|
||||
new HistoryItem("03:10", "12-05-2025", 3974866, "QRIS", "SUCCESS", "053059"),
|
||||
new HistoryItem("15:17", "13-05-2025", 2418167, "QRIS", "FAILED", "668320"),
|
||||
new HistoryItem("12:09", "11-05-2025", 3429230, "Debit", "FAILED", "454790"),
|
||||
new HistoryItem("08:39", "10-05-2025", 4656447, "QRIS", "FAILED", "454248"),
|
||||
new HistoryItem("00:35", "12-05-2025", 3507704, "QRIS", "FAILED", "301644"),
|
||||
new HistoryItem("22:43", "13-05-2025", 4277904, "Debit", "SUCCESS", "388709"),
|
||||
new HistoryItem("18:16", "11-05-2025", 4456904, "Debit", "FAILED", "986861"),
|
||||
new HistoryItem("12:51", "10-05-2025", 3027953, "Kredit", "SUCCESS", "771339"),
|
||||
new HistoryItem("19:50", "14-05-2025", 4399035, "QRIS", "FAILED", "103478")
|
||||
};
|
||||
|
||||
for (HistoryItem item : sampleData) {
|
||||
detailList.add(item);
|
||||
}
|
||||
|
||||
adapter.notifyDataSetChanged();
|
||||
}
|
||||
}
|
||||
|
||||
// HistoryDetailAdapter class - simplified for stability
|
||||
class HistoryDetailAdapter extends RecyclerView.Adapter<HistoryDetailAdapter.DetailViewHolder> {
|
||||
|
||||
private List<HistoryItem> detailList;
|
||||
|
||||
public HistoryDetailAdapter(List<HistoryItem> detailList) {
|
||||
this.detailList = detailList;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public DetailViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
View view = LayoutInflater.from(parent.getContext())
|
||||
.inflate(R.layout.item_history_detail, parent, false);
|
||||
return new DetailViewHolder(view);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull DetailViewHolder holder, int position) {
|
||||
HistoryItem item = detailList.get(position);
|
||||
|
||||
try {
|
||||
holder.tvReferenceId.setText("Ref: " + item.getReferenceId());
|
||||
holder.tvAmount.setText("Rp. " + formatCurrency(item.getAmount()));
|
||||
holder.tvChannel.setText(item.getChannelName());
|
||||
holder.tvMerchant.setText("TEST MERCHANT");
|
||||
holder.tvTime.setText(formatDateTime(item.getTime(), item.getDate()));
|
||||
holder.tvIssuer.setText("BANK MANDIRI");
|
||||
|
||||
// Set status color
|
||||
String status = item.getStatus();
|
||||
if ("SUCCESS".equals(status)) {
|
||||
holder.tvStatus.setText("Berhasil");
|
||||
holder.tvStatus.setTextColor(0xFF4CAF50); // Green
|
||||
} else if ("FAILED".equals(status)) {
|
||||
holder.tvStatus.setText("Gagal");
|
||||
holder.tvStatus.setTextColor(0xFFF44336); // Red
|
||||
} else {
|
||||
holder.tvStatus.setText("Tertunda");
|
||||
holder.tvStatus.setTextColor(0xFFFF9800); // Orange
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
// Set default values if error occurs
|
||||
holder.tvReferenceId.setText("Ref: " + position);
|
||||
holder.tvAmount.setText("Rp. 0");
|
||||
holder.tvChannel.setText("Unknown");
|
||||
holder.tvMerchant.setText("TEST MERCHANT");
|
||||
holder.tvTime.setText("00:00, 01-01-2025");
|
||||
holder.tvIssuer.setText("UNKNOWN");
|
||||
holder.tvStatus.setText("Tidak Diketahui");
|
||||
holder.tvStatus.setTextColor(0xFF666666);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return detailList != null ? detailList.size() : 0;
|
||||
}
|
||||
|
||||
private String formatCurrency(long amount) {
|
||||
try {
|
||||
NumberFormat formatter = NumberFormat.getNumberInstance(new Locale("id", "ID"));
|
||||
return formatter.format(amount);
|
||||
} catch (Exception e) {
|
||||
return String.valueOf(amount);
|
||||
}
|
||||
}
|
||||
|
||||
private String formatDateTime(String time, String date) {
|
||||
try {
|
||||
return time + ", " + date;
|
||||
} catch (Exception e) {
|
||||
return "00:00, 01-01-2025";
|
||||
}
|
||||
}
|
||||
|
||||
static class DetailViewHolder extends RecyclerView.ViewHolder {
|
||||
TextView tvReferenceId;
|
||||
TextView tvAmount;
|
||||
TextView tvChannel;
|
||||
TextView tvMerchant;
|
||||
TextView tvTime;
|
||||
TextView tvIssuer;
|
||||
TextView tvStatus;
|
||||
|
||||
public DetailViewHolder(@NonNull View itemView) {
|
||||
super(itemView);
|
||||
try {
|
||||
tvReferenceId = itemView.findViewById(R.id.tv_reference_id);
|
||||
tvAmount = itemView.findViewById(R.id.tv_amount);
|
||||
tvChannel = itemView.findViewById(R.id.tv_channel);
|
||||
tvMerchant = itemView.findViewById(R.id.tv_merchant);
|
||||
tvTime = itemView.findViewById(R.id.tv_time);
|
||||
tvIssuer = itemView.findViewById(R.id.tv_issuer);
|
||||
tvStatus = itemView.findViewById(R.id.tv_status);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,337 @@
|
||||
package com.example.bdkipoc.histori;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.graphics.Color;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.example.bdkipoc.R;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
public class HistoryListActivity extends AppCompatActivity {
|
||||
|
||||
private RecyclerView rvHistory;
|
||||
private TextView tvEmpty;
|
||||
private HistoryListAdapter adapter;
|
||||
private List<Transaction> transactionList = new ArrayList<>();
|
||||
private String API_URL;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_history_list);
|
||||
|
||||
// Initialize views
|
||||
rvHistory = findViewById(R.id.rv_history);
|
||||
tvEmpty = findViewById(R.id.tv_empty);
|
||||
|
||||
// Set up RecyclerView
|
||||
adapter = new HistoryListAdapter(transactionList);
|
||||
rvHistory.setLayoutManager(new LinearLayoutManager(this));
|
||||
rvHistory.setAdapter(adapter);
|
||||
|
||||
// Set up app bar
|
||||
setupAppBar();
|
||||
|
||||
// Build API URL and load data
|
||||
buildApiUrl();
|
||||
fetchTransactionData();
|
||||
}
|
||||
|
||||
private void buildApiUrl() {
|
||||
// Get current date in yyyy-MM-dd format
|
||||
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault());
|
||||
String currentDate = dateFormat.format(new Date());
|
||||
|
||||
// Option 2: Set specific date (uncomment and modify if needed)
|
||||
// String specificDate = "2025-06-27"; // Format: yyyy-MM-dd
|
||||
// String currentDate = specificDate;
|
||||
|
||||
// Build API URL with current date as both from_date and to_date
|
||||
API_URL = "https://be-edc.msvc.app/transactions/list?from_date=" + currentDate +
|
||||
"&to_date=" + currentDate + "&location_id=0&merchant_id=0";
|
||||
}
|
||||
|
||||
private void setupAppBar() {
|
||||
LinearLayout backNavigation = findViewById(R.id.back_navigation);
|
||||
TextView appbarTitle = findViewById(R.id.appbarTitle);
|
||||
|
||||
appbarTitle.setText("Kembali");
|
||||
|
||||
backNavigation.setOnClickListener(v -> onBackPressed());
|
||||
}
|
||||
|
||||
private void fetchTransactionData() {
|
||||
new FetchTransactionsTask().execute(API_URL);
|
||||
}
|
||||
|
||||
private void updateTransactionList(List<Transaction> transactions) {
|
||||
transactionList.clear();
|
||||
if (transactions != null && !transactions.isEmpty()) {
|
||||
transactionList.addAll(transactions);
|
||||
tvEmpty.setVisibility(View.GONE);
|
||||
rvHistory.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
tvEmpty.setVisibility(View.VISIBLE);
|
||||
rvHistory.setVisibility(View.GONE);
|
||||
}
|
||||
adapter.notifyDataSetChanged();
|
||||
}
|
||||
|
||||
// AsyncTask to fetch transactions from API
|
||||
private class FetchTransactionsTask extends AsyncTask<String, Void, String> {
|
||||
@Override
|
||||
protected String doInBackground(String... urls) {
|
||||
try {
|
||||
URL url = new URL(urls[0]);
|
||||
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
||||
connection.setRequestMethod("GET");
|
||||
connection.setConnectTimeout(10000);
|
||||
connection.setReadTimeout(10000);
|
||||
|
||||
int responseCode = connection.getResponseCode();
|
||||
if (responseCode == HttpURLConnection.HTTP_OK) {
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
|
||||
StringBuilder response = new StringBuilder();
|
||||
String line;
|
||||
|
||||
while ((line = reader.readLine()) != null) {
|
||||
response.append(line);
|
||||
}
|
||||
reader.close();
|
||||
return response.toString();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(String result) {
|
||||
if (result != null) {
|
||||
try {
|
||||
JSONObject jsonResponse = new JSONObject(result);
|
||||
if (jsonResponse.getInt("status") == 200) {
|
||||
JSONArray dataArray = jsonResponse.getJSONArray("data");
|
||||
List<Transaction> transactions = parseTransactions(dataArray);
|
||||
updateTransactionList(transactions);
|
||||
} else {
|
||||
showError("API Error: " + jsonResponse.getString("message"));
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
showError("Error parsing data");
|
||||
}
|
||||
} else {
|
||||
showError("Network error");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private List<Transaction> parseTransactions(JSONArray dataArray) throws JSONException {
|
||||
List<Transaction> transactions = new ArrayList<>();
|
||||
for (int i = 0; i < dataArray.length(); i++) {
|
||||
JSONObject item = dataArray.getJSONObject(i);
|
||||
try {
|
||||
Transaction transaction = new Transaction(
|
||||
item.getString("transaction_date"),
|
||||
item.getString("amount"),
|
||||
item.getString("channel_code"),
|
||||
item.getString("status")
|
||||
);
|
||||
transactions.add(transaction);
|
||||
} catch (ParseException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
// Urutkan dari terbaru ke terlama
|
||||
transactions.sort((t1, t2) -> {
|
||||
try {
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.getDefault());
|
||||
Date d1 = sdf.parse(t1.getDateTime());
|
||||
Date d2 = sdf.parse(t2.getDateTime());
|
||||
return d2.compareTo(d1); // terbaru di atas
|
||||
} catch (ParseException e) {
|
||||
e.printStackTrace();
|
||||
return 0;
|
||||
}
|
||||
});
|
||||
|
||||
return transactions;
|
||||
}
|
||||
|
||||
private void showError(String message) {
|
||||
Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
|
||||
tvEmpty.setVisibility(View.VISIBLE);
|
||||
rvHistory.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
// Transaction model class
|
||||
public static class Transaction {
|
||||
private final String dateTime;
|
||||
private final String amount;
|
||||
private final String channel;
|
||||
private final String status;
|
||||
|
||||
public Transaction(String dateTime, String amount, String channel, String status) throws ParseException {
|
||||
this.dateTime = dateTime;
|
||||
this.amount = amount;
|
||||
this.channel = channel;
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public String getDateTime() {
|
||||
return dateTime;
|
||||
}
|
||||
|
||||
public String getAmount() {
|
||||
return amount;
|
||||
}
|
||||
|
||||
public String getChannel() {
|
||||
return channel;
|
||||
}
|
||||
|
||||
public String getStatus() {
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
// Adapter class
|
||||
public class HistoryListAdapter extends RecyclerView.Adapter<HistoryListAdapter.ViewHolder> {
|
||||
|
||||
private final List<Transaction> transactions;
|
||||
|
||||
public HistoryListAdapter(List<Transaction> transactions) {
|
||||
this.transactions = transactions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||
View view = LayoutInflater.from(parent.getContext())
|
||||
.inflate(R.layout.item_history_list, parent, false);
|
||||
return new ViewHolder(view);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(ViewHolder holder, int position) {
|
||||
Transaction transaction = transactions.get(position);
|
||||
|
||||
// Format date
|
||||
SimpleDateFormat inputFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.getDefault());
|
||||
SimpleDateFormat outputFormat = new SimpleDateFormat("HH:mm, dd MMM yyyy", Locale.getDefault());
|
||||
try {
|
||||
Date date = inputFormat.parse(transaction.getDateTime());
|
||||
holder.tvTime.setText(outputFormat.format(date));
|
||||
} catch (ParseException e) {
|
||||
holder.tvTime.setText(transaction.getDateTime());
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
// Format amount
|
||||
holder.tvAmount.setText(String.format(Locale.getDefault(), "Rp. %s", transaction.getAmount()));
|
||||
|
||||
// Set channel and status
|
||||
holder.tvChannel.setText(formatChannelName(transaction.getChannel()));
|
||||
holder.tvStatus.setText(formatStatusText(transaction.getStatus()));
|
||||
|
||||
// Set status color
|
||||
int statusColor = Color.parseColor("#000000"); // default black
|
||||
if ("SUCCESS".equalsIgnoreCase(transaction.getStatus())) {
|
||||
statusColor = Color.parseColor("#4CAF50"); // green
|
||||
} else if ("FAILED".equalsIgnoreCase(transaction.getStatus())) {
|
||||
statusColor = Color.parseColor("#F44336"); // red
|
||||
} else if ("INIT".equalsIgnoreCase(transaction.getStatus())) {
|
||||
statusColor = Color.parseColor("#FF9800"); // orange
|
||||
}
|
||||
holder.tvStatus.setTextColor(statusColor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return transactions.size();
|
||||
}
|
||||
|
||||
private String formatChannelName(String channelCode) {
|
||||
switch (channelCode) {
|
||||
case "E_MONEY":
|
||||
return "E-Money";
|
||||
case "QRIS":
|
||||
return "QRIS";
|
||||
case "CREDIT_CARD":
|
||||
return "Kredit";
|
||||
case "DEBIT_CARD":
|
||||
return "Debit";
|
||||
default:
|
||||
return channelCode;
|
||||
}
|
||||
}
|
||||
|
||||
private String formatStatusText(String status) {
|
||||
switch (status) {
|
||||
case "SUCCESS":
|
||||
return "Berhasil";
|
||||
case "FAILED":
|
||||
return "Gagal";
|
||||
case "INIT":
|
||||
return "Tertunda";
|
||||
default:
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
public class ViewHolder extends RecyclerView.ViewHolder {
|
||||
public final TextView tvTime;
|
||||
public final TextView tvAmount;
|
||||
public final TextView tvChannel;
|
||||
public final TextView tvStatus;
|
||||
|
||||
public ViewHolder(View view) {
|
||||
super(view);
|
||||
tvTime = view.findViewById(R.id.tv_time);
|
||||
tvAmount = view.findViewById(R.id.tv_amount);
|
||||
tvChannel = view.findViewById(R.id.tv_channel);
|
||||
tvStatus = view.findViewById(R.id.tv_status);
|
||||
|
||||
// Set click listener if needed
|
||||
view.setOnClickListener(v -> {
|
||||
int position = getAdapterPosition();
|
||||
if (position != RecyclerView.NO_POSITION) {
|
||||
Transaction transaction = transactions.get(position);
|
||||
// TODO: Handle item click, maybe open detail activity
|
||||
// Intent intent = new Intent(HistoryListActivity.this, HistoryDetailActivity.class);
|
||||
// Pass transaction data to detail activity
|
||||
// startActivity(intent);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -18,7 +18,7 @@
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginTop="-70dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginBottom="11dp"
|
||||
android:layout_marginBottom="5dp"
|
||||
app:cardCornerRadius="16dp"
|
||||
app:cardElevation="6dp">
|
||||
|
||||
|
@ -1,46 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="#F5F5F5"
|
||||
android:orientation="vertical">
|
||||
|
||||
<!-- Header -->
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="56dp"
|
||||
android:background="#E53E3E"
|
||||
android:padding="16dp">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/btn_back"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:background="?attr/selectableItemBackgroundBorderless"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:src="@android:drawable/ic_menu_revert"
|
||||
app:tint="@android:color/white" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerInParent="true"
|
||||
android:text="Detail Transaksi"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="18sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
<!-- Content -->
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/recycler_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:padding="16dp" />
|
||||
|
||||
</LinearLayout>
|
56
app/src/main/res/layout/activity_history_list.xml
Normal file
56
app/src/main/res/layout/activity_history_list.xml
Normal file
@ -0,0 +1,56 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:padding="0dp">
|
||||
|
||||
<!-- App Bar -->
|
||||
<include layout="@layout/component_appbar_small" />
|
||||
|
||||
<!-- Title: Transaksi Terbaru -->
|
||||
<TextView
|
||||
android:id="@+id/tv_title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Transaksi Terbaru"
|
||||
android:textSize="18sp"
|
||||
android:textStyle="bold"
|
||||
android:paddingStart="16dp"
|
||||
android:paddingEnd="16dp"
|
||||
android:paddingTop="8dp"
|
||||
android:paddingBottom="4dp"
|
||||
android:textColor="#000000"
|
||||
android:fontFamily="@font/inter" />
|
||||
|
||||
<!-- Konten List & Empty View ditumpuk -->
|
||||
<FrameLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1">
|
||||
|
||||
<!-- RecyclerView: Daftar Transaksi -->
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/rv_history"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:clipToPadding="false"
|
||||
android:paddingHorizontal="16dp"
|
||||
android:paddingBottom="8dp"
|
||||
android:scrollbars="vertical" />
|
||||
|
||||
<!-- Teks Jika Tidak Ada Data -->
|
||||
<TextView
|
||||
android:id="@+id/tv_empty"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center"
|
||||
android:text="Tidak ada transaksi"
|
||||
android:visibility="gone"
|
||||
android:textColor="#999999"
|
||||
android:textSize="14sp"
|
||||
android:fontFamily="@font/inter"/>
|
||||
</FrameLayout>
|
||||
|
||||
</LinearLayout>
|
47
app/src/main/res/layout/component_appbar_small.xml
Normal file
47
app/src/main/res/layout/component_appbar_small.xml
Normal file
@ -0,0 +1,47 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout 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="50dp"
|
||||
android:background="#DE0701"
|
||||
android:fitsSystemWindows="true">
|
||||
|
||||
<!-- Back Navigation -->
|
||||
<LinearLayout
|
||||
android:id="@+id/back_navigation"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginTop="16dp"
|
||||
android:background="?attr/selectableItemBackgroundBorderless"
|
||||
android:padding="4dp"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<!-- Back Arrow -->
|
||||
<ImageView
|
||||
android:id="@+id/backArrow"
|
||||
android:layout_width="16dp"
|
||||
android:layout_height="16dp"
|
||||
android:src="@drawable/ic_arrow_back"
|
||||
android:contentDescription="Back"
|
||||
app:tint="@android:color/white" />
|
||||
|
||||
<!-- Title Text -->
|
||||
<TextView
|
||||
android:id="@+id/appbarTitle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="2dp"
|
||||
android:text="Kembali"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="10sp"
|
||||
android:fontFamily="@font/inter"
|
||||
android:textStyle="normal" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
@ -1,178 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="8dp"
|
||||
app:cardCornerRadius="8dp"
|
||||
app:cardElevation="2dp">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:padding="16dp">
|
||||
|
||||
<!-- Header Row -->
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_reference_id"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="Ref: 197870"
|
||||
android:textColor="#333333"
|
||||
android:textSize="14sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_status"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="SUCCESS"
|
||||
android:textColor="#4CAF50"
|
||||
android:textSize="12sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<!-- Amount -->
|
||||
<TextView
|
||||
android:id="@+id/tv_amount"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:text="Rp. 2.018.619"
|
||||
android:textColor="#333333"
|
||||
android:textSize="18sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<!-- Details Grid -->
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="12dp"
|
||||
android:orientation="vertical">
|
||||
|
||||
<!-- Row 1 -->
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Channel"
|
||||
android:textColor="#666666"
|
||||
android:textSize="12sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_channel"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Other Payment"
|
||||
android:textColor="#333333"
|
||||
android:textSize="14sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Waktu"
|
||||
android:textColor="#666666"
|
||||
android:textSize="12sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_time"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="16/05/2025 05:40"
|
||||
android:textColor="#333333"
|
||||
android:textSize="14sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<!-- Row 2 -->
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Merchant"
|
||||
android:textColor="#666666"
|
||||
android:textSize="12sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_merchant"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="TEST MERCHANT"
|
||||
android:textColor="#333333"
|
||||
android:textSize="14sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Issuer"
|
||||
android:textColor="#666666"
|
||||
android:textSize="12sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_issuer"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="BANK MANDIRI"
|
||||
android:textColor="#333333"
|
||||
android:textSize="14sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.cardview.widget.CardView>
|
69
app/src/main/res/layout/item_history_list.xml
Normal file
69
app/src/main/res/layout/item_history_list.xml
Normal file
@ -0,0 +1,69 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:background="@android:color/white">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:paddingHorizontal="16dp"
|
||||
android:paddingVertical="12dp"
|
||||
android:gravity="center_vertical">
|
||||
|
||||
<!-- Waktu -->
|
||||
<TextView
|
||||
android:id="@+id/tv_time"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="2"
|
||||
android:text="09.00, 07-05-2025"
|
||||
android:textColor="#000000"
|
||||
android:fontFamily="@font/inter"
|
||||
android:textSize="13sp" />
|
||||
|
||||
<!-- Nominal -->
|
||||
<TextView
|
||||
android:id="@+id/tv_amount"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="2"
|
||||
android:text="Rp. 78.000"
|
||||
android:textColor="#000000"
|
||||
android:gravity="center"
|
||||
android:fontFamily="@font/inter"
|
||||
android:textSize="13sp" />
|
||||
|
||||
<!-- Channel / Tipe -->
|
||||
<TextView
|
||||
android:id="@+id/tv_channel"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1.5"
|
||||
android:text="Kredit"
|
||||
android:textColor="#000000"
|
||||
android:gravity="center"
|
||||
android:fontFamily="@font/inter"
|
||||
android:textSize="13sp" />
|
||||
|
||||
<!-- Status -->
|
||||
<TextView
|
||||
android:id="@+id/tv_status"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1.5"
|
||||
android:text="Berhasil"
|
||||
android:textColor="#009966"
|
||||
android:gravity="end"
|
||||
android:fontFamily="@font/inter"
|
||||
android:textSize="13sp" />
|
||||
</LinearLayout>
|
||||
|
||||
<!-- Garis Bawah -->
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:background="#DDDDDD" />
|
||||
</LinearLayout>
|
Loading…
x
Reference in New Issue
Block a user