- Create basic TransactionsAdapter to populate the Transactions RecyclerView in Balances.

- Create basic Transactions items layout.
This commit is contained in:
Severiano Jaramillo 2018-11-28 20:13:40 -06:00
parent bebffa14ed
commit 51363bdf00
10 changed files with 371 additions and 11 deletions

View file

@ -17,7 +17,7 @@ import cy.agorise.graphenej.models.JsonRpcResponse
import kotlinx.android.synthetic.main.activity_main.*
class MainActivity : ConnectedActivity() {
private val TAG = this.javaClass.name
private val TAG = this.javaClass.simpleName
private val mOnNavigationItemSelectedListener = BottomNavigationView.OnNavigationItemSelectedListener { item ->
when (item.itemId) {

View file

@ -0,0 +1,118 @@
package cy.agorise.bitsybitshareswallet.adapters
import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.TextView
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.SortedList
import cy.agorise.bitsybitshareswallet.R
import cy.agorise.bitsybitshareswallet.entities.Transfer
class TransactionsAdapter(private val context: Context, private val mComparator: Comparator<Transfer>) :
RecyclerView.Adapter<TransactionsAdapter.ViewHolder>() {
private val mSortedList =
SortedList<Transfer>(Transfer::class.java, object : SortedList.Callback<Transfer>() {
override fun onInserted(position: Int, count: Int) {
notifyItemRangeInserted(position, count)
}
override fun onRemoved(position: Int, count: Int) {
notifyItemRangeRemoved(position, count)
}
override fun onMoved(fromPosition: Int, toPosition: Int) {
notifyItemMoved(fromPosition, toPosition)
}
override fun onChanged(position: Int, count: Int) {
notifyItemRangeChanged(position, count)
}
override fun compare(a: Transfer, b: Transfer): Int {
return mComparator.compare(a, b)
}
override fun areContentsTheSame(oldItem: Transfer, newItem: Transfer): Boolean {
return oldItem == newItem
}
override fun areItemsTheSame(item1: Transfer, item2: Transfer): Boolean {
return item1.id == item2.id
}
})
inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
val rootView = itemView.findViewById<ConstraintLayout>(R.id.rootView)
val vPaymentDirection = itemView.findViewById<View>(R.id.vPaymentDirection)
val tvFrom = itemView.findViewById<TextView>(R.id.tvFrom)
val ivDirectionArrow = itemView.findViewById<ImageView>(R.id.ivDirectionArrow)
val tvTo = itemView.findViewById<TextView>(R.id.tvTo)
val llMemo = itemView.findViewById<LinearLayout>(R.id.llMemo)
val tvMemo = itemView.findViewById<TextView>(R.id.tvMemo)
val tvDate = itemView.findViewById<TextView>(R.id.tvDate)
val tvTime = itemView.findViewById<TextView>(R.id.tvTime)
val tvCryptoAmount = itemView.findViewById<TextView>(R.id.tvCryptoAmount)
val tvFiatEquivalent = itemView.findViewById<TextView>(R.id.tvFiatEquivalent)
}
init {
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TransactionsAdapter.ViewHolder {
val inflater = LayoutInflater.from(context)
val transactionView = inflater.inflate(R.layout.item_transaction, parent, false)
return ViewHolder(transactionView)
}
override fun onBindViewHolder(viewHolder: ViewHolder, position: Int) {
val transaction = mSortedList.get(position)
viewHolder.tvFrom.text = transaction.source
viewHolder.tvTo.text = transaction.destination
}
fun add(transaction: Transfer) {
mSortedList.add(transaction)
}
fun remove(transaction: Transfer) {
mSortedList.remove(transaction)
}
fun add(transactions: List<Transfer>) {
mSortedList.addAll(transactions)
}
fun remove(transactions: List<Transfer>) {
mSortedList.beginBatchedUpdates()
for (transaction in transactions) {
mSortedList.remove(transaction)
}
mSortedList.endBatchedUpdates()
}
fun replaceAll(transactions: List<Transfer>) {
mSortedList.beginBatchedUpdates()
for (i in mSortedList.size() - 1 downTo 0) {
val transaction = mSortedList.get(i)
if (!transactions.contains(transaction)) {
mSortedList.remove(transaction)
}
}
mSortedList.addAll(transactions)
mSortedList.endBatchedUpdates()
}
override fun getItemCount(): Int {
return mSortedList.size()
}
}

View file

@ -8,18 +8,27 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.lifecycle.Observer
import androidx.recyclerview.widget.LinearLayoutManager
import cy.agorise.bitsybitshareswallet.R
import cy.agorise.bitsybitshareswallet.adapters.TransactionsAdapter
import cy.agorise.bitsybitshareswallet.entities.Transfer
import cy.agorise.bitsybitshareswallet.entities.UserAccount
import cy.agorise.bitsybitshareswallet.utils.Constants
import cy.agorise.bitsybitshareswallet.viewmodels.BalancesViewModel
import cy.agorise.bitsybitshareswallet.viewmodels.TransactionViewModel
import cy.agorise.bitsybitshareswallet.viewmodels.UserAccountViewModel
import kotlinx.android.synthetic.main.fragment_balances.*
import java.util.Comparator
class BalancesFragment : Fragment() {
private lateinit var mUserAccountViewModel: UserAccountViewModel
private lateinit var mBalancesViewModel: BalancesViewModel
private lateinit var mTransactionViewModel: TransactionViewModel
private val mComparator =
Comparator<Transfer> { a, b -> a.id.compareTo(b.id) }
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
@ -44,5 +53,14 @@ class BalancesFragment : Fragment() {
mBalancesViewModel = ViewModelProviders.of(this).get(BalancesViewModel::class.java)
// TODO: Use the ViewModel
mTransactionViewModel = ViewModelProviders.of(this).get(TransactionViewModel::class.java)
val transactionsAdapter = TransactionsAdapter(context!!, mComparator)
rvTransactions.adapter = transactionsAdapter
rvTransactions.layoutManager = LinearLayoutManager(context)
mTransactionViewModel.getAll().observe(this, Observer<List<Transfer>> { transfers ->
transactionsAdapter.replaceAll(transfers)
})
}
}

View file

@ -51,7 +51,7 @@ import javax.crypto.AEADBadTagException
class TransfersLoader(private var mContext: Context?, private val mLifeCycle: Lifecycle) : LifecycleObserver,
ServiceConnection {
private val TAG = this.javaClass.name
private val TAG = this.javaClass.simpleName
/** Constant that specifies if we are on debug mode */
private val DEBUG = false

View file

@ -2,6 +2,7 @@ package cy.agorise.bitsybitshareswallet.repositories
import android.content.Context
import android.os.AsyncTask
import androidx.lifecycle.LiveData
import cy.agorise.bitsybitshareswallet.daos.BitsyDatabase
import cy.agorise.bitsybitshareswallet.daos.TransferDao
import cy.agorise.bitsybitshareswallet.entities.Transfer
@ -20,6 +21,10 @@ class TransferRepository internal constructor(context: Context) {
insertAllAsyncTask(mTransferDao).execute(transfers)
}
fun getAll(): LiveData<List<Transfer>> {
return mTransferDao.getAll()
}
fun getCount(): Single<Int> {
return mTransferDao.getCount()
}

View file

@ -0,0 +1,15 @@
package cy.agorise.bitsybitshareswallet.viewmodels
import android.app.Application
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.LiveData
import cy.agorise.bitsybitshareswallet.entities.Transfer
import cy.agorise.bitsybitshareswallet.repositories.TransferRepository
class TransactionViewModel(application: Application) : AndroidViewModel(application) {
private var mRepository = TransferRepository(application)
internal fun getAll(): LiveData<List<Transfer>> {
return mRepository.getAll()
}
}

View file

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="@color/colorReceive"
android:pathData="M12,4l-1.41,1.41L16.17,11H4v2h12.17l-5.58,5.59L12,20l8,-8z"/>
</vector>

View file

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="@color/colorSend"
android:pathData="M12,4l-1.41,1.41L16.17,11H4v2h12.17l-5.58,5.59L12,20l8,-8z"/>
</vector>

View file

@ -1,14 +1,195 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
<androidx.cardview.widget.CardView
xmlns:card_view="http://schemas.android.com/apk/res-auto"
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_height="wrap_content"
android:layout_gravity="center"
card_view:cardElevation="4dp"
card_view:cardCornerRadius="4dp"
android:layout_margin="4dp">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/rootView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clickable="true"
android:focusable="true"
android:foreground="?android:attr/selectableItemBackground">
<androidx.constraintlayout.widget.Guideline
android:id="@+id/firstVerticalGuideline"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.05"/>
<androidx.constraintlayout.widget.Guideline
android:id="@+id/secondVerticalGuideline"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.45"/>
<androidx.constraintlayout.widget.Guideline
android:id="@+id/thirdVerticalGuideline"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.55"/>
<androidx.constraintlayout.widget.Guideline
android:id="@+id/fourthVerticalGuideline"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.95"/>
<androidx.constraintlayout.widget.Guideline
android:id="@+id/centeredVerticalGuideline"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.50"/>
<View
android:id="@+id/vPaymentDirection"
android:layout_width="8dp"
android:layout_height="0dp"
android:background="@color/colorReceive"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"/>
<TextView
android:layout_width="wrap_content"
android:id="@+id/tvFrom"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:padding="4dp"
tools:text="Transaction example"/>
android:layout_marginTop="16dp"
android:maxLines="1"
tools:text="denzel-washington"
android:textAppearance="@style/TextAppearance.Bitsy.Body2"
android:textColor="@color/gray"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toEndOf="@id/firstVerticalGuideline"
app:layout_constraintEnd_toStartOf="@id/secondVerticalGuideline"/>
<ImageView
android:id="@+id/ivDirectionArrow"
android:layout_width="0dp"
android:layout_height="0dp"
android:src="@drawable/ic_arrow_receive"
app:layout_constraintTop_toTopOf="@id/tvFrom"
app:layout_constraintBottom_toBottomOf="@id/tvFrom"
app:layout_constraintStart_toEndOf="@id/secondVerticalGuideline"
app:layout_constraintEnd_toStartOf="@id/thirdVerticalGuideline"
tools:ignore="ContentDescription" />
<TextView
android:id="@+id/tvTo"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:maxLines="1"
tools:text="joes-grocery-13"
android:textAppearance="@style/TextAppearance.Bitsy.Body2"
android:textColor="@color/gray"
android:textAlignment="textEnd"
app:layout_constraintTop_toTopOf="@id/tvFrom"
app:layout_constraintStart_toEndOf="@id/thirdVerticalGuideline"
app:layout_constraintEnd_toStartOf="@id/fourthVerticalGuideline"/>
<View
android:id="@+id/vSeparator"
android:layout_width="0dp"
android:layout_height="1dp"
android:layout_marginTop="12dp"
android:background="@color/lightGray"
app:layout_constraintTop_toBottomOf="@id/tvFrom"
app:layout_constraintStart_toEndOf="@id/firstVerticalGuideline"
app:layout_constraintEnd_toStartOf="@id/fourthVerticalGuideline" />
<LinearLayout
android:id="@+id/llMemo"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:orientation="vertical"
android:visibility="gone"
card_view:layout_constraintTop_toBottomOf="@id/vSeparator"
card_view:layout_constraintStart_toEndOf="@id/firstVerticalGuideline"
card_view:layout_constraintEnd_toStartOf="@id/fourthVerticalGuideline">
<TextView
android:id="@+id/tvMemo"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:maxLines="2"
android:textAppearance="@android:style/TextAppearance.Material.Caption"
tools:text="Here is a memo if exists and can span up to 2 lines, if it get lager we will have problems with the rendering"/>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginTop="12dp"
android:background="@color/lightGray"/>
</LinearLayout>
<TextView
android:id="@+id/tvDate"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:maxLines="1"
tools:text="02 Oct"
android:textStyle="bold"
android:textAppearance="@style/TextAppearance.Bitsy.Body1"
app:layout_constraintTop_toBottomOf="@id/llMemo"
app:layout_constraintStart_toEndOf="@id/firstVerticalGuideline"
app:layout_constraintEnd_toStartOf="@id/centeredVerticalGuideline"/>
<TextView
android:id="@+id/tvTime"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:maxLines="1"
tools:text="15:01:18 CET"
android:textAppearance="@style/TextAppearance.Bitsy.Body2"
android:textColor="@color/gray"
app:layout_constraintTop_toBottomOf="@+id/tvDate"
app:layout_constraintStart_toEndOf="@id/firstVerticalGuideline"
app:layout_constraintEnd_toStartOf="@id/centeredVerticalGuideline"/>
<TextView
android:id="@+id/tvCryptoAmount"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:maxLines="1"
tools:text="1234567.1234 BTS"
android:textAppearance="@style/TextAppearance.Bitsy.Body1"
android:textStyle="bold"
android:textAlignment="textEnd"
app:layout_constraintTop_toTopOf="@id/tvDate"
app:layout_constraintStart_toEndOf="@id/centeredVerticalGuideline"
app:layout_constraintEnd_toStartOf="@id/fourthVerticalGuideline" />
<TextView
android:id="@+id/tvFiatEquivalent"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:maxLines="1"
tools:text="4119.75 $"
android:textAppearance="@style/TextAppearance.Bitsy.Body2"
android:textColor="@color/gray"
android:textAlignment="textEnd"
app:layout_constraintTop_toBottomOf="@+id/tvCryptoAmount"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="@id/centeredVerticalGuideline"
app:layout_constraintEnd_toStartOf="@id/fourthVerticalGuideline"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>

View file

@ -6,4 +6,7 @@
<color name="black">#000</color>
<color name="gray">#888</color>
<color name="lightGray">#e0e0e0</color>
<color name="colorReceive">#669900</color>
<color name="colorSend">#DC473A</color>
</resources>