From 0b96f4968cd5c0b36474b94b94ec6dcf6699f60c Mon Sep 17 00:00:00 2001 From: Damyan Ivanov Date: Wed, 21 Apr 2021 22:22:20 +0300 Subject: [PATCH] rework transaction list with proper view holders and no background load all the data is already available in the transaction list loaded from the database (asynchronously) also, fix a glitch where a visible item's matching account row is not coloured when the list is filtered by account name (because the underlying item is the same) --- .../async/TransactionAccumulator.java | 6 +- .../model/TransactionListItem.java | 26 +- .../net/ktnx/mobileledger/ui/MainModel.java | 16 -- .../TransactionListAdapter.java | 237 +++--------------- .../TransactionListDelimiterRowHolder.java | 61 +++++ .../TransactionListFragment.java | 2 +- .../TransactionListLastUpdateRowHolder.java | 35 +++ .../TransactionLoaderStep.java | 77 ------ .../TransactionRowHolder.java | 131 ++++++---- .../TransactionRowHolderBase.java | 38 +++ .../main/res/layout/transaction_delimiter.xml | 65 +++++ .../main/res/layout/transaction_list_row.xml | 50 +--- 12 files changed, 346 insertions(+), 398 deletions(-) create mode 100644 app/src/main/java/net/ktnx/mobileledger/ui/transaction_list/TransactionListDelimiterRowHolder.java create mode 100644 app/src/main/java/net/ktnx/mobileledger/ui/transaction_list/TransactionListLastUpdateRowHolder.java delete mode 100644 app/src/main/java/net/ktnx/mobileledger/ui/transaction_list/TransactionLoaderStep.java create mode 100644 app/src/main/java/net/ktnx/mobileledger/ui/transaction_list/TransactionRowHolderBase.java create mode 100644 app/src/main/res/layout/transaction_delimiter.xml diff --git a/app/src/main/java/net/ktnx/mobileledger/async/TransactionAccumulator.java b/app/src/main/java/net/ktnx/mobileledger/async/TransactionAccumulator.java index eb8376f0..46b8426a 100644 --- a/app/src/main/java/net/ktnx/mobileledger/async/TransactionAccumulator.java +++ b/app/src/main/java/net/ktnx/mobileledger/async/TransactionAccumulator.java @@ -27,12 +27,16 @@ import java.util.ArrayList; public class TransactionAccumulator { private final ArrayList list = new ArrayList<>(); private final MainModel model; + private final String boldAccountName; private SimpleDate earliestDate, latestDate; private SimpleDate lastDate; private boolean done; public TransactionAccumulator(MainModel model) { this.model = model; + boldAccountName = model.getAccountFilter() + .getValue(); + list.add(new TransactionListItem()); // head item } public void put(LedgerTransaction transaction) { @@ -54,7 +58,7 @@ public class TransactionAccumulator { list.add(new TransactionListItem(date, showMonth)); } - list.add(new TransactionListItem(transaction)); + list.add(new TransactionListItem(transaction, boldAccountName)); lastDate = date; } diff --git a/app/src/main/java/net/ktnx/mobileledger/model/TransactionListItem.java b/app/src/main/java/net/ktnx/mobileledger/model/TransactionListItem.java index 1e62ff13..550a84c5 100644 --- a/app/src/main/java/net/ktnx/mobileledger/model/TransactionListItem.java +++ b/app/src/main/java/net/ktnx/mobileledger/model/TransactionListItem.java @@ -1,5 +1,5 @@ /* - * Copyright © 2020 Damyan Ivanov. + * Copyright © 2021 Damyan Ivanov. * This file is part of MoLe. * MoLe is free software: you can distribute it and/or modify it * under the term of the GNU General Public License as published by @@ -18,6 +18,7 @@ package net.ktnx.mobileledger.model; import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import net.ktnx.mobileledger.App; import net.ktnx.mobileledger.utils.SimpleDate; @@ -29,14 +30,17 @@ public class TransactionListItem { private SimpleDate date; private boolean monthShown; private LedgerTransaction transaction; + private String boldAccountName; public TransactionListItem(@NotNull SimpleDate date, boolean monthShown) { this.type = Type.DELIMITER; this.date = date; this.monthShown = monthShown; } - public TransactionListItem(@NotNull LedgerTransaction transaction) { + public TransactionListItem(@NotNull LedgerTransaction transaction, + @Nullable String boldAccountName) { this.type = Type.TRANSACTION; this.transaction = transaction; + this.boldAccountName = boldAccountName; } public TransactionListItem() { this.type = Type.HEADER; @@ -64,5 +68,21 @@ public class TransactionListItem { String.format("Item type is not %s, but %s", Type.TRANSACTION, type)); return transaction; } - public enum Type {TRANSACTION, DELIMITER, HEADER} + public @Nullable + String getBoldAccountName() { + return boldAccountName; + } + public enum Type { + TRANSACTION, DELIMITER, HEADER; + public static Type valueOf(int i) { + if (i == TRANSACTION.ordinal()) + return TRANSACTION; + else if (i == DELIMITER.ordinal()) + return DELIMITER; + else if (i == HEADER.ordinal()) + return HEADER; + else + throw new IllegalStateException("Unexpected value: " + i); + } + } } diff --git a/app/src/main/java/net/ktnx/mobileledger/ui/MainModel.java b/app/src/main/java/net/ktnx/mobileledger/ui/MainModel.java index 06f94ee3..039e24df 100644 --- a/app/src/main/java/net/ktnx/mobileledger/ui/MainModel.java +++ b/app/src/main/java/net/ktnx/mobileledger/ui/MainModel.java @@ -18,7 +18,6 @@ package net.ktnx.mobileledger.ui; import android.os.AsyncTask; -import android.text.TextUtils; import androidx.lifecycle.LiveData; import androidx.lifecycle.MutableLiveData; @@ -83,21 +82,6 @@ public class MainModel extends ViewModel { public void setLastTransactionDate(SimpleDate latestDate) { this.lastTransactionDate = latestDate; } - private void applyTransactionFilter(List list) { - final String accFilter = accountFilter.getValue(); - ArrayList newList = new ArrayList<>(); - - TransactionAccumulator accumulator = new TransactionAccumulator(this); - if (TextUtils.isEmpty(accFilter)) - for (LedgerTransaction tr : list) - newList.add(new TransactionListItem(tr)); - else - for (LedgerTransaction tr : list) - if (tr.hasAccountNamedLike(accFilter)) - newList.add(new TransactionListItem(tr)); - - displayedTransactions.postValue(newList); - } public synchronized void scheduleTransactionListRetrieval() { if (retrieveTransactionsTask != null) { Logger.debug("db", "Ignoring request for transaction retrieval - already active"); diff --git a/app/src/main/java/net/ktnx/mobileledger/ui/transaction_list/TransactionListAdapter.java b/app/src/main/java/net/ktnx/mobileledger/ui/transaction_list/TransactionListAdapter.java index 67a4922b..599a9f8c 100644 --- a/app/src/main/java/net/ktnx/mobileledger/ui/transaction_list/TransactionListAdapter.java +++ b/app/src/main/java/net/ktnx/mobileledger/ui/transaction_list/TransactionListAdapter.java @@ -17,51 +17,29 @@ package net.ktnx.mobileledger.ui.transaction_list; -import android.app.Activity; -import android.content.Context; -import android.database.sqlite.SQLiteDatabase; -import android.graphics.Typeface; -import android.os.AsyncTask; -import android.text.Spannable; -import android.text.SpannableString; -import android.text.style.StyleSpan; import android.view.LayoutInflater; -import android.view.View; import android.view.ViewGroup; -import android.widget.LinearLayout; -import android.widget.TextView; -import androidx.annotation.ColorInt; import androidx.annotation.NonNull; import androidx.recyclerview.widget.AsyncListDiffer; import androidx.recyclerview.widget.DiffUtil; import androidx.recyclerview.widget.RecyclerView; -import net.ktnx.mobileledger.App; -import net.ktnx.mobileledger.R; -import net.ktnx.mobileledger.model.Data; +import net.ktnx.mobileledger.databinding.LastUpdateLayoutBinding; +import net.ktnx.mobileledger.databinding.TransactionDelimiterBinding; +import net.ktnx.mobileledger.databinding.TransactionListRowBinding; import net.ktnx.mobileledger.model.LedgerTransaction; -import net.ktnx.mobileledger.model.LedgerTransactionAccount; import net.ktnx.mobileledger.model.TransactionListItem; -import net.ktnx.mobileledger.ui.MainModel; -import net.ktnx.mobileledger.utils.Colors; -import net.ktnx.mobileledger.utils.Globals; import net.ktnx.mobileledger.utils.Logger; import net.ktnx.mobileledger.utils.Misc; -import net.ktnx.mobileledger.utils.SimpleDate; -import java.text.DateFormat; -import java.util.GregorianCalendar; import java.util.List; import java.util.Locale; -import java.util.TimeZone; -public class TransactionListAdapter extends RecyclerView.Adapter { - private final MainModel model; +public class TransactionListAdapter extends RecyclerView.Adapter { private final AsyncListDiffer listDiffer; - public TransactionListAdapter(MainModel model) { + public TransactionListAdapter() { super(); - this.model = model; listDiffer = new AsyncListDiffer<>(this, new DiffUtil.ItemCallback() { @Override @@ -94,7 +72,9 @@ public class TransactionListAdapter extends RecyclerView.Adapter { - @Override - protected Void doInBackground(TransactionLoaderParams... p) { - LedgerTransaction tr = p[0].transaction; - - SQLiteDatabase db = App.getDatabase(); - tr.loadData(db); - - publishProgress(new TransactionLoaderStep(p[0].holder, p[0].position, tr)); - - int rowIndex = 0; - // FIXME ConcurrentModificationException in ArrayList$ltr.next (ArrayList.java:831) - for (LedgerTransactionAccount acc : tr.getAccounts()) { -// debug(c.getAccountName(), acc.getAmount())); - publishProgress(new TransactionLoaderStep(p[0].holder, acc, rowIndex++, - p[0].boldAccountName)); - } - - publishProgress(new TransactionLoaderStep(p[0].holder, p[0].position, rowIndex)); - - return null; - } - @Override - protected void onProgressUpdate(TransactionLoaderStep... values) { - super.onProgressUpdate(values); - TransactionLoaderStep step = values[0]; - TransactionRowHolder holder = step.getHolder(); - - switch (step.getStep()) { - case HEAD: - holder.tvDescription.setText(step.getTransaction() - .getDescription()); - String trComment = Misc.emptyIsNull(step.getTransaction() - .getComment()); - if (trComment == null) - holder.tvComment.setVisibility(View.GONE); - else { - holder.tvComment.setText(trComment); - holder.tvComment.setVisibility(View.VISIBLE); - } - -// if (step.isOdd()) -// holder.row.setBackgroundColor(Colors.tableRowDarkBG); -// else -// holder.row.setBackgroundColor(Colors.tableRowLightBG); - - break; - case ACCOUNTS: - int rowIndex = step.getAccountPosition(); - Context ctx = holder.row.getContext(); - LinearLayout row = (LinearLayout) holder.tableAccounts.getChildAt(rowIndex); - if (row == null) { - row = new LinearLayout(ctx); - LayoutInflater inflater = ((Activity) ctx).getLayoutInflater(); - inflater.inflate(R.layout.transaction_list_row_accounts_table_row, row); - holder.tableAccounts.addView(row); - } - TextView dummyText = row.findViewById(R.id.dummy_text); - TextView accName = row.findViewById(R.id.transaction_list_acc_row_acc_name); - TextView accComment = - row.findViewById(R.id.transaction_list_acc_row_acc_comment); - TextView accAmount = row.findViewById(R.id.transaction_list_acc_row_acc_amount); - LedgerTransactionAccount acc = step.getAccount(); - - -// debug("tmp", String.format("showing acc row %d: %s %1.2f", rowIndex, -// acc.getAccountName(), acc.getAmount())); - - String boldAccountName = step.getBoldAccountName(); - if ((boldAccountName != null) && acc.getAccountName() - .startsWith(boldAccountName)) - { - accName.setTextColor(Colors.secondary); - accAmount.setTextColor(Colors.secondary); - - SpannableString ss = new SpannableString(acc.getAccountName()); - ss.setSpan(new StyleSpan(Typeface.BOLD), 0, boldAccountName.length(), - Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); - accName.setText(ss); - } - else { - @ColorInt int textColor = dummyText.getTextColors() - .getDefaultColor(); - accName.setTextColor(textColor); - accAmount.setTextColor(textColor); - accName.setText(acc.getAccountName()); - } - - String comment = acc.getComment(); - if (comment != null && !comment.isEmpty()) { - accComment.setText(comment); - accComment.setVisibility(View.VISIBLE); - } - else { - accComment.setVisibility(View.GONE); - } - accAmount.setText(acc.toString()); - - break; - case DONE: - int accCount = step.getAccountCount(); - if (holder.tableAccounts.getChildCount() > accCount) { - holder.tableAccounts.removeViews(accCount, - holder.tableAccounts.getChildCount() - accCount); - } - -// debug("transactions", -// String.format("Position %d fill done", step.getPosition())); - } - } - } - - private static class TransactionLoaderParams { - final LedgerTransaction transaction; - final TransactionRowHolder holder; - final int position; - final String boldAccountName; - TransactionLoaderParams(LedgerTransaction transaction, TransactionRowHolder holder, - int position, String boldAccountName) { - this.transaction = transaction; - this.holder = holder; - this.position = position; - this.boldAccountName = boldAccountName; - } - } } \ No newline at end of file diff --git a/app/src/main/java/net/ktnx/mobileledger/ui/transaction_list/TransactionListDelimiterRowHolder.java b/app/src/main/java/net/ktnx/mobileledger/ui/transaction_list/TransactionListDelimiterRowHolder.java new file mode 100644 index 00000000..390b4941 --- /dev/null +++ b/app/src/main/java/net/ktnx/mobileledger/ui/transaction_list/TransactionListDelimiterRowHolder.java @@ -0,0 +1,61 @@ +/* + * Copyright © 2021 Damyan Ivanov. + * This file is part of MoLe. + * MoLe is free software: you can distribute it and/or modify it + * under the term of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your opinion), any later version. + * + * MoLe is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License terms for details. + * + * You should have received a copy of the GNU General Public License + * along with MoLe. If not, see . + */ + +package net.ktnx.mobileledger.ui.transaction_list; + +import android.view.View; + +import net.ktnx.mobileledger.App; +import net.ktnx.mobileledger.databinding.TransactionDelimiterBinding; +import net.ktnx.mobileledger.model.TransactionListItem; +import net.ktnx.mobileledger.utils.Globals; +import net.ktnx.mobileledger.utils.SimpleDate; + +import java.text.DateFormat; +import java.util.GregorianCalendar; +import java.util.TimeZone; + +class TransactionListDelimiterRowHolder extends TransactionRowHolderBase { + private final TransactionDelimiterBinding b; + TransactionListDelimiterRowHolder(TransactionDelimiterBinding binding) { + super(binding.getRoot()); + b = binding; + } + public void bind(TransactionListItem item) { + SimpleDate date = item.getDate(); + b.transactionDelimiterDate.setText(DateFormat.getDateInstance() + .format(date.toDate())); + if (item.isMonthShown()) { + GregorianCalendar cal = new GregorianCalendar(TimeZone.getDefault()); + cal.setTime(date.toDate()); + App.prepareMonthNames(); + b.transactionDelimiterMonth.setText( + Globals.monthNames[cal.get(GregorianCalendar.MONTH)]); + b.transactionDelimiterMonth.setVisibility(View.VISIBLE); + // holder.vDelimiterLine.setBackgroundResource(R.drawable + // .dashed_border_8dp); + b.transactionDelimiterThick.setVisibility(View.VISIBLE); + } + else { + b.transactionDelimiterMonth.setVisibility(View.GONE); + // holder.vDelimiterLine.setBackgroundResource(R.drawable + // .dashed_border_1dp); + b.transactionDelimiterThick.setVisibility(View.GONE); + } + + } +} diff --git a/app/src/main/java/net/ktnx/mobileledger/ui/transaction_list/TransactionListFragment.java b/app/src/main/java/net/ktnx/mobileledger/ui/transaction_list/TransactionListFragment.java index a809a17e..56d5032f 100644 --- a/app/src/main/java/net/ktnx/mobileledger/ui/transaction_list/TransactionListFragment.java +++ b/app/src/main/java/net/ktnx/mobileledger/ui/transaction_list/TransactionListFragment.java @@ -106,7 +106,7 @@ public class TransactionListFragment extends MobileLedgerListFragment root = view.findViewById(R.id.transaction_root); if (root == null) throw new RuntimeException("Can't get hold on the transaction value view"); - modelAdapter = new TransactionListAdapter(model); + modelAdapter = new TransactionListAdapter(); root.setAdapter(modelAdapter); mainActivity.fabShouldShow(); diff --git a/app/src/main/java/net/ktnx/mobileledger/ui/transaction_list/TransactionListLastUpdateRowHolder.java b/app/src/main/java/net/ktnx/mobileledger/ui/transaction_list/TransactionListLastUpdateRowHolder.java new file mode 100644 index 00000000..0d0d3d3f --- /dev/null +++ b/app/src/main/java/net/ktnx/mobileledger/ui/transaction_list/TransactionListLastUpdateRowHolder.java @@ -0,0 +1,35 @@ +/* + * Copyright © 2021 Damyan Ivanov. + * This file is part of MoLe. + * MoLe is free software: you can distribute it and/or modify it + * under the term of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your opinion), any later version. + * + * MoLe is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License terms for details. + * + * You should have received a copy of the GNU General Public License + * along with MoLe. If not, see . + */ + +package net.ktnx.mobileledger.ui.transaction_list; + +import net.ktnx.mobileledger.databinding.LastUpdateLayoutBinding; +import net.ktnx.mobileledger.model.Data; + +class TransactionListLastUpdateRowHolder extends TransactionRowHolderBase { + private final LastUpdateLayoutBinding b; + TransactionListLastUpdateRowHolder(LastUpdateLayoutBinding binding) { + super(binding.getRoot()); + b = binding; + } + void setLastUpdateText(String text) { + b.lastUpdateText.setText(text); + } + public void bind() { + b.lastUpdateText.setText(Data.lastTransactionsUpdateText.getValue()); + } +} diff --git a/app/src/main/java/net/ktnx/mobileledger/ui/transaction_list/TransactionLoaderStep.java b/app/src/main/java/net/ktnx/mobileledger/ui/transaction_list/TransactionLoaderStep.java deleted file mode 100644 index 8fcb6de5..00000000 --- a/app/src/main/java/net/ktnx/mobileledger/ui/transaction_list/TransactionLoaderStep.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright © 2020 Damyan Ivanov. - * This file is part of MoLe. - * MoLe is free software: you can distribute it and/or modify it - * under the term of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your opinion), any later version. - * - * MoLe is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License terms for details. - * - * You should have received a copy of the GNU General Public License - * along with MoLe. If not, see . - */ - -package net.ktnx.mobileledger.ui.transaction_list; - -import net.ktnx.mobileledger.model.LedgerTransaction; -import net.ktnx.mobileledger.model.LedgerTransactionAccount; - -class TransactionLoaderStep { - private final TransactionListAdapter.LoaderStep step; - private final TransactionRowHolder holder; - private int position; - private int accountCount; - private LedgerTransaction transaction; - private LedgerTransactionAccount account; - private int accountPosition; - private String boldAccountName; - public TransactionLoaderStep(TransactionRowHolder holder, int position, - LedgerTransaction transaction) { - this.step = TransactionListAdapter.LoaderStep.HEAD; - this.holder = holder; - this.transaction = transaction; - this.position = position; - } - public TransactionLoaderStep(TransactionRowHolder holder, LedgerTransactionAccount account, - int accountPosition, String boldAccountName) { - this.step = TransactionListAdapter.LoaderStep.ACCOUNTS; - this.holder = holder; - this.account = account; - this.accountPosition = accountPosition; - this.boldAccountName = boldAccountName; - } - public TransactionLoaderStep(TransactionRowHolder holder, int position, int accountCount) { - this.step = TransactionListAdapter.LoaderStep.DONE; - this.holder = holder; - this.position = position; - this.accountCount = accountCount; - } - public int getAccountCount() { - return accountCount; - } - public int getPosition() { - return position; - } - public String getBoldAccountName() { - return boldAccountName; - } - public int getAccountPosition() { - return accountPosition; - } - public TransactionRowHolder getHolder() { - return holder; - } - public TransactionListAdapter.LoaderStep getStep() { - return step; - } - public LedgerTransaction getTransaction() { - return transaction; - } - public LedgerTransactionAccount getAccount() { - return account; - } -} diff --git a/app/src/main/java/net/ktnx/mobileledger/ui/transaction_list/TransactionRowHolder.java b/app/src/main/java/net/ktnx/mobileledger/ui/transaction_list/TransactionRowHolder.java index 5ec19ba9..85d36911 100644 --- a/app/src/main/java/net/ktnx/mobileledger/ui/transaction_list/TransactionRowHolder.java +++ b/app/src/main/java/net/ktnx/mobileledger/ui/transaction_list/TransactionRowHolder.java @@ -17,74 +17,101 @@ package net.ktnx.mobileledger.ui.transaction_list; +import android.app.Activity; +import android.content.Context; +import android.graphics.Typeface; +import android.text.Spannable; +import android.text.SpannableString; +import android.text.style.StyleSpan; +import android.view.LayoutInflater; import android.view.View; import android.widget.LinearLayout; import android.widget.TextView; +import androidx.annotation.ColorInt; import androidx.annotation.NonNull; -import androidx.cardview.widget.CardView; -import androidx.constraintlayout.widget.ConstraintLayout; -import androidx.recyclerview.widget.RecyclerView; +import androidx.annotation.Nullable; import net.ktnx.mobileledger.R; +import net.ktnx.mobileledger.databinding.TransactionListRowBinding; +import net.ktnx.mobileledger.model.LedgerTransaction; +import net.ktnx.mobileledger.model.LedgerTransactionAccount; import net.ktnx.mobileledger.model.TransactionListItem; +import net.ktnx.mobileledger.utils.Colors; +import net.ktnx.mobileledger.utils.Misc; import java.util.Observer; -class TransactionRowHolder extends RecyclerView.ViewHolder { - final TextView tvDescription; - final TextView tvComment; - final LinearLayout tableAccounts; - final ConstraintLayout row; - final ConstraintLayout vDelimiter; - final CardView vTransaction; - final TextView tvDelimiterMonth, tvDelimiterDate; - final View vDelimiterThick; - final View vHeader; - final TextView tvLastUpdate; +class TransactionRowHolder extends TransactionRowHolderBase { + private final TransactionListRowBinding b; TransactionListItem.Type lastType; private Observer lastUpdateObserver; - public TransactionRowHolder(@NonNull View itemView) { - super(itemView); - this.row = itemView.findViewById(R.id.transaction_row); - this.tvDescription = itemView.findViewById(R.id.transaction_row_description); - this.tvComment = itemView.findViewById(R.id.transaction_comment); - this.tableAccounts = itemView.findViewById(R.id.transaction_row_acc_amounts); - this.vDelimiter = itemView.findViewById(R.id.transaction_delimiter); - this.vTransaction = itemView.findViewById(R.id.transaction_card_view); - this.tvDelimiterDate = itemView.findViewById(R.id.transaction_delimiter_date); - this.tvDelimiterMonth = itemView.findViewById(R.id.transaction_delimiter_month); - this.vDelimiterThick = itemView.findViewById(R.id.transaction_delimiter_thick); - this.vHeader = itemView.findViewById(R.id.last_update_container); - this.tvLastUpdate = itemView.findViewById(R.id.last_update_text); + public TransactionRowHolder(@NonNull TransactionListRowBinding binding) { + super(binding.getRoot()); + b = binding; } - void setLastUpdateText(String text) { - tvLastUpdate.setText(text); - } - void setType(TransactionListItem.Type newType) { - if (newType == lastType) - return; + public void bind(@NonNull LedgerTransaction tr, @Nullable String boldAccountName) { + b.transactionRowDescription.setText(tr.getDescription()); + String trComment = Misc.emptyIsNull(tr.getComment()); + if (trComment == null) + b.transactionComment.setVisibility(View.GONE); + else { + b.transactionComment.setText(trComment); + b.transactionComment.setVisibility(View.VISIBLE); + } + + int rowIndex = 0; + Context ctx = b.getRoot() + .getContext(); + LayoutInflater inflater = ((Activity) ctx).getLayoutInflater(); + for (LedgerTransactionAccount acc : tr.getAccounts()) { + LinearLayout row = (LinearLayout) b.transactionRowAccAmounts.getChildAt(rowIndex); + if (row == null) { + row = new LinearLayout(ctx); + inflater.inflate(R.layout.transaction_list_row_accounts_table_row, row); + b.transactionRowAccAmounts.addView(row); + } + + TextView dummyText = row.findViewById(R.id.dummy_text); + TextView accName = row.findViewById(R.id.transaction_list_acc_row_acc_name); + TextView accComment = row.findViewById(R.id.transaction_list_acc_row_acc_comment); + TextView accAmount = row.findViewById(R.id.transaction_list_acc_row_acc_amount); - switch (newType) { - case TRANSACTION: - vHeader.setVisibility(View.GONE); - vTransaction.setVisibility(View.VISIBLE); - vDelimiter.setVisibility(View.GONE); - break; - case DELIMITER: - vHeader.setVisibility(View.GONE); - vTransaction.setVisibility(View.GONE); - vDelimiter.setVisibility(View.VISIBLE); - break; - case HEADER: - vHeader.setVisibility(View.VISIBLE); - vTransaction.setVisibility(View.GONE); - vDelimiter.setVisibility(View.GONE); - break; - default: - throw new IllegalStateException("Unexpected value: " + newType); + if ((boldAccountName != null) && acc.getAccountName() + .startsWith(boldAccountName)) + { + accName.setTextColor(Colors.secondary); + accAmount.setTextColor(Colors.secondary); + + SpannableString ss = new SpannableString(acc.getAccountName()); + ss.setSpan(new StyleSpan(Typeface.BOLD), 0, boldAccountName.length(), + Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + accName.setText(ss); + } + else { + @ColorInt int textColor = dummyText.getTextColors() + .getDefaultColor(); + accName.setTextColor(textColor); + accAmount.setTextColor(textColor); + accName.setText(acc.getAccountName()); + } + + String comment = acc.getComment(); + if (comment != null && !comment.isEmpty()) { + accComment.setText(comment); + accComment.setVisibility(View.VISIBLE); + } + else { + accComment.setVisibility(View.GONE); + } + accAmount.setText(acc.toString()); + + rowIndex++; } - lastType = newType; + if (b.transactionRowAccAmounts.getChildCount() > rowIndex) { + b.transactionRowAccAmounts.removeViews(rowIndex, + b.transactionRowAccAmounts.getChildCount() - rowIndex); + } } } diff --git a/app/src/main/java/net/ktnx/mobileledger/ui/transaction_list/TransactionRowHolderBase.java b/app/src/main/java/net/ktnx/mobileledger/ui/transaction_list/TransactionRowHolderBase.java new file mode 100644 index 00000000..951cab62 --- /dev/null +++ b/app/src/main/java/net/ktnx/mobileledger/ui/transaction_list/TransactionRowHolderBase.java @@ -0,0 +1,38 @@ +/* + * Copyright © 2021 Damyan Ivanov. + * This file is part of MoLe. + * MoLe is free software: you can distribute it and/or modify it + * under the term of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your opinion), any later version. + * + * MoLe is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License terms for details. + * + * You should have received a copy of the GNU General Public License + * along with MoLe. If not, see . + */ + +package net.ktnx.mobileledger.ui.transaction_list; + +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +public class TransactionRowHolderBase extends RecyclerView.ViewHolder { + public TransactionRowHolderBase(@NonNull View itemView) { + super(itemView); + } + public TransactionListLastUpdateRowHolder asHeader() { + return (TransactionListLastUpdateRowHolder) this; + } + public TransactionRowHolder asTransaction() { + return (TransactionRowHolder) this; + } + public TransactionListDelimiterRowHolder asDelimiter() { + return (TransactionListDelimiterRowHolder) this; + } +} diff --git a/app/src/main/res/layout/transaction_delimiter.xml b/app/src/main/res/layout/transaction_delimiter.xml new file mode 100644 index 00000000..0b283b32 --- /dev/null +++ b/app/src/main/res/layout/transaction_delimiter.xml @@ -0,0 +1,65 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/transaction_list_row.xml b/app/src/main/res/layout/transaction_list_row.xml index a8940553..86b57169 100644 --- a/app/src/main/res/layout/transaction_list_row.xml +++ b/app/src/main/res/layout/transaction_list_row.xml @@ -1,7 +1,7 @@