public void onCreate() {
super.onCreate();
updateColorValues();
+ updateMonthNames();
MLDB.init(this);
SharedPreferences p = PreferenceManager.getDefaultSharedPreferences(this);
Data.optShowOnlyStarred.set(p.getBoolean(PREF_KEY_SHOW_ONLY_STARRED_ACCOUNTS, false));
- SharedPreferences.OnSharedPreferenceChangeListener handler = (preference, value) -> {
- Data.optShowOnlyStarred
- .set(preference.getBoolean(PREF_KEY_SHOW_ONLY_STARRED_ACCOUNTS, false));
- };
+ SharedPreferences.OnSharedPreferenceChangeListener handler =
+ (preference, value) -> Data.optShowOnlyStarred
+ .set(preference.getBoolean(PREF_KEY_SHOW_ONLY_STARRED_ACCOUNTS, false));
p.registerOnSharedPreferenceChangeListener(handler);
}
+ private void updateMonthNames() {
+ Resources rm = getResources();
+ Globals.monthNames = rm.getStringArray(R.array.month_names);
+ }
@Override
public void onTerminate() {
MLDB.done();
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
updateColorValues();
+ updateMonthNames();
}
private void updateColorValues() {
Resources rm = getResources();
import net.ktnx.mobileledger.model.Data;
import net.ktnx.mobileledger.model.LedgerTransaction;
import net.ktnx.mobileledger.model.LedgerTransactionAccount;
+import net.ktnx.mobileledger.utils.Globals;
import net.ktnx.mobileledger.utils.NetworkUtil;
import net.ktnx.mobileledger.utils.UrlEncodedFormData;
public class SaveTransactionTask extends AsyncTask<LedgerTransaction, Void, Void> {
private final TaskCallback taskCallback;
+ protected String error;
private String token;
private String session;
private String backendUrl;
private LedgerTransaction ltr;
- protected String error;
public SaveTransactionTask(TaskCallback callback) {
taskCallback = callback;
UrlEncodedFormData params = new UrlEncodedFormData();
params.addPair("_formid", "identify-add");
if (token != null) params.addPair("_token", token);
- params.addPair("date", ltr.getDate());
+ params.addPair("date", Globals.formatLedgerDate(ltr.getDate()));
params.addPair("description", ltr.getDescription());
for (LedgerTransactionAccount acc : ltr.getAccounts()) {
params.addPair("account", acc.getAccountName());
import net.ktnx.mobileledger.model.Data;
import net.ktnx.mobileledger.model.LedgerTransaction;
+import net.ktnx.mobileledger.model.TransactionListItem;
+import net.ktnx.mobileledger.utils.Globals;
import net.ktnx.mobileledger.utils.MLDB;
import java.util.ArrayList;
+import java.util.Date;
import java.util.List;
-public class UpdateTransactionsTask extends AsyncTask<String, Void, List<LedgerTransaction>> {
- protected List<LedgerTransaction> doInBackground(String[] filterAccName) {
+public class UpdateTransactionsTask extends AsyncTask<String, Void, List<TransactionListItem>> {
+ protected List<TransactionListItem> doInBackground(String[] filterAccName) {
Data.backgroundTaskCount.incrementAndGet();
String profile_uuid = Data.profile.get().getUuid();
try {
- ArrayList<LedgerTransaction> newList = new ArrayList<>();
+ ArrayList<TransactionListItem> newList = new ArrayList<>();
String sql;
String[] params;
if (filterAccName[0] == null) {
- sql = "SELECT id FROM transactions WHERE profile=? ORDER BY date desc, id desc";
+ sql = "SELECT id, date FROM transactions WHERE profile=? ORDER BY date desc, id " +
+ "desc";
params = new String[]{profile_uuid};
}
else {
- sql = "SELECT distinct tr.id from transactions tr JOIN transaction_accounts ta " +
+ sql = "SELECT distinct tr.id, tr.date from transactions tr JOIN " +
+ "transaction_accounts ta " +
"ON ta.transaction_id=tr.id AND ta.profile=tr.profile WHERE tr.profile=? " +
"and ta.account_name LIKE ?||'%' AND ta" +
".amount <> 0 ORDER BY tr.date desc, tr.id desc";
Log.d("UTT", sql);
SQLiteDatabase db = MLDB.getReadableDatabase();
+ Date lastDate = null;
try (Cursor cursor = db.rawQuery(sql, params)) {
while (cursor.moveToNext()) {
if (isCancelled()) return null;
int transaction_id = cursor.getInt(0);
- newList.add(new LedgerTransaction(transaction_id));
+ String dateString = cursor.getString(1);
+ Date date = Globals.parseLedgerDate(dateString);
+
+ if ((lastDate == null) || !lastDate.equals(date)) {
+ boolean showMonth = (lastDate == null) || (date != null) &&
+ (date.getMonth() !=
+ lastDate.getMonth() ||
+ date.getYear() !=
+ lastDate.getYear());
+ newList.add(new TransactionListItem(date, showMonth));
+ }
+ newList.add(new TransactionListItem(new LedgerTransaction(transaction_id)));
// Log.d("UTT", String.format("got transaction %d", transaction_id));
+
+ lastDate = date;
}
Data.transactions.set(newList);
Log.d("UTT", "transaction list value updated");
import android.util.Log;
import net.ktnx.mobileledger.utils.Digest;
+import net.ktnx.mobileledger.utils.Globals;
import java.nio.charset.Charset;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Comparator;
+import java.util.Date;
public class LedgerTransaction {
private static final String DIGEST_TYPE = "SHA-256";
};
private String profile;
private Integer id;
- private String date;
+ private Date date;
private String description;
private ArrayList<LedgerTransactionAccount> accounts;
private String dataHash;
private boolean dataLoaded;
- public LedgerTransaction(Integer id, String date, String description) {
+ public LedgerTransaction(Integer id, String dateString, String description) {
+ this(id, Globals.parseLedgerDate(dateString), description);
+ }
+ public LedgerTransaction(Integer id, Date date, String description) {
this.profile = Data.profile.get().getUuid();
this.id = id;
this.date = date;
this.dataHash = null;
dataLoaded = false;
}
- public LedgerTransaction(String date, String description) {
+ public LedgerTransaction(Date date, String description) {
this(null, date, description);
}
public LedgerTransaction(int id) {
- this(id, null, null);
+ this(id, (Date) null, null);
}
public ArrayList<LedgerTransactionAccount> getAccounts() {
return accounts;
accounts.add(item);
dataHash = null;
}
- public String getDate() {
+ public Date getDate() {
return date;
}
- public void setDate(String date) {
+ public void setDate(Date date) {
this.date = date;
dataHash = null;
}
new String[]{profile, String.valueOf(id)}))
{
if (cTr.moveToFirst()) {
- date = cTr.getString(0);
+ String dateString = cTr.getString(0);
+ date = Globals.parseLedgerDate(dateString);
description = cTr.getString(1);
try (Cursor cAcc = db.rawQuery("SELECT account_name, amount, currency FROM " +
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;
+import net.ktnx.mobileledger.utils.Globals;
import net.ktnx.mobileledger.utils.MLDB;
import java.util.ArrayList;
db.execSQL("INSERT INTO transactions(profile, id, date, description, data_hash, keep) " +
"values(?,?,?,?,?,1)",
- new Object[]{uuid, tr.getId(), tr.getDate(), tr.getDescription(), tr.getDataHash()
+ new Object[]{uuid, tr.getId(), Globals.formatLedgerDate(tr.getDate()),
+ tr.getDescription(), tr.getDataHash()
});
for (LedgerTransactionAccount item : tr.getAccounts()) {
import java.util.List;
-public class TransactionList extends ObservableValue<List<LedgerTransaction>> {
+public class TransactionList extends ObservableValue<List<TransactionListItem>> {
}
--- /dev/null
+/*
+ * Copyright © 2019 Damyan Ivanov.
+ * This file is part of Mobile-Ledger.
+ * Mobile-Ledger 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.
+ *
+ * Mobile-Ledger 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 Mobile-Ledger. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package net.ktnx.mobileledger.model;
+
+import java.util.Date;
+
+public class TransactionListItem {
+ private Type type;
+ private Date date;
+ private boolean monthShown;
+ private LedgerTransaction transaction;
+ public TransactionListItem(Date date, boolean monthShown) {
+ this.type = Type.DELIMITER;
+ this.date = date;
+ this.monthShown = monthShown;
+ }
+ public TransactionListItem(LedgerTransaction transaction) {
+ this.type = Type.TRANSACTION;
+ this.transaction = transaction;
+ }
+ public Type getType() {
+ return type;
+ }
+ public Date getDate() {
+ return date;
+ }
+ public boolean isMonthShown() {
+ return monthShown;
+ }
+ public LedgerTransaction getTransaction() {
+ return transaction;
+ }
+ public enum Type {TRANSACTION, DELIMITER}
+}
import net.ktnx.mobileledger.model.LedgerTransactionAccount;
import net.ktnx.mobileledger.ui.DatePickerFragment;
import net.ktnx.mobileledger.ui.OnSwipeTouchListener;
+import net.ktnx.mobileledger.utils.Globals;
import net.ktnx.mobileledger.utils.MLDB;
import java.util.Date;
saver = new SaveTransactionTask(this);
- String date = tvDate.getText().toString();
- if (date.isEmpty()) date = String.valueOf(new Date().getDate());
+ String dateString = tvDate.getText().toString();
+ Date date;
+ if (dateString.isEmpty()) date = new Date();
+ else date = Globals.parseLedgerDate(dateString);
LedgerTransaction tr = new LedgerTransaction(date, tvDescription.getText().toString());
TableLayout table = findViewById(R.id.new_transaction_accounts_table);
import net.ktnx.mobileledger.R;
import net.ktnx.mobileledger.model.LedgerTransaction;
import net.ktnx.mobileledger.model.LedgerTransactionAccount;
+import net.ktnx.mobileledger.model.TransactionListItem;
import net.ktnx.mobileledger.utils.Globals;
import net.ktnx.mobileledger.utils.MLDB;
+import java.text.DateFormat;
+import java.util.Date;
+
import static net.ktnx.mobileledger.utils.DimensionUtils.dp2px;
public class TransactionListAdapter extends RecyclerView.Adapter<TransactionRowHolder> {
private String boldAccountName;
public void onBindViewHolder(@NonNull TransactionRowHolder holder, int position) {
- LedgerTransaction tr = TransactionListViewModel.getTransaction(position);
- // in a race when transaction value is reduced, but the model hasn't been notified yet
- // the view will disappear when the notifications reaches the model, so by simply omitting
- // the out-of-range get() call nothing bad happens - just a to-be-deleted view remains
- // a bit longer
- if (tr == null) return;
+ TransactionListItem item = TransactionListViewModel.getTransactionListItem(position);
+
+ if (item.getType() == TransactionListItem.Type.TRANSACTION) {
+ holder.vTransaction.setVisibility(View.VISIBLE);
+ holder.vDelimiter.setVisibility(View.GONE);
+ LedgerTransaction tr = item.getTransaction();
+ // in a race when transaction value is reduced, but the model hasn't been notified yet
+ // the view will disappear when the notifications reaches the model, so by simply omitting
+ // the out-of-range get() call nothing bad happens - just a to-be-deleted view remains
+ // a bit longer
+ if (tr == null) return;
+
+ LedgerTransaction previous = null;
+ TransactionListItem previousItem = null;
+ if (position > 0)
+ previousItem = TransactionListViewModel.getTransactionListItem(position - 1);
// Log.d("transactions", String.format("Filling position %d with %d accounts", position,
// tr.getAccounts().size()));
- TransactionLoader loader = new TransactionLoader();
- loader.execute(new TransactionLoaderParams(tr, holder, position, boldAccountName));
+ TransactionLoader loader = new TransactionLoader();
+ loader.execute(
+ new TransactionLoaderParams(tr, previous, holder, position, boldAccountName));
+
+ // WORKAROUND what seems to be a bug in CardHolder somewhere
+ // when a view that was previously holding a delimiter is re-purposed
+ // occasionally it stays too short (not high enough)
+ holder.vTransaction.measure(View.MeasureSpec
+ .makeMeasureSpec(holder.itemView.getWidth(), View.MeasureSpec.EXACTLY),
+ View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
+ }
+ else {
+ Date date = item.getDate();
+ holder.vTransaction.setVisibility(View.GONE);
+ holder.vDelimiter.setVisibility(View.VISIBLE);
+ holder.tvDelimiterDate.setText(DateFormat.getDateInstance().format(date));
+ holder.tvDelimiterMonth
+ .setText(item.isMonthShown() ? Globals.monthNames[date.getMonth()] : "");
+ }
}
@NonNull
@Override
protected Void doInBackground(TransactionLoaderParams... p) {
LedgerTransaction tr = p[0].transaction;
+ LedgerTransaction previous = p[0].previousTransaction;
SQLiteDatabase db = MLDB.getReadableDatabase();
tr.loadData(db);
- publishProgress(new TransactionLoaderStep(p[0].holder, p[0].position, tr));
+ boolean showDate;
+ if (previous == null) showDate = true;
+ else {
+ previous.loadData(db);
+ showDate = !previous.getDate().equals(tr.getDate());
+ }
+ publishProgress(new TransactionLoaderStep(p[0].holder, p[0].position, tr, showDate));
int rowIndex = 0;
for (LedgerTransactionAccount acc : tr.getAccounts()) {
switch (step.getStep()) {
case HEAD:
holder.tvDescription.setText(step.getTransaction().getDescription());
- holder.tvDate.setText(step.getTransaction().getDate());
if (step.getPosition() % 2 == 0) {
holder.row.setBackgroundColor(Globals.tableRowEvenBG);
}
private class TransactionLoaderParams {
- LedgerTransaction transaction;
+ LedgerTransaction transaction, previousTransaction;
TransactionRowHolder holder;
int position;
String boldAccountName;
- TransactionLoaderParams(LedgerTransaction transaction, TransactionRowHolder holder,
+ TransactionLoaderParams(LedgerTransaction transaction, TransactionRowHolder holder, int position, String boldAccountName) {
+ this(transaction, null, holder, position, boldAccountName);
+ }
+ TransactionLoaderParams(LedgerTransaction transaction,
+ LedgerTransaction previousTransaction, TransactionRowHolder holder,
int position, String boldAccountName) {
this.transaction = transaction;
+ this.previousTransaction = previousTransaction;
this.holder = holder;
this.position = position;
this.boldAccountName = boldAccountName;
import net.ktnx.mobileledger.async.UpdateTransactionsTask;
import net.ktnx.mobileledger.model.Data;
-import net.ktnx.mobileledger.model.LedgerTransaction;
+import net.ktnx.mobileledger.model.TransactionListItem;
import net.ktnx.mobileledger.utils.ObservableValue;
import java.util.List;
public static void scheduleTransactionListReload() {
String filter = TransactionListFragment.accountFilter.get();
- AsyncTask<String, Void, List<LedgerTransaction>> task = new UTT();
+ AsyncTask<String, Void, List<TransactionListItem>> task = new UTT();
task.execute(filter);
}
- public static LedgerTransaction getTransaction(int position) {
- List<LedgerTransaction> transactions = Data.transactions.get();
+ public static TransactionListItem getTransactionListItem(int position) {
+ List<TransactionListItem> transactions = Data.transactions.get();
if (position >= transactions.size()) return null;
return transactions.get(position);
}
public static int getTransactionCount() {
- List<LedgerTransaction> transactions = Data.transactions.get();
+ List<TransactionListItem> transactions = Data.transactions.get();
if (transactions == null) return 0;
return transactions.size();
}
private static class UTT extends UpdateTransactionsTask {
@Override
- protected void onPostExecute(List<LedgerTransaction> list) {
+ protected void onPostExecute(List<TransactionListItem> list) {
super.onPostExecute(list);
if (list != null) Data.transactions.set(list);
}
private LedgerTransactionAccount account;
private int accountPosition;
private String boldAccountName;
+ private boolean showDate;
public TransactionLoaderStep(TransactionRowHolder holder, int position,
- LedgerTransaction transaction) {
+ LedgerTransaction transaction, boolean showDate) {
this.step = TransactionListAdapter.LoaderStep.HEAD;
this.holder = holder;
this.transaction = transaction;
this.position = position;
+ this.showDate = showDate;
}
public TransactionLoaderStep(TransactionRowHolder holder, LedgerTransactionAccount account,
int accountPosition, String boldAccountName) {
public LedgerTransactionAccount getAccount() {
return account;
}
+ public boolean isDateShown() {
+ return showDate;
+ }
}
import android.support.annotation.NonNull;
import android.support.constraint.ConstraintLayout;
+import android.support.v7.widget.CardView;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.LinearLayout;
import net.ktnx.mobileledger.R;
class TransactionRowHolder extends RecyclerView.ViewHolder {
- TextView tvDescription, tvDate;
+ TextView tvDescription;
LinearLayout tableAccounts;
ConstraintLayout row;
+ ConstraintLayout vDelimiter;
+ CardView vTransaction;
+ TextView tvDelimiterMonth, tvDelimiterDate;
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.tvDate = itemView.findViewById(R.id.transaction_row_date);
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);
}
}
import android.view.View;
import android.view.inputmethod.InputMethodManager;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Locale;
+
public final class Globals {
@ColorInt
public static int tableRowEvenBG;
public static int tableRowOddBG;
@ColorInt
public static int primaryDark, defaultTextColor;
+ public static String[] monthNames;
public static void hideSoftKeyboard(Activity act) {
// hide the keyboard
View v = act.getCurrentFocus();
imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
}
}
-
+ private static SimpleDateFormat ledgerDateFormatter = new SimpleDateFormat("y/M/d", Locale.US);
+ public static Date parseLedgerDate(String dateString) {
+ try {
+ return ledgerDateFormatter.parse(dateString);
+ }
+ catch (ParseException e) {
+ throw new RuntimeException(String.format("Error parsing date '%s'", dateString), e);
+ }
+ }
+ public static String formatLedgerDate(Date date) {
+ return ledgerDateFormatter.format(date);
+ }
}
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<!--
- ~ Copyright © 2018 Damyan Ivanov.
+ ~ Copyright © 2019 Damyan Ivanov.
~ This file is part of Mobile-Ledger.
~ Mobile-Ledger is free software: you can distribute it and/or modify it
~ under the term of the GNU General Public License as published by
~ along with Mobile-Ledger. If not, see <https://www.gnu.org/licenses/>.
-->
-<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
+<android.support.v7.widget.ContentFrameLayout 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="wrap_content"
- android:layout_margin="8dp"
- app:cardCornerRadius="16dp"
- app:cardElevation="4dp"
- app:cardUseCompatPadding="false"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_goneMarginBottom="8dp">
+ android:layout_height="wrap_content">
- <android.support.constraint.ConstraintLayout
- android:id="@+id/transaction_row"
+ <android.support.v7.widget.CardView
+ android:id="@+id/transaction_card_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:gravity="center_vertical"
- android:minHeight="36dp"
- android:orientation="horizontal"
- android:padding="8dp">
-
- <LinearLayout
- android:id="@+id/transaction_row_head"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="horizontal"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintStart_toStartOf="parent">
+ android:layout_margin="8dp"
+ android:visibility="gone"
+ app:cardCornerRadius="16dp"
+ app:cardElevation="4dp"
+ app:cardUseCompatPadding="false"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_goneMarginBottom="8dp">
- <TextView
- android:id="@+id/transaction_row_description"
- style="@style/account_summary_account_name"
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:layout_weight="5"
- android:text="---."
- android:textStyle="bold"
- tools:ignore="HardcodedText" />
-
- <TextView
- android:id="@+id/transaction_row_date"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginEnd="0dp"
- app:layout_constraintEnd_toEndOf="parent" />
- </LinearLayout>
-
- <LinearLayout
- android:id="@+id/transaction_row_header_border"
+ <android.support.constraint.ConstraintLayout
+ android:id="@+id/transaction_row"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:background="@drawable/dashed_border_1dp"
- android:minHeight="2dp"
+ android:gravity="center_vertical"
+ android:minHeight="36dp"
android:orientation="horizontal"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintTop_toBottomOf="@+id/transaction_row_head" />
-
- <LinearLayout
- android:id="@+id/transaction_row_acc_amounts"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_weight="5"
- android:orientation="vertical"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintTop_toBottomOf="@+id/transaction_row_header_border">
+ android:padding="8dp">
<LinearLayout
+ android:id="@+id/transaction_row_head"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:gravity="center_vertical"
android:orientation="horizontal"
- android:paddingStart="8dp"
- android:paddingEnd="0dp">
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintStart_toStartOf="parent">
<TextView
+ android:id="@+id/transaction_row_description"
+ style="@style/account_summary_account_name"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="5"
- android:text="---"
- android:textAlignment="viewStart"
+ android:text="---."
+ android:textStyle="bold"
tools:ignore="HardcodedText" />
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginEnd="0dp"
- android:minWidth="60dp"
- android:text="€ --,--"
- android:textAlignment="viewEnd"
- tools:ignore="HardcodedText" />
</LinearLayout>
<LinearLayout
+ android:id="@+id/transaction_row_header_border"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:gravity="center_vertical"
+ android:background="@drawable/dashed_border_1dp"
+ android:minHeight="2dp"
android:orientation="horizontal"
- android:paddingStart="8dp"
- android:paddingEnd="0dp">
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toBottomOf="@+id/transaction_row_head" />
- <TextView
- android:layout_width="0dp"
+ <LinearLayout
+ android:id="@+id/transaction_row_acc_amounts"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_weight="5"
+ android:orientation="vertical"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toBottomOf="@+id/transaction_row_header_border">
+
+ <LinearLayout
+ android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_weight="5"
- android:text="---"
- android:textAlignment="viewStart"
- tools:ignore="HardcodedText" />
+ android:gravity="center_vertical"
+ android:orientation="horizontal"
+ android:paddingStart="8dp"
+ android:paddingEnd="0dp">
- <TextView
- android:layout_width="wrap_content"
+ <TextView
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_weight="5"
+ android:text="---"
+ android:textAlignment="viewStart"
+ tools:ignore="HardcodedText" />
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginEnd="0dp"
+ android:minWidth="60dp"
+ android:text="€ --,--"
+ android:textAlignment="viewEnd"
+ tools:ignore="HardcodedText" />
+ </LinearLayout>
+
+ <LinearLayout
+ android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_marginEnd="0dp"
- android:minWidth="60dp"
- android:text="---,--"
- android:textAlignment="viewEnd"
- tools:ignore="HardcodedText" />
+ android:gravity="center_vertical"
+ android:orientation="horizontal"
+ android:paddingStart="8dp"
+ android:paddingEnd="0dp">
+
+ <TextView
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_weight="5"
+ android:text="---"
+ android:textAlignment="viewStart"
+ tools:ignore="HardcodedText" />
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginEnd="0dp"
+ android:minWidth="60dp"
+ android:text="---,--"
+ android:textAlignment="viewEnd"
+ tools:ignore="HardcodedText" />
+ </LinearLayout>
</LinearLayout>
- </LinearLayout>
+
+ </android.support.constraint.ConstraintLayout>
+ </android.support.v7.widget.CardView>
+
+ <android.support.constraint.ConstraintLayout
+ android:id="@+id/transaction_delimiter"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="8dp"
+ android:layout_marginTop="16dp"
+ android:layout_marginEnd="8dp"
+ android:foregroundGravity="center_vertical"
+ android:orientation="horizontal">
+
+ <TextView
+ android:id="@+id/transaction_delimiter_month"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:text="---------"
+ android:textStyle="bold"
+ app:layout_constraintStart_toStartOf="parent"
+ tools:ignore="HardcodedText" />
+
+ <TextView
+ android:id="@+id/transaction_delimiter_date"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:text="--.--.----"
+ android:textStyle="bold"
+ app:layout_constraintEnd_toEndOf="parent"
+ tools:ignore="HardcodedText" />
+
+ <View
+ android:id="@+id/view"
+ android:layout_width="0dp"
+ android:layout_height="0dp"
+ android:layout_marginStart="8dp"
+ android:layout_marginEnd="8dp"
+ android:background="@drawable/dashed_border_1dp"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintEnd_toStartOf="@id/transaction_delimiter_date"
+ app:layout_constraintStart_toEndOf="@id/transaction_delimiter_month"
+ app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
-</android.support.v7.widget.CardView>
+</android.support.v7.widget.ContentFrameLayout>
\ No newline at end of file
<string name="new_profile_title">Нов профил</string>
<string name="delete_profile">Изтриване на профила</string>
<string name="delete">Изтриване</string>
+ <string-array name="month_names">
+ <item>Януари</item>
+ <item>Февруари</item>
+ <item>Март</item>
+ <item>Април</item>
+ <item>Май</item>
+ <item>Юни</item>
+ <item>Юли</item>
+ <item>Август</item>
+ <item>Септември</item>
+ <item>Октомври</item>
+ <item>Ноември</item>
+ <item>Декември</item>
+ </string-array>
+
</resources>
\ No newline at end of file
<string name="new_profile_title" type="id">New profile</string>
<string name="delete_profile">Delete profile</string>
<string name="delete">Delete</string>
+ <string-array name="month_names">
+ <item>January</item>
+ <item>February</item>
+ <item>Match</item>
+ <item>April</item>
+ <item>May</item>
+ <item>June</item>
+ <item>July</item>
+ <item>August</item>
+ <item>September</item>
+ <item>October</item>
+ <item>November</item>
+ <item>December</item>
+ </string-array>
</resources>