filterAdapter first draft

hh
Laurent 6 years ago
parent 565223ad5a
commit 3c81d9dc34
  1. 202
      app/src/main/java/net/pokeranalytics/android/ui/adapter/FilterSectionAdapter.kt
  2. 2
      app/src/main/java/net/pokeranalytics/android/ui/adapter/SectionAdapter.kt

@ -0,0 +1,202 @@
package net.pokeranalytics.android.ui.adapter
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.appcompat.widget.AppCompatTextView
import androidx.recyclerview.widget.RecyclerView
import io.realm.RealmModel
import io.realm.RealmQuery
import io.realm.RealmResults
import net.pokeranalytics.android.R
import net.pokeranalytics.android.exceptions.PAIllegalStateException
import net.pokeranalytics.android.model.realm.Filter
import net.pokeranalytics.android.ui.view.RowRepresentable
import net.pokeranalytics.android.ui.view.RowViewType
import net.pokeranalytics.android.util.NULL_TEXT
import net.pokeranalytics.android.util.extensions.getMonthAndYear
import java.util.*
import kotlin.collections.HashMap
interface DateModel : RowRepresentable, RealmModel {
var date: Date
}
interface EntityDescriptor<T : DateModel> {
fun bindableHolder(view: View): RecyclerView.ViewHolder
val layout: Int
val viewType: Int
val sortFieldName: String
fun distinctHeaders(realmQuery: RealmQuery<T>): RealmQuery<T>
}
/**
* An adapter capable of displaying a list of RowRepresentables
* @param dataSource the datasource providing rows
* @param delegate the delegate, notified of UI actions
*/
class FilterSectionAdapter<T : DateModel>(
override var delegate: RowRepresentableDelegate? = null,
override var dataSource: RowRepresentableDataSource,
var descriptor: EntityDescriptor<T>,
var realmQuery: RealmQuery<T>
// var distinctTransactionsHeaders: RealmResults<Transaction>
) :
RecyclerView.Adapter<RecyclerView.ViewHolder>(), RecyclerAdapter {
private var headersPositions = HashMap<Int, Date?>()
private lateinit var sortedHeaders: SortedMap<Int, Date?>
private var realmEntities: RealmResults<T>
private var realmHeaders: RealmResults<T>
var filter: Filter? = null
init {
this.realmEntities = this.realmQuery.findAll().sort(this.descriptor.sortFieldName)
// this.realmEntities = this.filter?.results() ?: this.realmQuery.findAll().sort(this.descriptor.sortFieldName)
this.realmHeaders = this.descriptor.distinctHeaders(this.realmQuery).findAll()
refreshData()
}
/**
* Display a transaction view
*/
inner class RowEntityViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), BindableHolder {
fun bind(position: Int, row: T?, adapter: FilterSectionAdapter<T>) {
// itemView.transactionRow.setData(row as Transaction)
// val listener = View.OnClickListener {
// adapter.delegate?.onRowSelected(position, row)
// }
// itemView.transactionRow.setOnClickListener(listener)
}
}
/**
* Display a header
*/
inner class HeaderTitleViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), BindableHolder {
fun bind(title: String) {
// Title
itemView.findViewById<AppCompatTextView>(R.id.title)?.let {
it.text = title
}
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
val inflater = LayoutInflater.from(parent.context)
return if (viewType == this.descriptor.viewType) { // TODO layout
val layout = inflater.inflate(this.descriptor.layout, parent, false)
this.descriptor.bindableHolder(layout)
// RowEntityViewHolder(layout)
} else {
val layout = inflater.inflate(R.layout.row_header_title, parent, false)
HeaderTitleViewHolder(layout)
}
}
override fun getItemViewType(position: Int): Int {
return if (sortedHeaders.containsKey(position)) {
RowViewType.HEADER_TITLE.ordinal
} else {
this.descriptor.viewType // RowViewType.ROW_TRANSACTION.ordinal
}
}
override fun getItemCount(): Int {
return realmEntities.size + realmHeaders.size
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
if (holder is BindableHolder) {
holder.onBind(position, getEntityForPosition(position), this)
} else if (holder is FeedTransactionRowRepresentableAdapter.HeaderTitleViewHolder) {
holder.bind(getHeaderForPosition(position))
}
}
/**
* Return the header
*/
private fun getHeaderForPosition(position: Int): String {
if (sortedHeaders.containsKey(position)) {
val realmHeaderPosition = sortedHeaders.keys.indexOf(position)
return realmHeaders[realmHeaderPosition]?.date?.getMonthAndYear() ?: ""
}
return NULL_TEXT
}
/**
* Get real index
*/
private fun getEntityForPosition(position: Int): T {
// Row position
var headersBefore = 0
for (key in sortedHeaders.keys) {
if (position > key) {
headersBefore++
} else {
break
}
}
return realmEntities[position - headersBefore] ?: throw PAIllegalStateException("Nasty problem!")
}
/**
* Refresh headers positions
*/
fun refreshData() {
headersPositions.clear()
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, transaction) in realmEntities.withIndex()) {
calendar.time = transaction.date
if (checkHeaderCondition(calendar, previousYear, previousMonth)) {
headersPositions[index + headersPositions.size] = transaction.date
previousYear = calendar.get(Calendar.YEAR)
previousMonth = calendar.get(Calendar.MONTH)
}
}
sortedHeaders = headersPositions.toSortedMap()
}
/**
* 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)
}
}

@ -1,2 +0,0 @@
package net.pokeranalytics.android.ui.adapter
Loading…
Cancel
Save