Add edit/delete functions

This commit is contained in:
William Brawner 2018-08-02 08:28:32 -05:00
parent 36ed88a54c
commit 92f5ffbd69
23 changed files with 286 additions and 111 deletions

View file

@ -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

View file

@ -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" />

View file

@ -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
} }

View file

@ -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) {
}

View file

@ -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)
} }

View file

@ -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()
} }

View file

@ -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
);
} }

View file

@ -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
} }
} }

View file

@ -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)
} }
} }

View file

@ -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) {

View file

@ -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)

View file

@ -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)
} }

View file

@ -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>

View file

@ -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>

View file

@ -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" />

View file

@ -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"

View file

@ -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"

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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">&#x1F4C8;\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">&#x1F333;\nGet to work! Money doesn\'t grow on trees after all</string>
<string name="expenses_no_data">&#x1F914;\nAre you sure you haven\'t spent any money?</string>
</resources> </resources>

View file

@ -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
View file