2 * Copyright © 2021 Damyan Ivanov.
3 * This file is part of MoLe.
4 * MoLe is free software: you can distribute it and/or modify it
5 * under the term of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your opinion), any later version.
9 * MoLe is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License terms for details.
14 * You should have received a copy of the GNU General Public License
15 * along with MoLe. If not, see <https://www.gnu.org/licenses/>.
18 package net.ktnx.mobileledger.ui.new_transaction;
20 import android.view.LayoutInflater;
21 import android.view.ViewGroup;
23 import androidx.annotation.NonNull;
24 import androidx.recyclerview.widget.AsyncListDiffer;
25 import androidx.recyclerview.widget.DiffUtil;
26 import androidx.recyclerview.widget.ItemTouchHelper;
27 import androidx.recyclerview.widget.RecyclerView;
29 import net.ktnx.mobileledger.databinding.NewTransactionRowBinding;
30 import net.ktnx.mobileledger.model.MobileLedgerProfile;
31 import net.ktnx.mobileledger.utils.Logger;
33 import java.util.List;
34 import java.util.Locale;
35 import java.util.Objects;
37 class NewTransactionItemsAdapter extends RecyclerView.Adapter<NewTransactionItemHolder> {
38 final NewTransactionModel model;
39 private final ItemTouchHelper touchHelper;
40 private final AsyncListDiffer<NewTransactionModel.Item> differ =
41 new AsyncListDiffer<>(this, new DiffUtil.ItemCallback<NewTransactionModel.Item>() {
43 public boolean areItemsTheSame(@NonNull NewTransactionModel.Item oldItem,
44 @NonNull NewTransactionModel.Item newItem) {
45 // Logger.debug("new-trans",
46 // String.format("comparing ids of {%s} and {%s}", oldItem.toString(),
47 // newItem.toString()));
48 return oldItem.getId() == newItem.getId();
51 public boolean areContentsTheSame(@NonNull NewTransactionModel.Item oldItem,
52 @NonNull NewTransactionModel.Item newItem) {
54 // Logger.debug("new-trans",
55 // String.format("comparing contents of {%s} and {%s}", oldItem.toString(),
56 // newItem.toString()));
57 return oldItem.equalContents(newItem);
60 private MobileLedgerProfile mProfile;
61 private int checkHoldCounter = 0;
62 NewTransactionItemsAdapter(NewTransactionModel viewModel, MobileLedgerProfile profile) {
64 setHasStableIds(true);
69 NewTransactionItemsAdapter adapter = this;
71 touchHelper = new ItemTouchHelper(new ItemTouchHelper.Callback() {
73 public boolean isLongPressDragEnabled() {
77 public boolean canDropOver(@NonNull RecyclerView recyclerView,
78 @NonNull RecyclerView.ViewHolder current,
79 @NonNull RecyclerView.ViewHolder target) {
80 final int adapterPosition = target.getAdapterPosition();
82 // first and last items are immovable
83 if (adapterPosition == 0)
85 if (adapterPosition == adapter.getItemCount() - 1)
88 return super.canDropOver(recyclerView, current, target);
91 public int getMovementFlags(@NonNull RecyclerView recyclerView,
92 @NonNull RecyclerView.ViewHolder viewHolder) {
93 int flags = makeFlag(ItemTouchHelper.ACTION_STATE_IDLE, ItemTouchHelper.END);
94 // the top (date and description) and the bottom (padding) items are always there
95 final int adapterPosition = viewHolder.getAdapterPosition();
96 if ((adapterPosition > 0) && (adapterPosition < adapter.getItemCount() - 1)) {
97 flags |= makeFlag(ItemTouchHelper.ACTION_STATE_DRAG,
98 ItemTouchHelper.UP | ItemTouchHelper.DOWN) |
99 makeFlag(ItemTouchHelper.ACTION_STATE_SWIPE,
100 ItemTouchHelper.START | ItemTouchHelper.END);
106 public boolean onMove(@NonNull RecyclerView recyclerView,
107 @NonNull RecyclerView.ViewHolder viewHolder,
108 @NonNull RecyclerView.ViewHolder target) {
110 model.moveItem(viewHolder.getAdapterPosition(), target.getAdapterPosition());
114 public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int direction) {
115 int pos = viewHolder.getAdapterPosition();
116 viewModel.removeItem(pos);
121 public long getItemId(int position) {
122 return differ.getCurrentList()
126 public void setProfile(MobileLedgerProfile profile) {
131 public NewTransactionItemHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
132 NewTransactionRowBinding b =
133 NewTransactionRowBinding.inflate(LayoutInflater.from(parent.getContext()), parent,
136 return new NewTransactionItemHolder(b, this);
139 public void onBindViewHolder(@NonNull NewTransactionItemHolder holder, int position) {
140 Logger.debug("bind", String.format(Locale.US, "Binding item at position %d", position));
141 NewTransactionModel.Item item = Objects.requireNonNull(differ.getCurrentList()
144 Logger.debug("bind", String.format(Locale.US, "Bound %s item at position %d", item.getType()
149 public int getItemCount() {
150 return differ.getCurrentList()
154 public void onAttachedToRecyclerView(@NonNull RecyclerView recyclerView) {
155 super.onAttachedToRecyclerView(recyclerView);
156 touchHelper.attachToRecyclerView(recyclerView);
159 public void onDetachedFromRecyclerView(@NonNull RecyclerView recyclerView) {
160 touchHelper.attachToRecyclerView(null);
161 super.onDetachedFromRecyclerView(recyclerView);
163 void noteFocusIsOnAccount(int position) {
164 model.noteFocusChanged(position, FocusedElement.Account);
166 void noteFocusIsOnAmount(int position) {
167 model.noteFocusChanged(position, FocusedElement.Amount);
169 void noteFocusIsOnComment(int position) {
170 model.noteFocusChanged(position, FocusedElement.Comment);
172 void noteFocusIsOnTransactionComment(int position) {
173 model.noteFocusChanged(position, FocusedElement.TransactionComment);
175 public void noteFocusIsOnDescription(int pos) {
176 model.noteFocusChanged(pos, FocusedElement.Description);
178 private void holdSubmittableChecks() {
181 private void releaseSubmittableChecks() {
182 if (checkHoldCounter == 0)
183 throw new RuntimeException("Asymmetrical call to releaseSubmittableChecks");
186 void setItemCurrency(int position, String newCurrency) {
187 model.setItemCurrency(position, newCurrency);
190 public void setItems(List<NewTransactionModel.Item> newList) {
191 Logger.debug("new-trans", "adapter: submitting new item list");
192 differ.submitList(newList);