Add edit/delete functions
This commit is contained in:
parent
36ed88a54c
commit
92f5ffbd69
23 changed files with 286 additions and 111 deletions
|
@ -34,6 +34,7 @@ dependencies {
|
||||||
implementation 'com.android.support:appcompat-v7:27.1.1'
|
implementation 'com.android.support:appcompat-v7:27.1.1'
|
||||||
implementation 'com.android.support.constraint:constraint-layout:1.1.2'
|
implementation 'com.android.support.constraint:constraint-layout:1.1.2'
|
||||||
implementation 'com.android.support:design:27.1.1'
|
implementation 'com.android.support:design:27.1.1'
|
||||||
|
implementation "com.android.support:support-emoji-bundled:27.1.1"
|
||||||
def room_version = "1.1.1"
|
def room_version = "1.1.1"
|
||||||
def lifecycle_version = "1.1.1"
|
def lifecycle_version = "1.1.1"
|
||||||
// ViewModel and LiveData
|
// ViewModel and LiveData
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
android:supportsRtl="true"
|
android:supportsRtl="true"
|
||||||
android:theme="@style/AppTheme">
|
android:theme="@style/AppTheme">
|
||||||
<activity android:name=".transactions.TransactionListActivity">
|
<activity android:name=".transactions.TransactionListActivity">
|
||||||
<intent-filter>
|
<intent-filter android:label="@string/app_name_short">
|
||||||
<action android:name="android.intent.action.MAIN" />
|
<action android:name="android.intent.action.MAIN" />
|
||||||
|
|
||||||
<category android:name="android.intent.category.LAUNCHER" />
|
<category android:name="android.intent.category.LAUNCHER" />
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
package com.wbrawner.myallowance.addedittransaction
|
package com.wbrawner.myallowance.addedittransaction
|
||||||
|
|
||||||
|
import android.arch.lifecycle.Observer
|
||||||
import android.arch.lifecycle.ViewModelProviders
|
import android.arch.lifecycle.ViewModelProviders
|
||||||
import android.support.v7.app.AppCompatActivity
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
|
import android.support.v7.app.AppCompatActivity
|
||||||
import android.view.Menu
|
import android.view.Menu
|
||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
import com.wbrawner.myallowance.R
|
import com.wbrawner.myallowance.R
|
||||||
|
@ -15,20 +16,54 @@ import java.util.*
|
||||||
class AddEditTransactionActivity : AppCompatActivity() {
|
class AddEditTransactionActivity : AppCompatActivity() {
|
||||||
lateinit var viewModel: TransactionViewModel
|
lateinit var viewModel: TransactionViewModel
|
||||||
lateinit var type: TransactionType
|
lateinit var type: TransactionType
|
||||||
|
var id: Int? = null
|
||||||
var date: Date = Date()
|
var date: Date = Date()
|
||||||
|
var menu: Menu? = null
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
setContentView(R.layout.activity_add_edit_transaction)
|
setContentView(R.layout.activity_add_edit_transaction)
|
||||||
|
setSupportActionBar(action_bar)
|
||||||
supportActionBar?.setDisplayHomeAsUpEnabled(true)
|
supportActionBar?.setDisplayHomeAsUpEnabled(true)
|
||||||
viewModel = ViewModelProviders.of(this).get(TransactionViewModel::class.java)
|
viewModel = ViewModelProviders.of(this).get(TransactionViewModel::class.java)
|
||||||
type = TransactionType.valueOf(intent?.extras?.getString(EXTRA_TYPE, "EXPENSE")?: "EXPENSE")
|
if (intent?.hasExtra(EXTRA_TYPE) == true) {
|
||||||
setTitle(type.addTitle)
|
type = TransactionType.valueOf(intent?.extras?.getString(EXTRA_TYPE, "EXPENSE")
|
||||||
|
?: "EXPENSE")
|
||||||
|
setTitle(type.addTitle)
|
||||||
|
return
|
||||||
|
} else if (intent?.hasExtra(EXTRA_TRANSACTION_ID) != true) {
|
||||||
|
finish()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
viewModel.getTransaction(intent!!.extras!!.getInt(EXTRA_TRANSACTION_ID))
|
||||||
|
.observe(this, Observer<Transaction> { transaction ->
|
||||||
|
if (transaction == null) {
|
||||||
|
menu?.findItem(R.id.action_delete)?.isVisible = false
|
||||||
|
return@Observer
|
||||||
|
}
|
||||||
|
id = transaction.id
|
||||||
|
type = transaction.type
|
||||||
|
setTitle(type.editTitle)
|
||||||
|
menu?.findItem(R.id.action_delete)?.isVisible = true
|
||||||
|
edit_transaction_title.setText(transaction.title)
|
||||||
|
edit_transaction_description.setText(transaction.description)
|
||||||
|
edit_transaction_amount.setText(String.format("%.02f", transaction.amount))
|
||||||
|
val field = Calendar.getInstance()
|
||||||
|
field.time = transaction.date
|
||||||
|
val year = field.get(Calendar.YEAR)
|
||||||
|
val month = field.get(Calendar.MONTH)
|
||||||
|
val day = field.get(Calendar.DAY_OF_MONTH)
|
||||||
|
edit_transaction_date.updateDate(year, month, day)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
|
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
|
||||||
menuInflater.inflate(R.menu.menu_add_edit, menu)
|
menuInflater.inflate(R.menu.menu_add_edit, menu)
|
||||||
|
if (id != null) {
|
||||||
|
menu?.findItem(R.id.action_delete)?.isVisible = true
|
||||||
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,7 +76,7 @@ class AddEditTransactionActivity : AppCompatActivity() {
|
||||||
cal.set(field.year, field.month, field.dayOfMonth)
|
cal.set(field.year, field.month, field.dayOfMonth)
|
||||||
|
|
||||||
viewModel.saveTransaction(Transaction(
|
viewModel.saveTransaction(Transaction(
|
||||||
id = null,
|
id = id,
|
||||||
title = edit_transaction_title.text.toString(),
|
title = edit_transaction_title.text.toString(),
|
||||||
date = cal.time,
|
date = cal.time,
|
||||||
description = edit_transaction_description.text.toString(),
|
description = edit_transaction_description.text.toString(),
|
||||||
|
@ -50,6 +85,10 @@ class AddEditTransactionActivity : AppCompatActivity() {
|
||||||
))
|
))
|
||||||
finish()
|
finish()
|
||||||
}
|
}
|
||||||
|
R.id.action_delete -> {
|
||||||
|
viewModel.deleteTransactionById(this@AddEditTransactionActivity.id!!)
|
||||||
|
finish()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +0,0 @@
|
||||||
package com.wbrawner.myallowance.addedittransaction
|
|
||||||
|
|
||||||
import android.content.Context
|
|
||||||
import android.support.v7.app.AlertDialog
|
|
||||||
|
|
||||||
class AddEditTransactionDialog(context: Context) : AlertDialog(context) {
|
|
||||||
|
|
||||||
}
|
|
|
@ -2,6 +2,7 @@ package com.wbrawner.myallowance.data
|
||||||
|
|
||||||
import android.arch.lifecycle.LiveData
|
import android.arch.lifecycle.LiveData
|
||||||
import android.arch.persistence.room.Dao
|
import android.arch.persistence.room.Dao
|
||||||
|
import android.arch.persistence.room.Delete
|
||||||
import android.arch.persistence.room.Insert
|
import android.arch.persistence.room.Insert
|
||||||
import android.arch.persistence.room.OnConflictStrategy.REPLACE
|
import android.arch.persistence.room.OnConflictStrategy.REPLACE
|
||||||
import android.arch.persistence.room.Query
|
import android.arch.persistence.room.Query
|
||||||
|
@ -22,4 +23,10 @@ interface TransactionDao {
|
||||||
|
|
||||||
@Query("SELECT (SELECT TOTAL(amount) from `Transaction` WHERE type = 'INCOME') - (SELECT TOTAL(amount) from `Transaction` WHERE type = 'EXPENSE')")
|
@Query("SELECT (SELECT TOTAL(amount) from `Transaction` WHERE type = 'INCOME') - (SELECT TOTAL(amount) from `Transaction` WHERE type = 'EXPENSE')")
|
||||||
fun getBalance(): LiveData<Double>
|
fun getBalance(): LiveData<Double>
|
||||||
|
|
||||||
|
@Delete
|
||||||
|
fun delete(transaction: Transaction)
|
||||||
|
|
||||||
|
@Query("DELETE FROM `Transaction` WHERE id = :id")
|
||||||
|
fun deleteById(id: Int)
|
||||||
}
|
}
|
|
@ -1,10 +1,8 @@
|
||||||
package com.wbrawner.myallowance.data
|
package com.wbrawner.myallowance.data
|
||||||
|
|
||||||
import android.arch.lifecycle.LiveData
|
import android.arch.lifecycle.LiveData
|
||||||
import android.arch.lifecycle.MutableLiveData
|
|
||||||
import android.os.Handler
|
import android.os.Handler
|
||||||
import android.os.HandlerThread
|
import android.os.HandlerThread
|
||||||
import java.util.*
|
|
||||||
|
|
||||||
class TransactionRepository(val dao: TransactionDao) {
|
class TransactionRepository(val dao: TransactionDao) {
|
||||||
val handler: Handler
|
val handler: Handler
|
||||||
|
@ -53,5 +51,15 @@ class TransactionRepository(val dao: TransactionDao) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fun delete(transaction: Transaction) {
|
||||||
|
handler.post { dao.delete(transaction) }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fun deleteById(id: Int) {
|
||||||
|
handler.post { dao.deleteById(id) }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
fun getCurrentBalance(): LiveData<Double> = dao.getBalance()
|
fun getCurrentBalance(): LiveData<Double> = dao.getBalance()
|
||||||
}
|
}
|
|
@ -1,10 +1,29 @@
|
||||||
package com.wbrawner.myallowance.data
|
package com.wbrawner.myallowance.data
|
||||||
|
|
||||||
|
import android.support.annotation.ColorRes
|
||||||
import android.support.annotation.StringRes
|
import android.support.annotation.StringRes
|
||||||
import com.wbrawner.myallowance.R
|
import com.wbrawner.myallowance.R
|
||||||
import java.io.Serializable
|
import java.io.Serializable
|
||||||
|
|
||||||
enum class TransactionType(@StringRes val title: Int, @StringRes val addTitle: Int) : Serializable {
|
enum class TransactionType(
|
||||||
INCOME(R.string.title_income, R.string.title_add_income),
|
@StringRes val title: Int,
|
||||||
EXPENSE(R.string.title_expenses, R.string.title_add_expense);
|
@StringRes val addTitle: Int,
|
||||||
|
@StringRes val editTitle: Int,
|
||||||
|
@StringRes val noDataText: Int,
|
||||||
|
@ColorRes val textColor: Int
|
||||||
|
) : Serializable {
|
||||||
|
INCOME(
|
||||||
|
R.string.title_income,
|
||||||
|
R.string.title_add_income,
|
||||||
|
R.string.title_edit_income,
|
||||||
|
R.string.income_no_data,
|
||||||
|
R.color.colorTextGreen
|
||||||
|
),
|
||||||
|
EXPENSE(
|
||||||
|
R.string.title_expenses,
|
||||||
|
R.string.title_add_expense,
|
||||||
|
R.string.title_edit_expense,
|
||||||
|
R.string.expenses_no_data,
|
||||||
|
R.color.colorTextRed
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,6 +62,6 @@ class OverviewFragment : Fragment() {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val TAG_FRAGMENT = "overview"
|
const val TAG_FRAGMENT = "overview"
|
||||||
const val TITLE_FRAGMENT = R.string.title_dashboard
|
const val TITLE_FRAGMENT = R.string.app_name
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,12 +1,17 @@
|
||||||
package com.wbrawner.myallowance.transactions
|
package com.wbrawner.myallowance.transactions
|
||||||
|
|
||||||
|
import android.content.Intent
|
||||||
|
import android.support.v4.content.ContextCompat.startActivity
|
||||||
import android.support.v7.widget.RecyclerView
|
import android.support.v7.widget.RecyclerView
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
import com.wbrawner.myallowance.R
|
import com.wbrawner.myallowance.R
|
||||||
|
import com.wbrawner.myallowance.addedittransaction.AddEditTransactionActivity
|
||||||
|
import com.wbrawner.myallowance.addedittransaction.AddEditTransactionActivity.Companion.EXTRA_TRANSACTION_ID
|
||||||
import com.wbrawner.myallowance.data.Transaction
|
import com.wbrawner.myallowance.data.Transaction
|
||||||
|
import java.text.SimpleDateFormat
|
||||||
|
|
||||||
class TransactionAdapter(private val data: List<Transaction>)
|
class TransactionAdapter(private val data: List<Transaction>)
|
||||||
: RecyclerView.Adapter<TransactionAdapter.ViewHolder>() {
|
: RecyclerView.Adapter<TransactionAdapter.ViewHolder>() {
|
||||||
|
@ -21,11 +26,27 @@ class TransactionAdapter(private val data: List<Transaction>)
|
||||||
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
||||||
val transaction = data[position]
|
val transaction = data[position]
|
||||||
holder.title.text = transaction.title
|
holder.title.text = transaction.title
|
||||||
|
holder.date.text = SimpleDateFormat.getDateInstance(SimpleDateFormat.SHORT).format(transaction.date)
|
||||||
holder.amount.text = String.format("${'$'}%.02f", transaction.amount)
|
holder.amount.text = String.format("${'$'}%.02f", transaction.amount)
|
||||||
|
val context = holder.itemView.context
|
||||||
|
holder.amount.setTextColor(
|
||||||
|
context.resources.getColor(transaction.type.textColor, context.theme)
|
||||||
|
)
|
||||||
|
holder.itemView.setOnClickListener {
|
||||||
|
startActivity(
|
||||||
|
it.context.applicationContext,
|
||||||
|
Intent(it.context.applicationContext, AddEditTransactionActivity::class.java)
|
||||||
|
.apply {
|
||||||
|
putExtra(EXTRA_TRANSACTION_ID, transaction.id)
|
||||||
|
},
|
||||||
|
null
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inner class ViewHolder(itemView: View): RecyclerView.ViewHolder(itemView) {
|
inner class ViewHolder(itemView: View): RecyclerView.ViewHolder(itemView) {
|
||||||
val title = itemView.findViewById<TextView>(R.id.transaction_title)
|
val title = itemView.findViewById<TextView>(R.id.transaction_title)
|
||||||
|
val date = itemView.findViewById<TextView>(R.id.transaction_date)
|
||||||
val amount = itemView.findViewById<TextView>(R.id.transaction_amount)
|
val amount = itemView.findViewById<TextView>(R.id.transaction_amount)
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,8 +1,10 @@
|
||||||
package com.wbrawner.myallowance.transactions
|
package com.wbrawner.myallowance.transactions
|
||||||
|
|
||||||
import android.support.v7.app.AppCompatActivity
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.support.annotation.StringRes
|
import android.support.annotation.StringRes
|
||||||
|
import android.support.text.emoji.EmojiCompat
|
||||||
|
import android.support.text.emoji.bundled.BundledEmojiCompatConfig
|
||||||
|
import android.support.v7.app.AppCompatActivity
|
||||||
import com.wbrawner.myallowance.R
|
import com.wbrawner.myallowance.R
|
||||||
import com.wbrawner.myallowance.data.TransactionType
|
import com.wbrawner.myallowance.data.TransactionType
|
||||||
import com.wbrawner.myallowance.overview.OverviewFragment
|
import com.wbrawner.myallowance.overview.OverviewFragment
|
||||||
|
@ -11,7 +13,9 @@ import kotlinx.android.synthetic.main.activity_transaction_list.*
|
||||||
class TransactionListActivity : AppCompatActivity() {
|
class TransactionListActivity : AppCompatActivity() {
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
EmojiCompat.init(BundledEmojiCompatConfig(this))
|
||||||
setContentView(R.layout.activity_transaction_list)
|
setContentView(R.layout.activity_transaction_list)
|
||||||
|
setSupportActionBar(action_bar)
|
||||||
|
|
||||||
menu_main.setOnNavigationItemSelectedListener { item ->
|
menu_main.setOnNavigationItemSelectedListener { item ->
|
||||||
when (item.itemId) {
|
when (item.itemId) {
|
||||||
|
|
|
@ -4,8 +4,8 @@ import android.arch.lifecycle.Observer
|
||||||
import android.arch.lifecycle.ViewModelProviders
|
import android.arch.lifecycle.ViewModelProviders
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.support.annotation.StringRes
|
|
||||||
import android.support.design.widget.FloatingActionButton
|
import android.support.design.widget.FloatingActionButton
|
||||||
|
import android.support.text.emoji.widget.EmojiTextView
|
||||||
import android.support.v4.app.Fragment
|
import android.support.v4.app.Fragment
|
||||||
import android.support.v7.widget.LinearLayoutManager
|
import android.support.v7.widget.LinearLayoutManager
|
||||||
import android.support.v7.widget.RecyclerView
|
import android.support.v7.widget.RecyclerView
|
||||||
|
@ -17,7 +17,6 @@ import com.wbrawner.myallowance.addedittransaction.AddEditTransactionActivity
|
||||||
import com.wbrawner.myallowance.addedittransaction.AddEditTransactionActivity.Companion.EXTRA_TYPE
|
import com.wbrawner.myallowance.addedittransaction.AddEditTransactionActivity.Companion.EXTRA_TYPE
|
||||||
import com.wbrawner.myallowance.data.Transaction
|
import com.wbrawner.myallowance.data.Transaction
|
||||||
import com.wbrawner.myallowance.data.TransactionType
|
import com.wbrawner.myallowance.data.TransactionType
|
||||||
import java.io.Serializable
|
|
||||||
|
|
||||||
class TransactionListFragment : Fragment() {
|
class TransactionListFragment : Fragment() {
|
||||||
lateinit var viewModel: TransactionViewModel
|
lateinit var viewModel: TransactionViewModel
|
||||||
|
@ -41,16 +40,28 @@ class TransactionListFragment : Fragment() {
|
||||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||||
val view = inflater.inflate(R.layout.fragment_transaction_list, container, false)
|
val view = inflater.inflate(R.layout.fragment_transaction_list, container, false)
|
||||||
val recyclerView = view.findViewById<RecyclerView>(R.id.list_transactions)
|
val recyclerView = view.findViewById<RecyclerView>(R.id.list_transactions)
|
||||||
|
val fab = view.findViewById<FloatingActionButton>(R.id.fab_add_transaction)
|
||||||
recyclerView.layoutManager = LinearLayoutManager(activity)
|
recyclerView.layoutManager = LinearLayoutManager(activity)
|
||||||
viewModel.getTransactionsByType(20, type)
|
viewModel.getTransactionsByType(20, type)
|
||||||
.observe(this, Observer<List<Transaction>> { data ->
|
.observe(this, Observer<List<Transaction>> { data ->
|
||||||
if (data == null) {
|
val noDataView = view.findViewById<EmojiTextView>(R.id.transaction_list_no_data)
|
||||||
|
if (data == null || data.isEmpty()) {
|
||||||
recyclerView.adapter = null
|
recyclerView.adapter = null
|
||||||
|
noDataView?.setText(type.noDataText)
|
||||||
|
recyclerView?.visibility = View.GONE
|
||||||
|
noDataView?.visibility = View.VISIBLE
|
||||||
} else {
|
} else {
|
||||||
recyclerView.adapter = TransactionAdapter(data)
|
recyclerView.adapter = TransactionAdapter(data)
|
||||||
|
recyclerView.visibility = View.VISIBLE
|
||||||
|
noDataView.visibility = View.GONE
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
view.findViewById<FloatingActionButton>(R.id.fab_add_transaction).setOnClickListener {
|
recyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {
|
||||||
|
override fun onScrolled(recyclerView: RecyclerView?, dx: Int, dy: Int) {
|
||||||
|
if (dy > 0) fab.hide() else fab.show()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
fab.setOnClickListener {
|
||||||
startActivity(
|
startActivity(
|
||||||
Intent(activity, AddEditTransactionActivity::class.java).apply {
|
Intent(activity, AddEditTransactionActivity::class.java).apply {
|
||||||
this.putExtra(EXTRA_TYPE, this@TransactionListFragment.type.name)
|
this.putExtra(EXTRA_TYPE, this@TransactionListFragment.type.name)
|
||||||
|
|
|
@ -21,4 +21,8 @@ class TransactionViewModel(application: Application): AndroidViewModel(applicati
|
||||||
fun getCurrentBalance(): LiveData<Double> = transactionRepo.getCurrentBalance()
|
fun getCurrentBalance(): LiveData<Double> = transactionRepo.getCurrentBalance()
|
||||||
|
|
||||||
fun saveTransaction(transaction: Transaction) = transactionRepo.save(transaction)
|
fun saveTransaction(transaction: Transaction) = transactionRepo.save(transaction)
|
||||||
|
|
||||||
|
fun deleteTransaction(transaction: Transaction) = transactionRepo.delete(transaction)
|
||||||
|
|
||||||
|
fun deleteTransactionById(id: Int) = transactionRepo.deleteById(id)
|
||||||
}
|
}
|
|
@ -4,6 +4,6 @@
|
||||||
android:viewportWidth="24.0"
|
android:viewportWidth="24.0"
|
||||||
android:viewportHeight="24.0">
|
android:viewportHeight="24.0">
|
||||||
<path
|
<path
|
||||||
android:fillColor="#FFFFFFFF"
|
android:fillColor="@color/colorTextPrimary"
|
||||||
android:pathData="M17,3L5,3c-1.11,0 -2,0.9 -2,2v14c0,1.1 0.89,2 2,2h14c1.1,0 2,-0.9 2,-2L21,7l-4,-4zM12,19c-1.66,0 -3,-1.34 -3,-3s1.34,-3 3,-3 3,1.34 3,3 -1.34,3 -3,3zM15,9L5,9L5,5h10v4z"/>
|
android:pathData="M17,3L5,3c-1.11,0 -2,0.9 -2,2v14c0,1.1 0.89,2 2,2h14c1.1,0 2,-0.9 2,-2L21,7l-4,-4zM12,19c-1.66,0 -3,-1.34 -3,-3s1.34,-3 3,-3 3,1.34 3,3 -1.34,3 -3,3zM15,9L5,9L5,5h10v4z"/>
|
||||||
</vector>
|
</vector>
|
||||||
|
|
|
@ -1,79 +1,97 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent">
|
||||||
tools:context=".addedittransaction.AddEditTransactionActivity">
|
|
||||||
|
|
||||||
<android.support.constraint.ConstraintLayout
|
<android.support.v7.widget.Toolbar
|
||||||
|
android:id="@+id/action_bar"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="?attr/actionBarSize"
|
||||||
android:padding="16dp">
|
android:elevation="4dp"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
<android.support.design.widget.TextInputLayout
|
<ScrollView
|
||||||
android:id="@+id/container_edit_transaction_title"
|
android:id="@+id/scrollView2"
|
||||||
style="@style/AppTheme.EditText.Container"
|
android:layout_width="match_parent"
|
||||||
android:hint="@string/prompt_transaction_title"
|
android:layout_height="0dp"
|
||||||
app:layout_constraintBottom_toTopOf="@+id/container_edit_transaction_description"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="parent">
|
app:layout_constraintTop_toBottomOf="@+id/action_bar">
|
||||||
|
|
||||||
<android.support.design.widget.TextInputEditText
|
<android.support.constraint.ConstraintLayout
|
||||||
android:id="@+id/edit_transaction_title"
|
|
||||||
android:inputType="textCapWords"
|
|
||||||
style="@style/AppTheme.EditText" />
|
|
||||||
</android.support.design.widget.TextInputLayout>
|
|
||||||
|
|
||||||
<android.support.design.widget.TextInputLayout
|
|
||||||
android:id="@+id/container_edit_transaction_description"
|
|
||||||
style="@style/AppTheme.EditText.Container"
|
|
||||||
android:hint="@string/prompt_transaction_description"
|
|
||||||
android:inputType="textCapSentences"
|
|
||||||
app:layout_constraintBottom_toTopOf="@+id/container_edit_transaction_amount"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toBottomOf="@+id/container_edit_transaction_title">
|
|
||||||
|
|
||||||
<android.support.design.widget.TextInputEditText
|
|
||||||
android:id="@+id/edit_transaction_description"
|
|
||||||
style="@style/AppTheme.EditText" />
|
|
||||||
</android.support.design.widget.TextInputLayout>
|
|
||||||
|
|
||||||
<android.support.design.widget.TextInputLayout
|
|
||||||
android:id="@+id/container_edit_transaction_amount"
|
|
||||||
style="@style/AppTheme.EditText.Container"
|
|
||||||
android:hint="@string/prompt_transaction_amount"
|
|
||||||
app:layout_constraintBottom_toTopOf="@+id/container_edit_transaction_date"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toBottomOf="@+id/container_edit_transaction_description">
|
|
||||||
|
|
||||||
<android.support.design.widget.TextInputEditText
|
|
||||||
android:id="@+id/edit_transaction_amount"
|
|
||||||
style="@style/AppTheme.EditText"
|
|
||||||
android:inputType="numberDecimal" />
|
|
||||||
</android.support.design.widget.TextInputLayout>
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/container_edit_transaction_date"
|
|
||||||
style="@style/AppTheme.EditText.Hint"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="4dp"
|
android:padding="16dp">
|
||||||
android:text="@string/prompt_transaction_date"
|
|
||||||
app:layout_constraintBottom_toTopOf="@+id/edit_transaction_date"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toBottomOf="@+id/container_edit_transaction_amount" />
|
|
||||||
|
|
||||||
<DatePicker
|
<android.support.design.widget.TextInputLayout
|
||||||
android:id="@+id/edit_transaction_date"
|
android:id="@+id/container_edit_transaction_title"
|
||||||
style="@style/AppTheme.DatePicker"
|
style="@style/AppTheme.EditText.Container"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
android:hint="@string/prompt_transaction_title"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintBottom_toTopOf="@+id/container_edit_transaction_description"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/container_edit_transaction_date" />
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
</android.support.constraint.ConstraintLayout>
|
app:layout_constraintTop_toTopOf="parent">
|
||||||
</ScrollView>
|
|
||||||
|
<android.support.design.widget.TextInputEditText
|
||||||
|
android:id="@+id/edit_transaction_title"
|
||||||
|
style="@style/AppTheme.EditText"
|
||||||
|
android:inputType="textCapWords" />
|
||||||
|
</android.support.design.widget.TextInputLayout>
|
||||||
|
|
||||||
|
<android.support.design.widget.TextInputLayout
|
||||||
|
android:id="@+id/container_edit_transaction_description"
|
||||||
|
style="@style/AppTheme.EditText.Container"
|
||||||
|
android:hint="@string/prompt_transaction_description"
|
||||||
|
app:layout_constraintBottom_toTopOf="@+id/container_edit_transaction_amount"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/container_edit_transaction_title">
|
||||||
|
|
||||||
|
<android.support.design.widget.TextInputEditText
|
||||||
|
android:id="@+id/edit_transaction_description"
|
||||||
|
style="@style/AppTheme.EditText"
|
||||||
|
android:inputType="textCapSentences|textMultiLine"
|
||||||
|
android:scrollHorizontally="false" />
|
||||||
|
</android.support.design.widget.TextInputLayout>
|
||||||
|
|
||||||
|
<android.support.design.widget.TextInputLayout
|
||||||
|
android:id="@+id/container_edit_transaction_amount"
|
||||||
|
style="@style/AppTheme.EditText.Container"
|
||||||
|
android:hint="@string/prompt_transaction_amount"
|
||||||
|
app:layout_constraintBottom_toTopOf="@+id/container_edit_transaction_date"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/container_edit_transaction_description">
|
||||||
|
|
||||||
|
<android.support.design.widget.TextInputEditText
|
||||||
|
android:id="@+id/edit_transaction_amount"
|
||||||
|
style="@style/AppTheme.EditText"
|
||||||
|
android:inputType="numberDecimal" />
|
||||||
|
</android.support.design.widget.TextInputLayout>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/container_edit_transaction_date"
|
||||||
|
style="@style/AppTheme.EditText.Hint"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="4dp"
|
||||||
|
android:text="@string/prompt_transaction_date"
|
||||||
|
app:layout_constraintBottom_toTopOf="@+id/edit_transaction_date"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/container_edit_transaction_amount" />
|
||||||
|
|
||||||
|
<DatePicker
|
||||||
|
android:id="@+id/edit_transaction_date"
|
||||||
|
style="@style/AppTheme.DatePicker"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/container_edit_transaction_date" />
|
||||||
|
</android.support.constraint.ConstraintLayout>
|
||||||
|
</ScrollView>
|
||||||
|
</android.support.constraint.ConstraintLayout>
|
||||||
|
|
|
@ -6,11 +6,20 @@
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
tools:context=".transactions.TransactionListActivity">
|
tools:context=".transactions.TransactionListActivity">
|
||||||
|
|
||||||
|
<android.support.v7.widget.Toolbar
|
||||||
|
android:id="@+id/action_bar"
|
||||||
|
android:elevation="4dp"
|
||||||
|
app:layout_constraintLeft_toLeftOf="parent"
|
||||||
|
app:layout_constraintRight_toRightOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="?attr/actionBarSize" />
|
||||||
|
|
||||||
<FrameLayout
|
<FrameLayout
|
||||||
android:id="@+id/content_container"
|
android:id="@+id/content_container"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="0dp"
|
android:layout_height="0dp"
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
app:layout_constraintTop_toBottomOf="@+id/action_bar"
|
||||||
app:layout_constraintBottom_toTopOf="@+id/menu_main"
|
app:layout_constraintBottom_toTopOf="@+id/menu_main"
|
||||||
app:layout_constraintLeft_toLeftOf="parent"
|
app:layout_constraintLeft_toLeftOf="parent"
|
||||||
app:layout_constraintRight_toRightOf="parent" />
|
app:layout_constraintRight_toRightOf="parent" />
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
@ -28,7 +27,7 @@
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/overview_current_balance_label" />
|
app:layout_constraintTop_toBottomOf="@+id/overview_current_balance_label" />
|
||||||
|
|
||||||
<TextView
|
<android.support.text.emoji.widget.EmojiTextView
|
||||||
android:id="@+id/overview_no_data"
|
android:id="@+id/overview_no_data"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
|
|
@ -9,7 +9,18 @@
|
||||||
android:id="@+id/list_transactions"
|
android:id="@+id/list_transactions"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="center_horizontal"/>
|
android:layout_gravity="fill_vertical|center_horizontal" />
|
||||||
|
|
||||||
|
<android.support.text.emoji.widget.EmojiTextView
|
||||||
|
android:id="@+id/transaction_list_no_data"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_margin="8dp"
|
||||||
|
android:textAlignment="center"
|
||||||
|
android:textSize="24sp"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:textColor="@color/colorTextPrimary"
|
||||||
|
android:visibility="gone" />
|
||||||
|
|
||||||
<android.support.design.widget.FloatingActionButton
|
<android.support.design.widget.FloatingActionButton
|
||||||
android:id="@+id/fab_add_transaction"
|
android:id="@+id/fab_add_transaction"
|
||||||
|
|
|
@ -1,28 +1,47 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<android.support.constraint.ConstraintLayout
|
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="?android:attr/listPreferredItemHeight"
|
android:layout_height="wrap_content"
|
||||||
android:padding="8dp">
|
android:padding="16dp">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/transaction_title"
|
android:id="@+id/transaction_title"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
android:textColor="@color/colorTextPrimary"
|
||||||
app:layout_constraintEnd_toStartOf="@+id/transaction_amount"
|
android:textSize="18sp"
|
||||||
app:layout_constraintHorizontal_chainStyle="spread_inside"
|
app:layout_constraintHorizontal_bias="0"
|
||||||
|
app:layout_constraintVertical_chainStyle="packed"
|
||||||
|
app:layout_constraintBottom_toTopOf="@+id/transaction_date"
|
||||||
|
app:layout_constraintEnd_toStartOf="@+id/barrier"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/transaction_date"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:layout_constraintHorizontal_bias="0"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintVertical_chainStyle="packed"
|
||||||
|
app:layout_constraintEnd_toStartOf="@+id/transaction_amount"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/transaction_title" />
|
||||||
|
|
||||||
|
<android.support.constraint.Barrier
|
||||||
|
android:id="@+id/barrier"
|
||||||
|
app:barrierDirection="start"
|
||||||
|
app:constraint_referenced_ids="transaction_amount"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/transaction_amount"
|
android:id="@+id/transaction_amount"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:textSize="18sp"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toEndOf="@+id/transaction_title"
|
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
</android.support.constraint.ConstraintLayout>
|
</android.support.constraint.ConstraintLayout>
|
|
@ -6,4 +6,9 @@
|
||||||
android:icon="@drawable/ic_save_white_24dp"
|
android:icon="@drawable/ic_save_white_24dp"
|
||||||
app:showAsAction="ifRoom|withText"
|
app:showAsAction="ifRoom|withText"
|
||||||
android:title="@string/action_save" />
|
android:title="@string/action_save" />
|
||||||
|
<item
|
||||||
|
android:id="@+id/action_delete"
|
||||||
|
app:showAsAction="never"
|
||||||
|
android:visible="false"
|
||||||
|
android:title="@string/action_delete" />
|
||||||
</menu>
|
</menu>
|
|
@ -1,8 +1,8 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources>
|
<resources>
|
||||||
<color name="colorPrimary">#3F51B5</color>
|
<color name="colorPrimary">#3F51B5</color>
|
||||||
<color name="colorPrimaryDark">#303F9F</color>
|
<color name="colorPrimaryDark">#3F51B5</color>
|
||||||
<color name="colorAccent">#FF4081</color>
|
<color name="colorAccent">#3F51B5</color>
|
||||||
<color name="colorTextPrimary">#FF000000</color>
|
<color name="colorTextPrimary">#FF000000</color>
|
||||||
<color name="colorTextGreen">#388e3c</color>
|
<color name="colorTextGreen">#388e3c</color>
|
||||||
<color name="colorTextRed">#d32f2f</color>
|
<color name="colorTextRed">#d32f2f</color>
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
<resources>
|
<resources>
|
||||||
<string name="app_name">My Allowance</string>
|
<string name="app_name">My Allowance</string>
|
||||||
|
<string name="app_name_short">Allowance</string>
|
||||||
<string name="prompt_transaction_title">Title</string>
|
<string name="prompt_transaction_title">Title</string>
|
||||||
<string name="title_add_income">Add Income</string>
|
<string name="title_add_income">Add Income</string>
|
||||||
<string name="title_add_expense">Add Expense</string>
|
<string name="title_add_expense">Add Expense</string>
|
||||||
|
@ -11,6 +12,11 @@
|
||||||
<string name="title_income">Income</string>
|
<string name="title_income">Income</string>
|
||||||
<string name="title_dashboard">Dashboard</string>
|
<string name="title_dashboard">Dashboard</string>
|
||||||
<string name="label_current_balance">Current Balance</string>
|
<string name="label_current_balance">Current Balance</string>
|
||||||
<string name="overview_no_data">Add some transactions to see an overview of your spending here</string>
|
<string name="overview_no_data">📈\nAdd some transactions to see an overview of your spending here</string>
|
||||||
<string name="action_save">Save</string>
|
<string name="action_save">Save</string>
|
||||||
|
<string name="action_delete">Delete</string>
|
||||||
|
<string name="title_edit_income">Edit Income</string>
|
||||||
|
<string name="title_edit_expense">Edit Expense</string>
|
||||||
|
<string name="income_no_data">🌳\nGet to work! Money doesn\'t grow on trees after all</string>
|
||||||
|
<string name="expenses_no_data">🤔\nAre you sure you haven\'t spent any money?</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -1,11 +1,13 @@
|
||||||
<resources>
|
<resources>
|
||||||
|
|
||||||
<!-- Base application theme. -->
|
<!-- Base application theme. -->
|
||||||
<style name="BaseTheme" parent="Theme.AppCompat.Light.DarkActionBar">
|
<style name="BaseTheme" parent="Theme.AppCompat.Light.NoActionBar">
|
||||||
<!-- Customize your theme here. -->
|
<!-- Customize your theme here. -->
|
||||||
<item name="colorPrimary">@color/colorPrimary</item>
|
<item name="colorPrimary">@color/colorPrimary</item>
|
||||||
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
|
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
|
||||||
<item name="colorAccent">@color/colorAccent</item>
|
<item name="colorAccent">@color/colorAccent</item>
|
||||||
|
<item name="android:windowLightStatusBar">true</item>
|
||||||
|
<item name="android:statusBarColor">?android:attr/windowBackground</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style name="AppTheme" parent="BaseTheme" />
|
<style name="AppTheme" parent="BaseTheme" />
|
||||||
|
|
0
gradlew
vendored
Normal file → Executable file
0
gradlew
vendored
Normal file → Executable file
Loading…
Reference in a new issue