Improve History Session Adapter

feature/top10
Aurelien Hubert 7 years ago
parent 36b1dddec4
commit 21802eb7ec
  1. 83
      app/src/main/java/net/pokeranalytics/android/ui/adapter/HistorySessionRowRepresentableAdapter.kt
  2. 80
      app/src/main/java/net/pokeranalytics/android/ui/fragment/HistoryFragment.kt
  3. 2
      app/src/main/res/values/strings.xml

@ -1,5 +1,6 @@
package net.pokeranalytics.android.ui.adapter
import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
@ -11,6 +12,7 @@ import net.pokeranalytics.android.R
import net.pokeranalytics.android.model.realm.Session
import net.pokeranalytics.android.ui.view.BindableHolder
import net.pokeranalytics.android.ui.view.RowViewType
import net.pokeranalytics.android.util.NULL_TEXT
import net.pokeranalytics.android.util.extensions.getMonthAndYear
import timber.log.Timber
import java.util.*
@ -22,15 +24,16 @@ import kotlin.collections.HashMap
* @param dataSource the datasource providing rows
* @param delegate the delegate, notified of UI actions
*/
class HistoryRowRepresentableAdapter(
var realmResults: RealmResults<Session>,
class HistorySessionRowRepresentableAdapter(
var delegate: RowRepresentableDelegate? = null,
var headers: RealmResults<Session>
var realmResults: RealmResults<Session>,
var pendingRealmResults: RealmResults<Session>,
var distinctHeaders: RealmResults<Session>
) :
RecyclerView.Adapter<RecyclerView.ViewHolder>() {
private var headersPositions = HashMap<Int, Date>()
private lateinit var sortedHeaders: SortedMap<Int, Date>
private var headersPositions = HashMap<Int, Date?>()
private lateinit var sortedHeaders: SortedMap<Int, Date?>
init {
refreshData()
@ -40,7 +43,7 @@ class HistoryRowRepresentableAdapter(
* Display a session view
*/
inner class RowSessionViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), BindableHolder {
fun bind(position: Int, row: Session?, adapter: HistoryRowRepresentableAdapter) {
fun bind(position: Int, row: Session?, adapter: HistorySessionRowRepresentableAdapter) {
itemView.sessionRow.setData(row as Session)
val listener = View.OnClickListener {
@ -54,10 +57,10 @@ class HistoryRowRepresentableAdapter(
* Display a session view
*/
inner class HeaderTitleViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), BindableHolder {
fun bind(position: Int, session: Session?, adapter: HistoryRowRepresentableAdapter) {
fun bind(position: Int, title: String, adapter: HistorySessionRowRepresentableAdapter) {
// Title
itemView.findViewById<AppCompatTextView>(R.id.title)?.let {
it.text = session?.creationDate?.getMonthAndYear()
it.text = title
}
}
}
@ -83,27 +86,45 @@ class HistoryRowRepresentableAdapter(
}
override fun getItemCount(): Int {
return realmResults.size + headers.size
return realmResults.size + pendingRealmResults.size + distinctHeaders.size
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
if (holder is RowSessionViewHolder) {
holder.bind(position, realmResults[getRealIndex(position)], this)
holder.bind(position, getSessionForPosition(position), this)
} else if (holder is HeaderTitleViewHolder) {
holder.bind(position, headers[getRealIndex(position)], this)
holder.bind(position, getHeaderForPosition(holder.itemView.context, position), this)
}
}
/**
* Get real index
* Return the header
*/
private fun getRealIndex(position: Int): Int {
private fun getHeaderForPosition(context: Context, position :Int) : String {
if (sortedHeaders.containsKey(position)) {
// Header position
//Timber.d("getRealIndex: Header: ${sortedHeaders.keys.indexOf(position)}")
return sortedHeaders.keys.indexOf(position)
// If the header has no date, it's a pending session
return if (sortedHeaders[position] == null) {
context.getString(R.string.pending)
} else {
// Else, return the formatted date
val realmHeaderPosition = if (pendingRealmResults.size > 0) sortedHeaders.keys.indexOf(position) - 1 else sortedHeaders.keys.indexOf(position)
distinctHeaders[realmHeaderPosition]?.startDate?.getMonthAndYear() ?: ""
}
}
return NULL_TEXT
}
/**
* Get real index
*/
private fun getSessionForPosition(position: Int): Session? {
return if (pendingRealmResults.size > 0 && position < pendingRealmResults.size + 1) {
// If we have pending session & the position is between these sessions
pendingRealmResults[position - 1]
} else {
// Else, return the correct session
// Row position
var headersBefore = 0
for (key in sortedHeaders.keys) {
@ -113,8 +134,8 @@ class HistoryRowRepresentableAdapter(
break
}
}
//Timber.d("getRealIndex: Row: $position $headersBefore")
return position - headersBefore
realmResults[position - headersBefore - pendingRealmResults.size]
}
}
@ -124,17 +145,24 @@ class HistoryRowRepresentableAdapter(
fun refreshData() {
headersPositions.clear()
// If we have pending sessions, set the first header to null
if (pendingRealmResults.size > 0) {
headersPositions[0] = null
}
val start = System.currentTimeMillis()
var previousYear = 0
var previousMonth = 0
var previousYear = Int.MAX_VALUE
var previousMonth = Int.MAX_VALUE
val calendar = Calendar.getInstance()
// Add headers if the date doesn't exist yet
for ((index, session) in realmResults.withIndex()) {
calendar.time = session.creationDate
if (calendar.get(Calendar.YEAR) == previousYear && calendar.get(Calendar.MONTH) < previousMonth || (calendar.get(Calendar.YEAR) < previousYear) || index == 0) {
headersPositions[index + headersPositions.size] = session.creationDate
if (checkHeaderCondition(calendar, previousYear, previousMonth)) {
headersPositions[index + headersPositions.size + pendingRealmResults.size] = session.creationDate
previousYear = calendar.get(Calendar.YEAR)
previousMonth = calendar.get(Calendar.MONTH)
}
@ -145,5 +173,14 @@ class HistoryRowRepresentableAdapter(
Timber.d("Create viewTypesPositions in: ${System.currentTimeMillis() - start}ms")
}
/**
* Check if we need to add a header
* Can be change to manage different condition
*/
private fun checkHeaderCondition(currentCalendar: Calendar, previousYear: Int, previousMonth: Int) : Boolean {
return currentCalendar.get(Calendar.YEAR) == previousYear && currentCalendar.get(Calendar.MONTH) < previousMonth || (currentCalendar.get(Calendar.YEAR) < previousYear)
}
}

@ -12,7 +12,7 @@ import net.pokeranalytics.android.R
import net.pokeranalytics.android.model.interfaces.Manageable
import net.pokeranalytics.android.model.realm.Session
import net.pokeranalytics.android.ui.activity.SessionActivity
import net.pokeranalytics.android.ui.adapter.HistoryRowRepresentableAdapter
import net.pokeranalytics.android.ui.adapter.HistorySessionRowRepresentableAdapter
import net.pokeranalytics.android.ui.adapter.LiveRowRepresentableDataSource
import net.pokeranalytics.android.ui.adapter.RowRepresentableDelegate
import net.pokeranalytics.android.ui.fragment.components.PokerAnalyticsFragment
@ -31,9 +31,9 @@ class HistoryFragment : PokerAnalyticsFragment(), LiveRowRepresentableDataSource
}
}
private lateinit var historyAdapter: HistoryRowRepresentableAdapter
private lateinit var historyAdapter: HistorySessionRowRepresentableAdapter
// Old
//private lateinit var historyAdapter: HistoryRowRepresentableAdapter
//private lateinit var historyAdapter: HistorySessionRowRepresentableAdapter
private lateinit var realmSessions: RealmResults<Session>
private val sessions: ArrayList<Session> = ArrayList()
private val rows: ArrayList<RowRepresentable> = ArrayList()
@ -81,22 +81,22 @@ class HistoryFragment : PokerAnalyticsFragment(), LiveRowRepresentableDataSource
* Init data
*/
private fun initData() {
realmSessions = getRealm().where<Session>().findAll().sort("creationDate", Sort.DESCENDING)
val viewManager = SmoothScrollLinearLayoutManager(requireContext())
realmSessions = getRealm().where<Session>().findAll().sort("startDate", Sort.DESCENDING)
realmSessions.addChangeListener { t, changeSet ->
if (changeSet.insertions.isNotEmpty() || changeSet.deletions.isNotEmpty()) {
historyAdapter.refreshData()
}
historyAdapter.notifyDataSetChanged()
}
val months = getRealm().where<Session>().distinct("year", "month").findAll().sort("creationDate", Sort.DESCENDING)
historyAdapter = HistoryRowRepresentableAdapter(realmSessions, this, months)
// Old
//historyAdapter = RowRepresentableAdapter(this, this)
val startedSessions = getRealm().where<Session>().isNotNull("year").isNotNull("month").findAll().sort("startDate", Sort.DESCENDING)
val pendingSessions = getRealm().where<Session>().isNull("year").isNull("month").findAll().sort("startDate", Sort.DESCENDING)
val distinctDateSessions = getRealm().where<Session>().distinct("year", "month").findAll().sort("startDate", Sort.DESCENDING)
historyAdapter = HistorySessionRowRepresentableAdapter(this, startedSessions, pendingSessions, distinctDateSessions)
val viewManager = SmoothScrollLinearLayoutManager(requireContext())
recyclerView.apply {
setHasFixedSize(true)
layoutManager = viewManager
@ -104,66 +104,6 @@ class HistoryFragment : PokerAnalyticsFragment(), LiveRowRepresentableDataSource
}
}
/**
* Create the endedSessions headers
* TODO: Remove
*/
private fun createSessionsHeaders() {
/*
val start = System.currentTimeMillis()
val oldRows = ArrayList<RowRepresentable>()
oldRows.addAll(rows)
rows.clear()
sessions.clear()
sessions.addAll(getRealm().copyFromRealm(realmSessions))
noSessionFound.isVisible = sessions.isEmpty()
GlobalScope.launch {
val groupedByDay = false
val calendar = Calendar.getInstance()
val currentCalendar = Calendar.getInstance()
for ((index, session) in sessions.withIndex()) {
currentCalendar.time = session.creationDate
if (groupedByDay) {
if (!calendar.isSameDay(currentCalendar) || index == 0) {
calendar.time = currentCalendar.time
val header = CustomizableRowRepresentable(
customViewType = RowViewType.HEADER_TITLE,
title = session.creationDate.longDate()
)
rows.add(header)
}
} else {
if (!calendar.isSameMonth(currentCalendar) || index == 0) {
calendar.time = currentCalendar.time
val header = CustomizableRowRepresentable(
customViewType = RowViewType.HEADER_TITLE,
title = session.creationDate.getMonthAndYear()
)
rows.add(header)
}
}
rows.add(session)
}
val diffResult = DiffUtil.calculateDiff(HistorySessionDiffCallback(rows, oldRows))
historyAdapter.updateRows(diffResult)
if (newSessionCreated) {
newSessionCreated = false
recyclerView.smoothScrollToPosition(0)
}
Timber.d("createSessionsHeaders in: ${System.currentTimeMillis() - start}ms")
}
*/
}
override fun rowRepresentableForPosition(position: Int): RowRepresentable? {
return this.rows[position]
}

@ -31,6 +31,8 @@
<string name="tournament_feature">Tournament Feature</string>
<string name="new_entity">New</string>
<string name="pending">Pending</string>
<!-- Translated -->
<string name="_ago">%s ago</string>

Loading…
Cancel
Save