diff --git a/app/build.gradle b/app/build.gradle index 2b5195f7..16f3127c 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -34,6 +34,10 @@ android { } } + configurations { + all*.exclude group: 'com.google.guava', module: 'listenablefuture' + } + } dependencies { @@ -47,6 +51,9 @@ dependencies { implementation 'androidx.constraintlayout:constraintlayout:1.1.3' implementation 'androidx.lifecycle:lifecycle-extensions:2.0.0' + // Places + implementation 'com.google.android.libraries.places:places:1.0.0' + // Firebase implementation 'com.google.firebase:firebase-core:16.0.7' diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 23186ad9..3354a3c9 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -2,6 +2,9 @@ + + + () + fun init(context: Context) { + values.clear() + values.addAll(context.resources.getStringArray(R.array.limit_short_name)) + } + + /** + * Get a limit name + */ + fun get(index: Int) : String? { + if (index >= 0 && index < values.size) { + return values[index] + } + return "" + } + } + +} \ No newline at end of file diff --git a/app/src/main/java/net/pokeranalytics/android/model/LiveData.kt b/app/src/main/java/net/pokeranalytics/android/model/LiveData.kt index 48212554..1d79a807 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/LiveData.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/LiveData.kt @@ -16,6 +16,8 @@ interface ObjectSavable { fun isValidForSave(): Boolean { return true } + + fun uniqueIdentifier(): String } /** @@ -64,8 +66,8 @@ enum class LiveData : Localizable { } } - fun deleteData(realm:Realm, data:LiveDataDataSource) { - realm.where(this.relatedEntity).equalTo("id", data.primaryKey).findAll().deleteAllFromRealm() + fun deleteData(realm:Realm, data:ObjectSavable) { + realm.where(this.relatedEntity).equalTo("id", data.uniqueIdentifier()).findAll().deleteAllFromRealm() } fun updateOrCreate(realm:Realm, primaryKey:String?): RealmObject { diff --git a/app/src/main/java/net/pokeranalytics/android/model/realm/Bankroll.kt b/app/src/main/java/net/pokeranalytics/android/model/realm/Bankroll.kt index 240ce6de..be0cc9d9 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/realm/Bankroll.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/realm/Bankroll.kt @@ -8,15 +8,12 @@ import net.pokeranalytics.android.model.ObjectSavable import net.pokeranalytics.android.ui.adapter.components.LiveDataDataSource import net.pokeranalytics.android.ui.adapter.components.RowRepresentableDataSource import net.pokeranalytics.android.ui.fragment.components.bottomsheet.BottomSheetData -import net.pokeranalytics.android.ui.view.BankrollRow -import net.pokeranalytics.android.ui.view.RowEditable -import net.pokeranalytics.android.ui.view.RowRepresentable -import net.pokeranalytics.android.ui.view.SimpleRow +import net.pokeranalytics.android.ui.view.* import java.util.* import kotlin.collections.ArrayList -open class Bankroll(name: String = "") : RealmObject(), RowRepresentableDataSource, LiveDataDataSource, - RowEditable, ObjectSavable { +open class Bankroll(name: String = "") : RealmObject(), RowRepresentableDataSource, + RowEditable, ObjectSavable, RowRepresentable { companion object { fun newInstance() : Bankroll { @@ -42,8 +39,13 @@ open class Bankroll(name: String = "") : RealmObject(), RowRepresentableDataSour // @todo rate management - override val title: String get() = this.name - override val primaryKey: String get() = this.id + override fun getDisplayName(): String { + return this.name + } + + override fun uniqueIdentifier(): String { + return this.id + } override fun adapterRows(): ArrayList { val rows = ArrayList() diff --git a/app/src/main/java/net/pokeranalytics/android/model/realm/Game.kt b/app/src/main/java/net/pokeranalytics/android/model/realm/Game.kt index 2171bfb4..2ff50761 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/realm/Game.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/realm/Game.kt @@ -4,16 +4,15 @@ import android.text.InputType import io.realm.RealmObject import io.realm.annotations.PrimaryKey import net.pokeranalytics.android.model.ObjectSavable +import net.pokeranalytics.android.ui.adapter.components.DisplayableDelegate import net.pokeranalytics.android.ui.adapter.components.LiveDataDataSource import net.pokeranalytics.android.ui.adapter.components.RowRepresentableDataSource import net.pokeranalytics.android.ui.fragment.components.bottomsheet.BottomSheetData -import net.pokeranalytics.android.ui.view.GameRow -import net.pokeranalytics.android.ui.view.RowEditable -import net.pokeranalytics.android.ui.view.RowRepresentable -import net.pokeranalytics.android.ui.view.SimpleRow +import net.pokeranalytics.android.ui.view.* import java.util.* -open class Game : RealmObject(), RowRepresentableDataSource, LiveDataDataSource, RowEditable, ObjectSavable { +open class Game : RealmObject(), RowRepresentableDataSource, RowEditable, ObjectSavable, + RowRepresentable { @PrimaryKey var id = UUID.randomUUID().toString() @@ -24,8 +23,13 @@ open class Game : RealmObject(), RowRepresentableDataSource, LiveDataDataSource, // A shorter name for the game var shortName: String? = null - override val title: String get() = this.name - override val primaryKey: String get() = this.id + override fun getDisplayName(): String { + return this.name + } + + override fun uniqueIdentifier(): String { + return this.id + } override fun adapterRows(): ArrayList { val rows = ArrayList() diff --git a/app/src/main/java/net/pokeranalytics/android/model/realm/Location.kt b/app/src/main/java/net/pokeranalytics/android/model/realm/Location.kt index e5d24908..733d6de6 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/realm/Location.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/realm/Location.kt @@ -13,7 +13,7 @@ import net.pokeranalytics.android.ui.view.SimpleRow import java.util.* -open class Location : RealmObject(), RowRepresentableDataSource, LiveDataDataSource, RowEditable, ObjectSavable { +open class Location : RealmObject(), RowRepresentableDataSource, RowEditable, ObjectSavable, RowRepresentable { @PrimaryKey var id = UUID.randomUUID().toString() @@ -27,8 +27,13 @@ open class Location : RealmObject(), RowRepresentableDataSource, LiveDataDataSou // the latitude of the location var latitude: Double? = null - override val title: String get() = this.name - override val primaryKey: String get() = this.id + override fun getDisplayName(): String { + return this.name + } + + override fun uniqueIdentifier(): String { + return this.id + } override fun adapterRows(): ArrayList { val rows = ArrayList() diff --git a/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt b/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt index 66d07af9..e4b9083f 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt @@ -1,28 +1,33 @@ package net.pokeranalytics.android.model.realm +import android.content.Context import android.text.InputType -import io.realm.* +import io.realm.RealmList +import io.realm.RealmObject import io.realm.annotations.Ignore import io.realm.annotations.PrimaryKey import net.pokeranalytics.android.R import net.pokeranalytics.android.calculus.SessionInterface +import net.pokeranalytics.android.model.Limit import net.pokeranalytics.android.model.LiveData +import net.pokeranalytics.android.model.ObjectSavable import net.pokeranalytics.android.model.extensions.SessionState import net.pokeranalytics.android.model.extensions.getState -import net.pokeranalytics.android.ui.adapter.components.LiveDataDataSource import net.pokeranalytics.android.ui.adapter.components.RowRepresentableDataSource import net.pokeranalytics.android.ui.fragment.components.bottomsheet.BottomSheetData import net.pokeranalytics.android.ui.view.RowEditable import net.pokeranalytics.android.ui.view.RowRepresentable import net.pokeranalytics.android.ui.view.SessionRow -import net.pokeranalytics.android.util.data.sessionDao +import net.pokeranalytics.android.util.getDuration +import net.pokeranalytics.android.util.round import net.pokeranalytics.android.util.short import net.pokeranalytics.android.util.toCurrency +import timber.log.Timber import java.util.* import kotlin.collections.ArrayList -open class Session : RealmObject(), SessionInterface, RowRepresentableDataSource, LiveDataDataSource, - RowEditable { +open class Session : RealmObject(), SessionInterface, RowRepresentableDataSource, + RowEditable, RowRepresentable, ObjectSavable { @PrimaryKey var id = UUID.randomUUID().toString() @@ -138,6 +143,22 @@ open class Session : RealmObject(), SessionInterface, RowRepresentableDataSource } } + /** + * Return the duration of the current session + */ + fun getDuration(context: Context): String { + val startDate = timeFrame?.startDate ?: Date() + val enDate = timeFrame?.endDate ?: Date() + return startDate.getDuration(context, enDate) + } + + /** + * Return the formatted blinds + */ + fun getBlinds(): String { + return if (cgSmallBlind == null) "--" else "$${cgSmallBlind?.round()}/${cgBigBlind?.round()}" + } + /** * Delete the object from realm * TODO: Cascade delete? @@ -179,13 +200,13 @@ open class Session : RealmObject(), SessionInterface, RowRepresentableDataSource */ fun getGameTitle(): String { var gameTitle = "" - if (limit != null) { - gameTitle += limit + limit?.let { + gameTitle += Limit.get(it) + " " } if (game != null) { - gameTitle += game?.title + gameTitle += game?.name } - return gameTitle + return if (gameTitle.isNotBlank()) gameTitle else "--" } companion object { @@ -237,6 +258,14 @@ open class Session : RealmObject(), SessionInterface, RowRepresentableDataSource return 0.0 } + override fun uniqueIdentifier(): String { + return this.id + } + + override fun getDisplayName(): String { + return "session ${this.creationDate}" + } + override fun adapterRows(): ArrayList { val rows = ArrayList() rows.addAll(SessionRow.getRowsForState(getState())) @@ -251,9 +280,9 @@ open class Session : RealmObject(), SessionInterface, RowRepresentableDataSource return when (row) { SessionRow.BUY_IN -> buyin.toCurrency() SessionRow.BLINDS -> if (cgSmallBlind != null && cgBigBlind != null) "$cgSmallBlind / $cgBigBlind" else "--" - SessionRow.GAME -> game?.title ?: "--" - SessionRow.LOCATION -> location?.title ?: "--" - SessionRow.BANKROLL -> bankroll?.title ?: "--" + SessionRow.GAME -> getGameTitle() + SessionRow.LOCATION -> location?.name ?: "--" + SessionRow.BANKROLL -> bankroll?.name ?: "--" SessionRow.TABLE_SIZE -> tableSize?.toString() ?: "--" SessionRow.START_DATE -> if (timeFrame != null) timeFrame?.startDate?.short() ?: "--" else "--" SessionRow.END_DATE -> if (timeFrame != null) timeFrame?.endDate?.short() ?: "--" else "--" @@ -271,12 +300,6 @@ open class Session : RealmObject(), SessionInterface, RowRepresentableDataSource } } - - override var title: String = "Change that: $creationDate" - override val primaryKey: String get() = this.id - - - override fun getBottomSheetData(row: RowRepresentable): ArrayList { val data = ArrayList() @@ -288,8 +311,21 @@ open class Session : RealmObject(), SessionInterface, RowRepresentableDataSource data.add(BottomSheetData(100.0 * (cgBigBlind ?: 0.0))) data.add(BottomSheetData(200.0 * (cgBigBlind ?: 0.0))) data.add(BottomSheetData(buyin)) - data.add(BottomSheetData("",inputType = InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_FLAG_DECIMAL)) - data.add(BottomSheetData("",inputType = InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_FLAG_DECIMAL)) + data.add( + BottomSheetData( + "", + inputType = InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_FLAG_DECIMAL + ) + ) + data.add( + BottomSheetData( + "", + inputType = InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_FLAG_DECIMAL + ) + ) + } + SessionRow.CASHED_OUT -> { + data.add(BottomSheetData(result?.cashout, inputType = InputType.TYPE_CLASS_NUMBER)) } SessionRow.TIPS -> { // Disable the buttons with value = 0, add current value & set the 2 edit texts @@ -300,7 +336,9 @@ open class Session : RealmObject(), SessionInterface, RowRepresentableDataSource data.add(BottomSheetData("", inputType = InputType.TYPE_CLASS_NUMBER)) data.add(BottomSheetData("", inputType = InputType.TYPE_CLASS_NUMBER)) } - SessionRow.TABLE_SIZE -> {data.add(BottomSheetData(tableSize))} + SessionRow.TABLE_SIZE -> { + data.add(BottomSheetData(tableSize)) + } SessionRow.GAME -> { // Add current game & games list data.add(BottomSheetData(limit)) @@ -329,14 +367,33 @@ open class Session : RealmObject(), SessionInterface, RowRepresentableDataSource override fun updateValue(value: Any?, row: RowRepresentable) { realm.beginTransaction() when (row) { - SessionRow.BUY_IN -> { val localResult = if (result != null) result as Result else realm.createObject(Result::class.java) - localResult.buyin = value as Double + localResult.buyin = value as Double? + result = localResult + } + SessionRow.CASHED_OUT -> { + val localResult = if (result != null) result as Result else realm.createObject(Result::class.java) + localResult.cashout = if (value == null) null else (value as String).toDouble() result = localResult } SessionRow.TABLE_SIZE -> tableSize = value as Int? - SessionRow.GAME -> game = value as Game? + SessionRow.GAME -> { + if (value is ArrayList<*>) { + Timber.d("${value[0]}") + Timber.d("${value[1]}") + limit = try { + (value[0] as Int?) + } catch (e: Exception) { + null + } + game = try { + (value[1] as Game?) + } catch (e: Exception) { + null + } + } + } SessionRow.BANKROLL -> bankroll = value as Bankroll? SessionRow.LOCATION -> location = value as Location? SessionRow.COMMENT -> comment = value as String? ?: "" @@ -351,20 +408,28 @@ open class Session : RealmObject(), SessionInterface, RowRepresentableDataSource } catch (e: Exception) { null } + + cgBigBlind?.let { + if (cgSmallBlind == null || cgSmallBlind == 0.0) { + cgSmallBlind = it / 2.0 + } + } } //TODO: Update SessionRow.START_DATE -> if (value is Date?) { if (value == null) { timeFrame = null } else { - val timeFrameToUpdate = if (timeFrame != null) timeFrame as TimeFrame else realm.createObject(TimeFrame::class.java) + val timeFrameToUpdate = + if (timeFrame != null) timeFrame as TimeFrame else realm.createObject(TimeFrame::class.java) timeFrameToUpdate.setDate(value, null) timeFrame = timeFrameToUpdate } } //TODO: Update SessionRow.END_DATE -> if (value is Date?) { - val timeFrameToUpdate = if (timeFrame != null) timeFrame as TimeFrame else realm.createObject(TimeFrame::class.java) + val timeFrameToUpdate = + if (timeFrame != null) timeFrame as TimeFrame else realm.createObject(TimeFrame::class.java) timeFrameToUpdate.setDate(null, value) timeFrame = timeFrameToUpdate } @@ -378,70 +443,3 @@ enum class TournamentKind { MTT, SNG } - - -/** - * Session Dao - */ -class SessionDao(realmDb: Realm) { - - var realm: Realm = realmDb - - /** - * Create or update session - */ - fun createOrUpdateSession(session: Session): Session { - realm.beginTransaction() - val sessionToSave = realm.copyToRealmOrUpdate(session) - realm.commitTransaction() - return realm.copyFromRealm(sessionToSave) - } - - /** - * Create or update sessions - */ - fun createOrUpdateSessions(sessions: List): List { - - realm.beginTransaction() - - // Update - val sessionsToSave = realm.copyToRealmOrUpdate(sessions) - realm.commitTransaction() - - return realm.copyFromRealm(sessionsToSave) - } - - /** - * Find all sessions - */ - fun findAllSessions(): RealmResults { - return realm.where(Session::class.java).findAll().sort("creationDate", Sort.DESCENDING) - } - - /** - * Find session by id - */ - fun findSessionById(sessionId: Int): Session? { - return realm.copyFromRealm(realm.where(Session::class.java).equalTo("id", sessionId).findFirst()) - } - - /** - * Delete session - */ - fun deleteSession(sessionId: Int) { - realm.beginTransaction() - realm.sessionDao().findSessionById(sessionId)?.deleteFromRealm() - realm.commitTransaction() - } - - /** - * Delete all sessions - */ - fun deleteAllSessions() { - realm.beginTransaction() - realm.sessionDao().findAllSessions().deleteAllFromRealm() - realm.commitTransaction() - } - - -} \ No newline at end of file diff --git a/app/src/main/java/net/pokeranalytics/android/model/realm/TournamentFeature.kt b/app/src/main/java/net/pokeranalytics/android/model/realm/TournamentFeature.kt index b90c304b..a765249b 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/realm/TournamentFeature.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/realm/TournamentFeature.kt @@ -12,7 +12,7 @@ import net.pokeranalytics.android.ui.view.SimpleRow import net.pokeranalytics.android.ui.view.TournamentFeatureRow import java.util.* -open class TournamentFeature : RealmObject(), RowRepresentableDataSource, LiveDataDataSource, RowEditable, ObjectSavable { +open class TournamentFeature : RealmObject(), RowRepresentableDataSource, RowEditable, ObjectSavable, RowRepresentable { @PrimaryKey var id = UUID.randomUUID().toString() @@ -20,8 +20,13 @@ open class TournamentFeature : RealmObject(), RowRepresentableDataSource, LiveDa // The name of the feature var name: String = "" - override val title: String get() = this.name - override val primaryKey: String get() = this.id + override fun getDisplayName(): String { + return this.name + } + + override fun uniqueIdentifier(): String { + return this.id + } override fun adapterRows(): ArrayList { val rows = ArrayList() diff --git a/app/src/main/java/net/pokeranalytics/android/model/realm/TransactionType.kt b/app/src/main/java/net/pokeranalytics/android/model/realm/TransactionType.kt index f569440e..8e526eab 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/realm/TransactionType.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/realm/TransactionType.kt @@ -13,7 +13,7 @@ import net.pokeranalytics.android.ui.view.TransactionTypeRow import java.util.* -open class TransactionType : RealmObject(), RowRepresentableDataSource, LiveDataDataSource, RowEditable, ObjectSavable { +open class TransactionType : RealmObject(), RowRepresentableDataSource, RowEditable, ObjectSavable, RowRepresentable { @PrimaryKey var id = UUID.randomUUID().toString() @@ -30,8 +30,13 @@ open class TransactionType : RealmObject(), RowRepresentableDataSource, LiveData // The predefined kind, if necessary, like: Withdrawal, deposit, or tips var kind: Int? = null - override val title: String get() = this.name - override val primaryKey: String get() = this.id + override fun getDisplayName(): String { + return this.name + } + + override fun uniqueIdentifier(): String { + return this.id + } override fun adapterRows(): ArrayList { val rows = ArrayList() diff --git a/app/src/main/java/net/pokeranalytics/android/ui/activity/HomeActivity.kt b/app/src/main/java/net/pokeranalytics/android/ui/activity/HomeActivity.kt index b8203b78..b1c395b9 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/activity/HomeActivity.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/activity/HomeActivity.kt @@ -3,6 +3,7 @@ package net.pokeranalytics.android.ui.activity import android.content.Context import android.content.Intent import android.os.Bundle +import androidx.fragment.app.Fragment import com.google.android.material.bottomnavigation.BottomNavigationView import kotlinx.android.synthetic.main.activity_home.* import net.pokeranalytics.android.R @@ -68,7 +69,7 @@ class HomeActivity : PokerAnalyticsActivity() { else -> "" } - val fragment = when(index) { + val fragment: Fragment = when(index) { 0 -> HistoryFragment() 1 -> StatsFragment() else -> SettingsFragment() diff --git a/app/src/main/java/net/pokeranalytics/android/ui/adapter/LimitTypesAdapter.kt b/app/src/main/java/net/pokeranalytics/android/ui/adapter/LimitTypesAdapter.kt index 81e5af9a..52832cbd 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/adapter/LimitTypesAdapter.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/adapter/LimitTypesAdapter.kt @@ -21,6 +21,7 @@ class LimitTypesAdapter(private var tableSizes: ArrayList) : RecyclerVie itemView.title.text = tableSize itemView.container.setOnClickListener { onClickOnItem?.invoke(adapterPosition) + } } } diff --git a/app/src/main/java/net/pokeranalytics/android/ui/adapter/components/LiveDataAdapter.kt b/app/src/main/java/net/pokeranalytics/android/ui/adapter/components/LiveDataAdapter.kt index 2528a469..f2e3b683 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/adapter/components/LiveDataAdapter.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/adapter/components/LiveDataAdapter.kt @@ -9,9 +9,13 @@ import androidx.recyclerview.widget.RecyclerView import net.pokeranalytics.android.R import net.pokeranalytics.android.ui.view.RowViewType +enum class LiveDataViewType { + DATA, + BOTTOM_SHEET_DATA +} + interface LiveDataDataSource { val title: String - val primaryKey: String } interface LiveDataDelegate { @@ -20,17 +24,20 @@ interface LiveDataDelegate { fun size() : Int } -class LiveDataAdapter(var adapterDelegate: LiveDataDelegate, var layout: Int? = null) : RecyclerView.Adapter() { +class LiveDataAdapter(var adapterDelegate: LiveDataDelegate, var liveDataViewType: LiveDataViewType? = LiveDataViewType.DATA) : RecyclerView.Adapter() { inner class DataViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { fun bind(row: LiveDataDataSource, listener: View.OnClickListener) { - try { - itemView.findViewById(R.id.title).text = row.title - itemView.findViewById(R.id.container).setOnClickListener(listener) - } catch (e: Exception) { - e.printStackTrace() + when(liveDataViewType) { + LiveDataViewType.DATA -> { + itemView.findViewById(R.id.rowTitle_title).text = row.title + itemView.findViewById(R.id.rowTitle_container).setOnClickListener(listener) + } + LiveDataViewType.BOTTOM_SHEET_DATA -> { + itemView.findViewById(R.id.title).text = row.title + itemView.findViewById(R.id.container).setOnClickListener(listener) + } } - } } @@ -39,8 +46,16 @@ class LiveDataAdapter(var adapterDelegate: LiveDataDelegate, var layout: Int? = } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder { - val layoutToInflate = layout ?: R.layout.row_title - return DataViewHolder(LayoutInflater.from(parent.context).inflate(layoutToInflate, parent, false)) + val layoutToInflate = when(liveDataViewType) { + LiveDataViewType.DATA -> { + R.layout.row_title + } + LiveDataViewType.BOTTOM_SHEET_DATA -> { + R.layout.row_bottom_sheet_title + } + else -> R.layout.row_title + } + return DataViewHolder(LayoutInflater.from(parent.context).inflate(layoutToInflate, parent, false)) } override fun getItemCount(): Int { diff --git a/app/src/main/java/net/pokeranalytics/android/ui/adapter/components/RowRepresentableAdapter.kt b/app/src/main/java/net/pokeranalytics/android/ui/adapter/components/RowRepresentableAdapter.kt index 9a1eb91c..9977fe0b 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/adapter/components/RowRepresentableAdapter.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/adapter/components/RowRepresentableAdapter.kt @@ -6,18 +6,45 @@ import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.RecyclerView import net.pokeranalytics.android.ui.view.BindableHolder import net.pokeranalytics.android.ui.view.RowRepresentable -import net.pokeranalytics.android.ui.view.RowRepresentableDiffCallback import net.pokeranalytics.android.ui.view.RowViewType +interface RowRepresentableDataSource : DisplayableDataSource { + fun rowRepresentableForPosition(position:Int): RowRepresentable { + if (this.numberOfRows() > position) { + return this.adapterRows()[position] + } else { + throw IllegalStateException("Need to implement Data Source") + } + } + + fun numberOfRows(): Int { + return this.adapterRows().size + } + + fun viewTypeForPosition(position:Int): Int { + return this.rowRepresentableForPosition(position).viewType + } + + fun indexForRow(row:RowRepresentable): Int { + return this.adapterRows().indexOf(row) + } +} + +interface RowRepresentableDelegate : DisplayableDelegate { + fun onIndexSelected(position: Int) {} +} + /** * An interface used to provide RowRepresentableAdapter content and value in the form of rows */ -interface RowRepresentableDataSource { +interface DisplayableDataSource { /** * Returns a list of rows */ - fun adapterRows(): ArrayList + fun adapterRows(): ArrayList { + return ArrayList() + } /** * Returns a boolean for a specific row @@ -48,39 +75,29 @@ interface RowRepresentableDataSource { * - switch (bool) * - static content * */ - } /** * A delegate used to propagate UI actions */ -interface RowRepresentableDelegate { +interface DisplayableDelegate { fun onRowSelected(row: RowRepresentable) {} fun onActionSelected(row: RowRepresentable) {} } /** * An adapter capable of displaying a list of RowRepresentables - * @param rowRepresentableDataSource the datasource providing rows - * @param rowRepresentableDelegate the delegate, notified of UI actions + * @param dataSource the datasource providing rows + * @param delegate the delegate, notified of UI actions */ class RowRepresentableAdapter( - var rowRepresentableDataSource: RowRepresentableDataSource, - var rowRepresentableDelegate: RowRepresentableDelegate? = null + var dataSource: RowRepresentableDataSource, + var delegate: RowRepresentableDelegate? = null ) : RecyclerView.Adapter() { - /** - * The list of rows to display - */ - private var rows: ArrayList = ArrayList() - - init { - this.rows = rowRepresentableDataSource.adapterRows() - } - override fun getItemViewType(position: Int): Int { - return this.rows[position].viewType + return this.dataSource.viewTypeForPosition(position) } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder { @@ -89,28 +106,29 @@ class RowRepresentableAdapter( } override fun getItemCount(): Int { - return this.rows.size + return this.dataSource.numberOfRows() } override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { - val dynamicRow = this.rows[position] + val dynamicRow = this.dataSource.rowRepresentableForPosition(position) val listener = View.OnClickListener { - rowRepresentableDelegate?.onRowSelected(dynamicRow) + delegate?.onRowSelected(dynamicRow) + delegate?.onIndexSelected(position) } val actionListener = View.OnClickListener { - rowRepresentableDelegate?.onActionSelected(dynamicRow) + delegate?.onActionSelected(dynamicRow) } - (holder as BindableHolder).bind(dynamicRow, this.rowRepresentableDataSource, listener, actionListener) + (holder as BindableHolder).bind(dynamicRow, this.dataSource, listener, actionListener) } /** * Refresh the row in the adapter */ fun refreshRow(row: RowRepresentable) { - val index = rows.indexOf(row) + val index = this.dataSource.indexForRow(row) if (index >= 0) { notifyItemChanged(index) } @@ -119,9 +137,7 @@ class RowRepresentableAdapter( /** * Update UI */ - fun updateRows(newRows: ArrayList) { - val diffResult = DiffUtil.calculateDiff(RowRepresentableDiffCallback(newRows, rows, rowRepresentableDataSource)) - this.rows = newRows + fun updateRows(diffResult: DiffUtil.DiffResult) { diffResult.dispatchUpdatesTo(this) } diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/DataListFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/DataListFragment.kt index a5e69cc5..5b7798c4 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/DataListFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/DataListFragment.kt @@ -5,17 +5,21 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.recyclerview.widget.LinearLayoutManager +import io.realm.ObjectChangeSet import io.realm.Realm import io.realm.RealmResults import kotlinx.android.synthetic.main.fragment_data_list.* import net.pokeranalytics.android.R +import net.pokeranalytics.android.model.ObjectSavable import net.pokeranalytics.android.ui.activity.EditableDataActivity import net.pokeranalytics.android.ui.adapter.components.* import net.pokeranalytics.android.ui.fragment.components.PokerAnalyticsFragment +import net.pokeranalytics.android.ui.view.RowRepresentable +import net.pokeranalytics.android.ui.view.RowViewType import net.pokeranalytics.android.ui.view.SettingRow import timber.log.Timber -class DataListFragment : PokerAnalyticsFragment(), LiveDataDelegate { +class DataListFragment : PokerAnalyticsFragment(), RowRepresentableDataSource, RowRepresentableDelegate{ private lateinit var dataType: SettingRow @@ -31,20 +35,28 @@ class DataListFragment : PokerAnalyticsFragment(), LiveDataDelegate { initUI() } - override fun data(position: Int): LiveDataDataSource { - return (items[position] as LiveDataDataSource) + override fun rowRepresentableForPosition(position: Int): RowRepresentable { + return this.items[position] as RowRepresentable } - override fun onRowSelected(position: Int) { + override fun numberOfRows(): Int { + return this.items.size + } + + override fun viewTypeForPosition(position: Int): Int { + return RowViewType.DATA.ordinal + } + + override fun indexForRow(row: RowRepresentable): Int { + return this.items.indexOf(row) + } + + override fun onIndexSelected(position: Int) { this.dataType.relatedResultsRepresentable?.let { - EditableDataActivity.newInstance(requireContext(), it.ordinal, this.data(position).primaryKey) + EditableDataActivity.newInstance(requireContext(), it.ordinal, (this.items[position] as ObjectSavable).uniqueIdentifier()) } } - override fun size(): Int { - return items.size - } - private fun initData() { } @@ -54,7 +66,7 @@ class DataListFragment : PokerAnalyticsFragment(), LiveDataDelegate { private fun initUI() { val viewManager = LinearLayoutManager(requireContext()) - val dataListAdapter = LiveDataAdapter(this) + val dataListAdapter = RowRepresentableAdapter(this, this) recyclerView.apply { setHasFixedSize(true) diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/EditableDataFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/EditableDataFragment.kt index 62e25c8f..9b9de841 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/EditableDataFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/EditableDataFragment.kt @@ -1,10 +1,7 @@ package net.pokeranalytics.android.ui.fragment -import android.content.DialogInterface import android.os.Bundle -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup +import android.view.* import android.widget.Toast import androidx.appcompat.app.AlertDialog import androidx.recyclerview.widget.LinearLayoutManager @@ -25,9 +22,10 @@ import timber.log.Timber class EditableDataFragment : PokerAnalyticsFragment(), RowRepresentableDelegate, BottomSheetDelegate { - private lateinit var item: RealmObject + private lateinit var item: RealmObject private lateinit var liveDataType: LiveData private lateinit var rowRepresentableAdapter: RowRepresentableAdapter + private var editableMenu: Menu? = null override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { return inflater.inflate(R.layout.fragment_editable_data, container, false) @@ -39,6 +37,22 @@ class EditableDataFragment : PokerAnalyticsFragment(), RowRepresentableDelegate, initUI() } + override fun onCreateOptionsMenu(menu: Menu?, inflater: MenuInflater?) { + inflater?.inflate(R.menu.editable_data, menu) + this.editableMenu = menu + updateMenuUI() + super.onCreateOptionsMenu(menu, inflater) + } + + + override fun onOptionsItemSelected(item: MenuItem?): Boolean { + when (item!!.itemId) { + R.id.save -> saveData() + R.id.delete -> deleteData() + } + return true + } + override fun onRowSelected(row: RowRepresentable) { BottomSheetFragment.create(fragmentManager, row, this, (this.item as RowEditable).getBottomSheetData(row)) } @@ -49,16 +63,16 @@ class EditableDataFragment : PokerAnalyticsFragment(), RowRepresentableDelegate, override fun clickOnClear(row: RowRepresentable) { Toast.makeText(requireContext(), "Clear: $row", Toast.LENGTH_SHORT).show() - (this.item as RowEditable).updateValue(null, row) this.getRealm().executeTransaction { + (this.item as RowEditable).updateValue(null, row) it.copyToRealmOrUpdate(this.item) } rowRepresentableAdapter.refreshRow(row) } override fun setValue(value: Any?, row: RowRepresentable) { - (this.item as RowEditable).updateValue(value, row) this.getRealm().executeTransaction { + (this.item as RowEditable).updateValue(value, row) it.copyToRealmOrUpdate(this.item) } rowRepresentableAdapter.refreshRow(row) @@ -74,6 +88,7 @@ class EditableDataFragment : PokerAnalyticsFragment(), RowRepresentableDelegate, val activity = activity as PokerAnalyticsActivity activity.setSupportActionBar(toolbar) activity.supportActionBar?.setDisplayHomeAsUpEnabled(true) + setHasOptionsMenu(true) val viewManager = LinearLayoutManager(requireContext()) @@ -81,49 +96,60 @@ class EditableDataFragment : PokerAnalyticsFragment(), RowRepresentableDelegate, setHasFixedSize(true) layoutManager = viewManager } + } + + /** + * Update menu UI + */ + private fun updateMenuUI() { + editableMenu?.findItem(R.id.delete)?.isVisible = item.isManaged + editableMenu?.findItem(R.id.save)?.isVisible = true + } + + /** + * Save data + */ + private fun saveData() { + if ((this.item as ObjectSavable).isValidForSave()) { + this.getRealm().executeTransaction { + it.copyToRealmOrUpdate(this.item) + } + activity?.finish() + } else { + val builder = AlertDialog.Builder(requireContext()) + .setMessage(R.string.empty_name_for_br_error) + .setNegativeButton(R.string.ok, null) + builder.show() + } - this.saveButton.text = this.saveButton.context.getString(R.string.save) - this.saveButton.setOnClickListener { + } - if ((this.item as ObjectSavable).isValidForSave()) { - this.getRealm().executeTransaction { - it.copyToRealmOrUpdate(this.item) + /** + * Delete data + */ + private fun deleteData() { + + val builder = AlertDialog.Builder(requireContext()) + builder.setTitle(R.string.warning) + .setMessage(R.string.are_you_sure_you_want_to_do_that_) + .setNegativeButton(R.string.no, null) + .setPositiveButton(R.string.yes) { dialog, id -> + if (this.item.isManaged) { + Toast.makeText(requireContext(), "isManaged", Toast.LENGTH_SHORT).show() + Timber.d("is managed") + this.getRealm().executeTransaction { + this.liveDataType.deleteData(it, (this.item as ObjectSavable)) + } + } else { + Toast.makeText(requireContext(), "isNotManaged", Toast.LENGTH_SHORT).show() + Timber.d("is not managed") } this.activity?.let { it.finish() } - } else { - val builder = AlertDialog.Builder(it.context) - .setMessage(R.string.empty_name_for_br_error) - .setNegativeButton(R.string.ok, null) - builder.show() } - } + builder.show() - this.deleteButton.text = this.deleteButton.context.getString(R.string.delete) - this.deleteButton.setOnClickListener { - val builder = AlertDialog.Builder(it.context) - builder.setTitle(R.string.warning) - .setMessage(R.string.are_you_sure_you_want_to_do_that_) - .setNeutralButton(R.string.no, null) - .setNegativeButton(R.string.yes, DialogInterface.OnClickListener { dialog, id -> - - if (this.item.isManaged) { - Toast.makeText(requireContext(), "isManaged", Toast.LENGTH_SHORT).show() - Timber.d("is managed") - this.getRealm().executeTransaction { - this.liveDataType.deleteData(it, (this.item as LiveDataDataSource)) - } - } else { - Toast.makeText(requireContext(), "isNotManaged", Toast.LENGTH_SHORT).show() - Timber.d("is not managed") - } - this.activity?.let { - it.finish() - } - }) - builder.show() - } } /** @@ -131,8 +157,8 @@ class EditableDataFragment : PokerAnalyticsFragment(), RowRepresentableDelegate, */ fun setData(dataType: Int, primaryKey: String?) { this.liveDataType = LiveData.values()[dataType] - var proxyItem : RealmObject? = this.liveDataType.getData(this.getRealm(), primaryKey) - proxyItem?.let { + var proxyItem: RealmObject? = this.liveDataType.getData(this.getRealm(), primaryKey) + proxyItem?.let { this.appBar.toolbar.title = "Update ${this.liveDataType.name.toLowerCase().capitalize()}" } ?: run { this.appBar.toolbar.title = "New ${this.liveDataType.name.toLowerCase().capitalize()}" diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/HistoryFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/HistoryFragment.kt index 517aeca3..b9a2a85c 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/HistoryFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/HistoryFragment.kt @@ -7,15 +7,21 @@ import android.view.ViewGroup import android.widget.Toast import androidx.recyclerview.widget.LinearLayoutManager import io.realm.RealmResults +import io.realm.Sort +import io.realm.kotlin.where import kotlinx.android.synthetic.main.fragment_history.* import net.pokeranalytics.android.R +import net.pokeranalytics.android.model.ObjectSavable import net.pokeranalytics.android.model.realm.Session import net.pokeranalytics.android.ui.activity.SessionActivity -import net.pokeranalytics.android.ui.adapter.HistoryAdapter +import net.pokeranalytics.android.ui.adapter.components.RowRepresentableAdapter +import net.pokeranalytics.android.ui.adapter.components.RowRepresentableDataSource +import net.pokeranalytics.android.ui.adapter.components.RowRepresentableDelegate import net.pokeranalytics.android.ui.fragment.components.PokerAnalyticsFragment -import net.pokeranalytics.android.util.data.sessionDao +import net.pokeranalytics.android.ui.view.RowRepresentable +import net.pokeranalytics.android.ui.view.RowViewType -class HistoryFragment : PokerAnalyticsFragment() { +class HistoryFragment : PokerAnalyticsFragment(), RowRepresentableDataSource, RowRepresentableDelegate { companion object { fun newInstance(): HistoryFragment { @@ -26,8 +32,8 @@ class HistoryFragment : PokerAnalyticsFragment() { } } - private lateinit var historyAdapter: HistoryAdapter - private var realmSessions: RealmResults? = null + private lateinit var historyAdapter: RowRepresentableAdapter + private lateinit var realmSessions: RealmResults override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { return inflater.inflate(R.layout.fragment_history, container, false) @@ -41,7 +47,12 @@ class HistoryFragment : PokerAnalyticsFragment() { override fun onDestroyView() { super.onDestroyView() - realmSessions?.removeAllChangeListeners() + realmSessions.removeAllChangeListeners() + } + + override fun onResume() { + super.onResume() + historyAdapter.notifyDataSetChanged() } /** @@ -70,28 +81,34 @@ class HistoryFragment : PokerAnalyticsFragment() { * Init data */ private fun initData() { + realmSessions = getRealm().where().findAll().sort("timeFrame.startDate", Sort.DESCENDING) + val viewManager = LinearLayoutManager(requireContext()) + historyAdapter = RowRepresentableAdapter(this, this) + + recyclerView.apply { + setHasFixedSize(true) + layoutManager = viewManager + adapter = historyAdapter + } + } - realmSessions = getRealm().sessionDao().findAllSessions() - realmSessions?.let { - - val viewManager = LinearLayoutManager(requireContext()) - historyAdapter = HistoryAdapter(it) - - recyclerView.apply { - setHasFixedSize(true) - layoutManager = viewManager - adapter = historyAdapter - } + override fun rowRepresentableForPosition(position: Int): RowRepresentable { + return this.realmSessions[position] as RowRepresentable + } - historyAdapter.onClickOnSession = {position, session -> - SessionActivity.newInstance(requireContext(), sessionId = session.id) - } + override fun numberOfRows(): Int { + return this.realmSessions.size + } - it.addChangeListener { newSessions -> - historyAdapter.notifyDataSetChanged() - } - } + override fun viewTypeForPosition(position: Int): Int { + return RowViewType.ROW_SESSION.ordinal + } + override fun indexForRow(row: RowRepresentable): Int { + return this.realmSessions.indexOf(row) } + override fun onRowSelected(row: RowRepresentable) { + SessionActivity.newInstance(requireContext(), sessionId = (row as ObjectSavable).uniqueIdentifier()) + } } \ No newline at end of file diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/SessionFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/SessionFragment.kt index 32481276..f06fca4b 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/SessionFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/SessionFragment.kt @@ -4,7 +4,9 @@ import android.os.Bundle import android.view.* import android.view.animation.OvershootInterpolator import android.widget.Toast +import androidx.core.content.ContextCompat import androidx.interpolator.view.animation.FastOutSlowInInterpolator +import androidx.recyclerview.widget.DiffUtil import io.realm.kotlin.where import kotlinx.android.synthetic.main.fragment_session.* import net.pokeranalytics.android.R @@ -21,8 +23,10 @@ import net.pokeranalytics.android.ui.fragment.components.PokerAnalyticsFragment import net.pokeranalytics.android.ui.fragment.components.bottomsheet.BottomSheetDelegate import net.pokeranalytics.android.ui.fragment.components.bottomsheet.BottomSheetFragment import net.pokeranalytics.android.ui.view.RowRepresentable +import net.pokeranalytics.android.ui.view.RowRepresentableDiffCallback import net.pokeranalytics.android.ui.view.SessionRow import net.pokeranalytics.android.ui.view.SmoothScrollLinearLayoutManager +import net.pokeranalytics.android.util.px import net.pokeranalytics.android.util.toast import timber.log.Timber import java.util.* @@ -32,7 +36,7 @@ class SessionFragment : PokerAnalyticsFragment(), RowRepresentableDelegate, Bott private lateinit var currentSession: Session private lateinit var sessionAdapter: RowRepresentableAdapter private var sessionMenu: Menu? = null - + private val oldRows: ArrayList = ArrayList() override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { return inflater.inflate(R.layout.fragment_session, container, false) @@ -145,7 +149,6 @@ class SessionFragment : PokerAnalyticsFragment(), RowRepresentableDelegate, Bott floatingActionButton.setOnClickListener { manageSessionState() } - } /** @@ -156,42 +159,89 @@ class SessionFragment : PokerAnalyticsFragment(), RowRepresentableDelegate, Bott when (currentSession.getState()) { SessionState.PENDING -> { + state.text = "WAITING" + state.setTextColor(ContextCompat.getColor(requireContext(), R.color.white)) sessionMenu?.findItem(R.id.restart)?.isVisible = false floatingActionButton.setImageResource(R.drawable.ic_outline_play) bottomAppBar.menu.findItem(R.id.stop).isVisible = false + floatingActionButton.animate().scaleX(1f).scaleY(1f).alpha(1f) .setInterpolator(OvershootInterpolator()).start() + sessionData.animate().translationY(-(72f.px)).alpha(1f) + .setInterpolator(FastOutSlowInInterpolator()).setDuration(500).start() + recyclerView.animate().translationY(-(72f.px)) + .setInterpolator(FastOutSlowInInterpolator()).setDuration(500).start() } SessionState.STARTED -> { + state.text = "PLAYING" + state.setTextColor(ContextCompat.getColor(requireContext(), R.color.green)) sessionMenu?.findItem(R.id.restart)?.isVisible = true floatingActionButton.setImageResource(R.drawable.ic_outline_pause) bottomAppBar.menu.findItem(R.id.stop).isVisible = true + floatingActionButton.animate().scaleX(1f).scaleY(1f).alpha(1f) .setInterpolator(OvershootInterpolator()).start() + sessionData.animate().translationY(0f).alpha(1f) + .setInterpolator(FastOutSlowInInterpolator()).setDuration(500).start() + recyclerView.animate().translationY(0f.px) + .setInterpolator(FastOutSlowInInterpolator()).setDuration(500).start() } SessionState.PAUSED -> { + state.text = "BREAK" + state.setTextColor(ContextCompat.getColor(requireContext(), R.color.blue)) sessionMenu?.findItem(R.id.restart)?.isVisible = true floatingActionButton.setImageResource(R.drawable.ic_outline_play) bottomAppBar.menu.findItem(R.id.stop).isVisible = true + floatingActionButton.animate().scaleX(1f).scaleY(1f).alpha(1f) .setInterpolator(OvershootInterpolator()).start() + sessionData.animate().translationY(0f).alpha(1f) + .setInterpolator(FastOutSlowInInterpolator()).setDuration(500).start() + recyclerView.animate().translationY(0f.px) + .setInterpolator(FastOutSlowInInterpolator()).setDuration(500).start() } SessionState.FINISHED -> { + state.text = "FINISHED" + state.setTextColor(ContextCompat.getColor(requireContext(), R.color.white)) sessionMenu?.findItem(R.id.restart)?.isVisible = true bottomAppBar.menu.findItem(R.id.stop).isVisible = false + floatingActionButton.animate().scaleX(0f).scaleY(0f).alpha(0f) .setInterpolator(FastOutSlowInInterpolator()).start() + sessionData.animate().translationY(0f).alpha(1f) + .setInterpolator(FastOutSlowInInterpolator()).setDuration(500).start() + recyclerView.animate().translationY(0f.px) + .setInterpolator(FastOutSlowInInterpolator()).setDuration(500).start() } } - sessionAdapter.updateRows(currentSession.adapterRows()) - recyclerView.smoothScrollToPosition(0) + updateAdapterUI(true) + } + + /** + * Update adapter UI + */ + private fun updateAdapterUI(scrollToTop: Boolean) { + + val diffResult = DiffUtil.calculateDiff(RowRepresentableDiffCallback(currentSession.adapterRows(), oldRows)) + sessionAdapter.updateRows(diffResult) + + oldRows.clear() + oldRows.addAll(currentSession.adapterRows()) + + if (scrollToTop) { + recyclerView.smoothScrollToPosition(0) + + } } /** * Update the state of the session (start / pause) */ private fun manageSessionState() { + + Timber.d("oldRows: $oldRows") + when (currentSession.getState()) { SessionState.PENDING -> { currentSession.startSession() diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/bottomsheet/BottomSheetListFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/bottomsheet/BottomSheetListFragment.kt index 7f083f62..abca4c07 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/bottomsheet/BottomSheetListFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/bottomsheet/BottomSheetListFragment.kt @@ -8,15 +8,14 @@ import io.realm.RealmResults import kotlinx.android.synthetic.main.bottom_sheet_list.* import kotlinx.android.synthetic.main.fragment_bottom_sheet.view.* import net.pokeranalytics.android.R -import net.pokeranalytics.android.model.realm.Game -import net.pokeranalytics.android.ui.adapter.components.LiveDataAdapter -import net.pokeranalytics.android.ui.adapter.components.LiveDataDataSource -import net.pokeranalytics.android.ui.adapter.components.LiveDataDelegate +import net.pokeranalytics.android.ui.adapter.components.* +import net.pokeranalytics.android.ui.view.RowRepresentable +import net.pokeranalytics.android.ui.view.RowViewType -class BottomSheetListFragment : BottomSheetFragment(), LiveDataDelegate { +class BottomSheetListFragment : BottomSheetFragment(), RowRepresentableDataSource, RowRepresentableDelegate { private var realmData: RealmResults<*>? = null - private lateinit var dataAdapter: LiveDataAdapter + private lateinit var dataAdapter: RowRepresentableAdapter override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) @@ -29,15 +28,32 @@ class BottomSheetListFragment : BottomSheetFragment(), LiveDataDelegate { dataAdapter.notifyDataSetChanged() } - override fun data(position: Int): LiveDataDataSource { + override fun rowRepresentableForPosition(position: Int): RowRepresentable { realmData?.let { - return it[position] as LiveDataDataSource + return it[position] as RowRepresentable } - //TODO: Change that - return Game() + return super.rowRepresentableForPosition(position) } - override fun onRowSelected(position: Int) { + override fun numberOfRows(): Int { + realmData?.let { + return it.size + } + return super.numberOfRows() + } + + override fun viewTypeForPosition(position: Int): Int { + return RowViewType.BOTTOM_SHEET_DATA.ordinal + } + + override fun indexForRow(row: RowRepresentable): Int { + realmData?.let { + return it.indexOf(row) + } + return super.indexForRow(row) + } + + override fun onIndexSelected(position: Int) { realmData?.let { val selectedData = it[position] selectedData?.let {data -> @@ -45,10 +61,7 @@ class BottomSheetListFragment : BottomSheetFragment(), LiveDataDelegate { dismiss() } } - } - - override fun size(): Int { - return realmData?.size ?: 0 + super.onIndexSelected(position) } /** @@ -69,7 +82,7 @@ class BottomSheetListFragment : BottomSheetFragment(), LiveDataDelegate { LayoutInflater.from(requireContext()).inflate(R.layout.bottom_sheet_list, view?.bottomSheetContainer, true) val viewManager = LinearLayoutManager(requireContext()) - dataAdapter = LiveDataAdapter(this, R.layout.row_bottom_sheet_title) + dataAdapter = RowRepresentableAdapter(this, this) reyclerView.apply { setHasFixedSize(true) diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/bottomsheet/BottomSheetListGameFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/bottomsheet/BottomSheetListGameFragment.kt index 08fcce2d..deb023f0 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/bottomsheet/BottomSheetListGameFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/bottomsheet/BottomSheetListGameFragment.kt @@ -4,22 +4,24 @@ import android.os.Bundle import android.view.LayoutInflater import android.view.View import androidx.recyclerview.widget.LinearLayoutManager +import com.google.android.material.chip.Chip import io.realm.RealmResults import kotlinx.android.synthetic.main.bottom_sheet_game_list.* import kotlinx.android.synthetic.main.fragment_bottom_sheet.view.* import net.pokeranalytics.android.R -import net.pokeranalytics.android.model.realm.Game -import net.pokeranalytics.android.ui.adapter.LimitTypesAdapter -import net.pokeranalytics.android.ui.adapter.components.LiveDataAdapter -import net.pokeranalytics.android.ui.adapter.components.LiveDataDataSource -import net.pokeranalytics.android.ui.adapter.components.LiveDataDelegate +import net.pokeranalytics.android.ui.adapter.components.RowRepresentableAdapter +import net.pokeranalytics.android.ui.adapter.components.RowRepresentableDataSource +import net.pokeranalytics.android.ui.adapter.components.RowRepresentableDelegate +import net.pokeranalytics.android.ui.view.RowRepresentable +import net.pokeranalytics.android.ui.view.RowViewType import timber.log.Timber -class BottomSheetListGameFragment : BottomSheetFragment(), LiveDataDelegate { +class BottomSheetListGameFragment : BottomSheetFragment(), RowRepresentableDataSource, RowRepresentableDelegate { private var realmData: RealmResults<*>? = null - private lateinit var dataAdapter: LiveDataAdapter + private lateinit var dataAdapter: RowRepresentableAdapter + private val values = ArrayList() override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) @@ -32,29 +34,45 @@ class BottomSheetListGameFragment : BottomSheetFragment(), LiveDataDelegate { dataAdapter.notifyDataSetChanged() } - override fun data(position: Int): LiveDataDataSource { + override fun getValue(): Any? { + return values + } + + override fun rowRepresentableForPosition(position: Int): RowRepresentable { realmData?.let { - return it[position] as LiveDataDataSource + return it[position] as RowRepresentable } - //TODO: Change that - return Game() + return super.rowRepresentableForPosition(position) } - override fun onRowSelected(position: Int) { + override fun numberOfRows(): Int { realmData?.let { - val selectedData = it[position] - selectedData?.let {data -> - bottomSheetDelegate.setValue(data, row) - dismiss() - } + return it.size } + return super.numberOfRows() } - override fun size(): Int { + override fun viewTypeForPosition(position: Int): Int { + return RowViewType.BOTTOM_SHEET_DATA.ordinal + } - Timber.d("Games: ${realmData?.size}") + override fun indexForRow(row: RowRepresentable): Int { + realmData?.let { + return it.indexOf(row) + } + return super.indexForRow(row) + } - return realmData?.size ?: 0 + override fun onIndexSelected(position: Int) { + realmData?.let { + val selectedData = it[position] + selectedData?.let { data -> + values[1] = data + bottomSheetDelegate.setValue(values, row) + dismiss() + } + } + super.onIndexSelected(position) } /** @@ -74,23 +92,28 @@ class BottomSheetListGameFragment : BottomSheetFragment(), LiveDataDelegate { LayoutInflater.from(requireContext()).inflate(R.layout.bottom_sheet_game_list, view?.bottomSheetContainer, true) + values.add(0, null) + values.add(1, null) + val limits = ArrayList() limits.addAll(resources.getStringArray(R.array.limit_short_name)) + chipGroup.removeAllViews() + for ((index, limit) in limits.withIndex()) { + val chip = Chip(requireContext()) + chip.text = limit + chip.id = index + chipGroup.addView(chip) + } - val viewManager1 = LinearLayoutManager(requireContext()) - val gameDataAdapter1 = LimitTypesAdapter(limits) - - recyclerView1.apply { - setHasFixedSize(true) - layoutManager = viewManager1 - adapter = gameDataAdapter1 - isNestedScrollingEnabled = false + chipGroup.setOnCheckedChangeListener { chipGroup, i -> + Timber.d("Chip selected: $i") + values[0] = i } val viewManager2 = LinearLayoutManager(requireContext()) - dataAdapter = LiveDataAdapter(this, R.layout.row_bottom_sheet_title) + dataAdapter = RowRepresentableAdapter(this, this) recyclerView2.apply { setHasFixedSize(true) diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/bottomsheet/BottomSheetTableSizeGridFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/bottomsheet/BottomSheetTableSizeGridFragment.kt index 868d17e7..38159ee5 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/bottomsheet/BottomSheetTableSizeGridFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/bottomsheet/BottomSheetTableSizeGridFragment.kt @@ -1,16 +1,131 @@ package net.pokeranalytics.android.ui.fragment.components.bottomsheet +import android.content.Context import android.os.Bundle import android.view.LayoutInflater import android.view.View import androidx.recyclerview.widget.GridLayoutManager import kotlinx.android.synthetic.main.bottom_sheet_grid.* import kotlinx.android.synthetic.main.fragment_bottom_sheet.view.* -import net.pokeranalytics.android.ui.adapter.TableSizeGridAdapter +import net.pokeranalytics.android.R +import net.pokeranalytics.android.ui.adapter.components.* import net.pokeranalytics.android.ui.view.GridSpacingItemDecoration +import net.pokeranalytics.android.ui.view.RowRepresentable +import net.pokeranalytics.android.ui.view.RowViewType import net.pokeranalytics.android.util.px +class TableSize(var numberOfPlayer:Int): RowRepresentable { + companion object { + val all = Array(8, init = + { index -> TableSize(index+2)}) + } + + override val resId: Int? + get() { + return if (this.numberOfPlayer == 2) { + R.string.heads_up + } else { + R.string.max + } + } + + override fun localizedTitle(context: Context): String { + this.resId?.let { + return if (this.numberOfPlayer == 2) { + context.getString(it) + } else { + "$this.numberOfPlayer$context.getString(it)" + } + } + return super.localizedTitle(context) + } + + override val viewType: Int + get() = RowViewType.TITLE_GRID.ordinal +} + +class BottomSheetTableSizeGridFragment : BottomSheetFragment(), RowRepresentableDataSource, RowRepresentableDelegate { + + private lateinit var dataAdapter: RowRepresentableAdapter + private var defaultSize: Int? = null + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + initData() + initUI() + } + + override fun onResume() { + super.onResume() + dataAdapter.notifyDataSetChanged() + } + + override fun getValue(): Any? { + return defaultSize + } + + /** + * Init data + */ + private fun initData() { + + val bottomSheetData = getData() + if (bottomSheetData.isNotEmpty() && bottomSheetData.first().defaultValue != null) { + defaultSize = bottomSheetData.first().defaultValue as Int? + } + } + /** + * Init UI + */ + private fun initUI() { + + setAddButtonVisible(false) + + LayoutInflater.from(requireContext()) + .inflate(net.pokeranalytics.android.R.layout.bottom_sheet_grid, view?.bottomSheetContainer, true) + + val viewManager = GridLayoutManager(requireContext(), 3) + dataAdapter = RowRepresentableAdapter(this, this) + + val spanCount = 3 + val spacing = 2.px + val includeEdge = false + + reyclerView.apply { + setHasFixedSize(true) + layoutManager = viewManager + adapter = dataAdapter + addItemDecoration(GridSpacingItemDecoration(spanCount, spacing, includeEdge)) + } + } + + override fun rowRepresentableForPosition(position: Int): RowRepresentable { + return TableSize.all[position] + } + + override fun indexForRow(row: RowRepresentable): Int { + return TableSize.all.indexOf(row) + } + + override fun numberOfRows(): Int { + return TableSize.all.size + } + + override fun onRowSelected(row: RowRepresentable) { + bottomSheetDelegate.setValue((this.row as TableSize).numberOfPlayer, this.row) + dismiss() + } + + override fun stringForRow(row: RowRepresentable): String { + this.context?.let { + return row.localizedTitle(it) + } + return "UNKNOWN CONTEXT FOR ROW $row" + } +} + +/* class BottomSheetTableSizeGridFragment : BottomSheetFragment() { private var dataList: ArrayList = ArrayList() @@ -79,4 +194,6 @@ class BottomSheetTableSizeGridFragment : BottomSheetFragment() { } -} \ No newline at end of file +} + + */ \ No newline at end of file diff --git a/app/src/main/java/net/pokeranalytics/android/ui/view/RowRepresentable.kt b/app/src/main/java/net/pokeranalytics/android/ui/view/RowRepresentable.kt index 6174bc78..f3770e73 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/view/RowRepresentable.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/view/RowRepresentable.kt @@ -29,11 +29,17 @@ interface Localizable { } } + +interface RowRepresentable : Displayable { + fun getDisplayName(): String { + return "UNKNOWN NAME" + } +} /** * An interface used so that enums values can be represented visually * as rows in RecyclerViews */ -interface RowRepresentable : Localizable { +interface Displayable: Localizable { /** * The type of view associated with the row */ diff --git a/app/src/main/java/net/pokeranalytics/android/ui/view/RowRepresentableDiffCallback.kt b/app/src/main/java/net/pokeranalytics/android/ui/view/RowRepresentableDiffCallback.kt index 21982d75..54ad05d3 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/view/RowRepresentableDiffCallback.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/view/RowRepresentableDiffCallback.kt @@ -2,12 +2,8 @@ package net.pokeranalytics.android.ui.view import androidx.annotation.Nullable import androidx.recyclerview.widget.DiffUtil -import net.pokeranalytics.android.ui.adapter.components.RowRepresentableDataSource -class RowRepresentableDiffCallback( - var newRows: List, var oldRows: List, - var rowRepresentableDataSource: RowRepresentableDataSource -) : +class RowRepresentableDiffCallback(var newRows: List, var oldRows: List) : DiffUtil.Callback() { override fun getOldListSize(): Int { diff --git a/app/src/main/java/net/pokeranalytics/android/ui/view/RowViewType.kt b/app/src/main/java/net/pokeranalytics/android/ui/view/RowViewType.kt index 73bf2d22..a0845f5d 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/view/RowViewType.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/view/RowViewType.kt @@ -3,12 +3,18 @@ package net.pokeranalytics.android.ui.view import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import androidx.appcompat.widget.AppCompatTextView +import androidx.constraintlayout.widget.ConstraintLayout import androidx.recyclerview.widget.RecyclerView +import kotlinx.android.synthetic.main.row_bottom_sheet_grid_title.view.* import kotlinx.android.synthetic.main.row_header_title_value.view.* +import kotlinx.android.synthetic.main.row_history_session.view.* import kotlinx.android.synthetic.main.row_title.view.* import kotlinx.android.synthetic.main.row_title_value.view.* import kotlinx.android.synthetic.main.row_title_value_action.view.* import net.pokeranalytics.android.R +import net.pokeranalytics.android.model.realm.Session +import net.pokeranalytics.android.ui.adapter.TableSizeGridAdapter import net.pokeranalytics.android.ui.adapter.components.RowRepresentableDataSource /** @@ -26,7 +32,11 @@ enum class RowViewType { EDIT_TEXT, TITLE, TITLE_VALUE, - TITLE_VALUE_ACTION; + TITLE_VALUE_ACTION, + DATA, + BOTTOM_SHEET_DATA, + TITLE_GRID, + ROW_SESSION; inner class FakeViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), BindableHolder { @@ -34,6 +44,35 @@ enum class RowViewType { } } + inner class RowSessionViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), + BindableHolder { + override fun bind(row: RowRepresentable, rowRepresentableDataSource: RowRepresentableDataSource?, listener: View.OnClickListener, actionListener: View.OnClickListener?) { + itemView.sessionRow.setData(row as Session) + itemView.sessionRow.setOnClickListener(listener) + } + } + + inner class CellSessionViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), BindableHolder { + override fun bind(row: RowRepresentable, rowRepresentableDataSource: RowRepresentableDataSource?, listener: View.OnClickListener, actionListener: View.OnClickListener?) { + itemView.title.text = row.localizedTitle(itemView.context) + itemView.container.setOnClickListener(listener) + } + } + + inner class DataViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), BindableHolder { + override fun bind(row: RowRepresentable, rowRepresentableDataSource: RowRepresentableDataSource?, listener: View.OnClickListener, actionListener: View.OnClickListener?) { + itemView.findViewById(R.id.rowTitle_title).text = row.getDisplayName() + itemView.findViewById(R.id.rowTitle_container).setOnClickListener(listener) + } + } + + inner class BottomSheetDataViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), BindableHolder { + override fun bind(row: RowRepresentable, rowRepresentableDataSource: RowRepresentableDataSource?, listener: View.OnClickListener, actionListener: View.OnClickListener?) { + itemView.findViewById(R.id.title).text = row.getDisplayName() + itemView.findViewById(R.id.container).setOnClickListener(listener) + } + } + inner class TitleViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), BindableHolder { override fun bind(row: RowRepresentable, rowRepresentableDataSource: RowRepresentableDataSource?, listener: View.OnClickListener, actionListener: View.OnClickListener?) { @@ -115,7 +154,32 @@ enum class RowViewType { false ) ) - + DATA -> DataViewHolder( + LayoutInflater.from(parent.context).inflate( + R.layout.row_title, + parent, + false + ) + ) + BOTTOM_SHEET_DATA -> BottomSheetDataViewHolder( + LayoutInflater.from(parent.context).inflate( + R.layout.row_bottom_sheet_title, + parent, + false + ) + ) + TITLE_GRID -> CellSessionViewHolder( + LayoutInflater.from(parent.context).inflate( + R.layout.row_bottom_sheet_grid_title, + parent, + false) + ) + ROW_SESSION -> RowSessionViewHolder( + LayoutInflater.from(parent.context).inflate( + R.layout.row_history_session, + parent, + false) + ) else -> FakeViewHolder(parent) } } diff --git a/app/src/main/java/net/pokeranalytics/android/ui/view/SessionRowView.kt b/app/src/main/java/net/pokeranalytics/android/ui/view/SessionRowView.kt index b1300f1c..b286df75 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/view/SessionRowView.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/view/SessionRowView.kt @@ -10,6 +10,7 @@ import net.pokeranalytics.android.R import net.pokeranalytics.android.model.realm.Session import net.pokeranalytics.android.util.getDayNumber import net.pokeranalytics.android.util.getShortDayName +import net.pokeranalytics.android.util.toCurrency class SessionRowView : FrameLayout { @@ -55,17 +56,9 @@ class SessionRowView : FrameLayout { rowHistorySession.dateDay.text = session.creationDate.getShortDayName() rowHistorySession.dateNumber.text = session.creationDate.getDayNumber() - // TODO - - var gameTitle = session.getGameTitle() - if (gameTitle.isEmpty()) { - gameTitle = "Game title here" - } - - rowHistorySession.gameType.text = gameTitle - - rowHistorySession.gameInfo.text = "Game info: duration, table size, ..." - rowHistorySession.gameResult.text = "$ 0" + rowHistorySession.gameType.text = session.getGameTitle() + rowHistorySession.gameInfo.text = session.getDuration(context) + rowHistorySession.gameResult.text = session.result?.netResult?.toCurrency() ?: "$0" } diff --git a/app/src/main/java/net/pokeranalytics/android/util/Extensions.kt b/app/src/main/java/net/pokeranalytics/android/util/Extensions.kt index 10fc83fe..1e8c5ab1 100644 --- a/app/src/main/java/net/pokeranalytics/android/util/Extensions.kt +++ b/app/src/main/java/net/pokeranalytics/android/util/Extensions.kt @@ -1,5 +1,6 @@ package net.pokeranalytics.android.util +import android.content.Context import android.content.res.Resources import android.widget.Toast import net.pokeranalytics.android.ui.activity.components.PokerAnalyticsActivity @@ -9,6 +10,8 @@ import java.text.DecimalFormat import java.text.SimpleDateFormat import java.util.* + + // Sizes val Int.dp: Int get() = (this / Resources.getSystem().displayMetrics.density).toInt() @@ -55,6 +58,20 @@ fun Date.getDayNumber() : String { fun Date.getShortDayName() : String { return SimpleDateFormat("EE", Locale.getDefault()).format(this) } +// Return the duration between two dates +fun Date.getDuration(context: Context, toDate: Date) : String { + val difference = (toDate.time - this.time).toInt() + val numOfDays = (difference / (1000 * 60 * 60 * 24)) + val hours = (difference / (1000 * 60 * 60)) + val minutes = (difference / (1000 * 60)) % 60 + val seconds = (difference / 1000) % 60 + + val hoursStr = if (hours < 10) "0$hours" else "$hours" + val minutesStr = if (minutes < 10) "0$minutes" else "$minutes" + val secondsStr = if (seconds < 10) "0$seconds" else "$seconds" + + return "$hoursStr:$minutesStr:$secondsStr" +} // Toast diff --git a/app/src/main/java/net/pokeranalytics/android/util/data/LiveRealmData.kt b/app/src/main/java/net/pokeranalytics/android/util/data/LiveRealmData.kt deleted file mode 100644 index 3edd4d69..00000000 --- a/app/src/main/java/net/pokeranalytics/android/util/data/LiveRealmData.kt +++ /dev/null @@ -1,21 +0,0 @@ -package net.pokeranalytics.android.util.data - -import androidx.lifecycle.LiveData -import io.realm.RealmChangeListener -import io.realm.RealmModel -import io.realm.RealmResults - - -class LiveRealmData(private val results: RealmResults) : LiveData>() { - private val listener = RealmChangeListener> { results -> value = results } - - override fun onActive() { - results.addChangeListener(listener) - value = results - } - - override fun onInactive() { - results.removeChangeListener(listener) - } - -} \ No newline at end of file diff --git a/app/src/main/java/net/pokeranalytics/android/util/data/Realm+Dao.kt b/app/src/main/java/net/pokeranalytics/android/util/data/Realm+Dao.kt deleted file mode 100644 index f09412c6..00000000 --- a/app/src/main/java/net/pokeranalytics/android/util/data/Realm+Dao.kt +++ /dev/null @@ -1,11 +0,0 @@ -@file:JvmName("RealmUtils") // pretty name for utils class if called from -package net.pokeranalytics.android.util.data - -import io.realm.Realm -import io.realm.RealmModel -import io.realm.RealmResults -import net.pokeranalytics.android.model.realm.SessionDao - -fun Realm.sessionDao(): SessionDao = SessionDao(this) - -fun RealmResults.asLiveData() = LiveRealmData(this) \ No newline at end of file diff --git a/app/src/main/res/color/chips_background_states.xml b/app/src/main/res/color/chips_background_states.xml new file mode 100755 index 00000000..7d57a042 --- /dev/null +++ b/app/src/main/res/color/chips_background_states.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/font/roboto_medium.xml b/app/src/main/res/font/roboto_medium.xml new file mode 100644 index 00000000..59df90bc --- /dev/null +++ b/app/src/main/res/font/roboto_medium.xml @@ -0,0 +1,7 @@ + + + diff --git a/app/src/main/res/font/roboto_mono_medium.xml b/app/src/main/res/font/roboto_mono_medium.xml new file mode 100644 index 00000000..485dd2d9 --- /dev/null +++ b/app/src/main/res/font/roboto_mono_medium.xml @@ -0,0 +1,7 @@ + + + diff --git a/app/src/main/res/layout/bottom_sheet_game_list.xml b/app/src/main/res/layout/bottom_sheet_game_list.xml index 7f658f14..7f5a61b1 100644 --- a/app/src/main/res/layout/bottom_sheet_game_list.xml +++ b/app/src/main/res/layout/bottom_sheet_game_list.xml @@ -2,16 +2,62 @@ - + app:layout_constraintTop_toTopOf="parent"> + + + + + + + + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@+id/chips" /> \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_editable_data.xml b/app/src/main/res/layout/fragment_editable_data.xml index ed7b8bf4..bab049a9 100644 --- a/app/src/main/res/layout/fragment_editable_data.xml +++ b/app/src/main/res/layout/fragment_editable_data.xml @@ -1,74 +1,61 @@ + xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="match_parent"> + android:id="@+id/nestedScrollView" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:fillViewport="true" + app:layout_behavior="@string/appbar_scrolling_view_behavior"> + android:layout_width="match_parent" + android:layout_height="wrap_content"> + android:id="@+id/recyclerView" + android:layout_width="0dp" + android:layout_height="0dp" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" /> + android:id="@+id/appBar" + android:layout_width="match_parent" + android:layout_height="128dp" + android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"> + android:id="@+id/collapsingToolbar" + android:layout_width="match_parent" + android:layout_height="match_parent" + app:collapsedTitleTextAppearance="@style/PokerAnalyticsTheme.Toolbar.CollapsedTitleAppearance" + app:contentScrim="?attr/colorPrimary" + app:expandedTitleGravity="bottom" + app:expandedTitleMarginStart="72dp" + app:expandedTitleTextAppearance="@style/PokerAnalyticsTheme.Toolbar.ExpandedTitleAppearance" + app:layout_scrollFlags="scroll|exitUntilCollapsed|snap"> + android:id="@+id/toolbar" + android:layout_width="match_parent" + android:layout_height="?attr/actionBarSize" + app:layout_collapseMode="pin" + app:title="Poker Analytics" + app:titleTextColor="@color/white" /> -