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 343dfcd9..763b6a51 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 @@ -2,10 +2,12 @@ package net.pokeranalytics.android.ui.adapter.components import android.view.View import android.view.ViewGroup +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.RowViewType +import net.pokeranalytics.android.ui.view.RowRepresentableDiffCallback /** * An interface used to provide RowRepresentableAdapter content and value in the form of rows @@ -62,7 +64,10 @@ interface RowRepresentableDelegate { * @param rowRepresentableDataSource the datasource providing rows * @param rowRepresentableDelegate the delegate, notified of UI actions */ -class RowRepresentableAdapter(var rowRepresentableDataSource: RowRepresentableDataSource, var rowRepresentableDelegate: RowRepresentableDelegate? = null) : +class RowRepresentableAdapter( + var rowRepresentableDataSource: RowRepresentableDataSource, + var rowRepresentableDelegate: RowRepresentableDelegate? = null +) : RecyclerView.Adapter() { /** @@ -119,4 +124,18 @@ class RowRepresentableAdapter(var rowRepresentableDataSource: RowRepresentableDa notifyDataSetChanged() } + /** + * Update UI + */ + fun updateRows(newRows: ArrayList) { + val diffResult = DiffUtil.calculateDiff( + RowRepresentableDiffCallback( + newRows, + rows + ) + ) + this.rows = newRows + diffResult.dispatchUpdatesTo(this) + } + } \ 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 d11c4424..a35add77 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 @@ -5,7 +5,6 @@ import android.view.* import android.view.animation.OvershootInterpolator import android.widget.Toast import androidx.interpolator.view.animation.FastOutSlowInInterpolator -import androidx.recyclerview.widget.LinearLayoutManager import io.realm.kotlin.where import kotlinx.android.synthetic.main.fragment_session.* import net.pokeranalytics.android.R @@ -23,6 +22,7 @@ import net.pokeranalytics.android.ui.fragment.components.bottomsheet.BottomSheet import net.pokeranalytics.android.ui.fragment.components.bottomsheet.BottomSheetFragment import net.pokeranalytics.android.ui.view.RowRepresentable import net.pokeranalytics.android.ui.view.SessionRow +import net.pokeranalytics.android.ui.view.SmoothScrollLinearLayoutManager import net.pokeranalytics.android.util.toast import timber.log.Timber import java.util.* @@ -123,8 +123,7 @@ class SessionFragment : PokerAnalyticsFragment(), RowRepresentableDelegate, Bott activity.supportActionBar?.setDisplayHomeAsUpEnabled(true) setHasOptionsMenu(true) - val viewManager = LinearLayoutManager(requireContext()) - + val viewManager = SmoothScrollLinearLayoutManager(requireContext()) recyclerView.apply { setHasFixedSize(true) layoutManager = viewManager @@ -186,7 +185,8 @@ class SessionFragment : PokerAnalyticsFragment(), RowRepresentableDelegate, Bott } } - sessionAdapter.refreshAllRows() + sessionAdapter.updateRows(currentSession.adapterRows()) + recyclerView.smoothScrollToPosition(0) } /** 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 new file mode 100644 index 00000000..d5547a5b --- /dev/null +++ b/app/src/main/java/net/pokeranalytics/android/ui/view/RowRepresentableDiffCallback.kt @@ -0,0 +1,32 @@ +package net.pokeranalytics.android.ui.view + +import androidx.annotation.Nullable +import androidx.recyclerview.widget.DiffUtil +import net.pokeranalytics.android.ui.view.RowRepresentable +import timber.log.Timber + +class RowRepresentableDiffCallback(var newRows: List, var oldRows: List) : + DiffUtil.Callback() { + + override fun getOldListSize(): Int { + return oldRows.size + } + + override fun getNewListSize(): Int { + return newRows.size + } + + override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean { + return oldRows[oldItemPosition] === newRows[newItemPosition] + } + + override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean { + return oldRows[oldItemPosition] == newRows[newItemPosition] + } + + @Nullable + override fun getChangePayload(oldItemPosition: Int, newItemPosition: Int): Any? { + //you can return particular field for changed item. + return super.getChangePayload(oldItemPosition, newItemPosition) + } +} \ No newline at end of file diff --git a/app/src/main/java/net/pokeranalytics/android/ui/view/SmoothScrollLinearLayoutManager.kt b/app/src/main/java/net/pokeranalytics/android/ui/view/SmoothScrollLinearLayoutManager.kt new file mode 100644 index 00000000..3311f731 --- /dev/null +++ b/app/src/main/java/net/pokeranalytics/android/ui/view/SmoothScrollLinearLayoutManager.kt @@ -0,0 +1,46 @@ +package net.pokeranalytics.android.ui.view + +import android.content.Context +import android.graphics.PointF +import android.util.DisplayMetrics +import androidx.recyclerview.widget.LinearLayoutManager +import androidx.recyclerview.widget.LinearSmoothScroller +import androidx.recyclerview.widget.RecyclerView + +/** + * SmoothScrollLinearLayoutManager + */ +class SmoothScrollLinearLayoutManager(context: Context) : + LinearLayoutManager(context, RecyclerView.VERTICAL, false) { + + companion object { + private const val MILLISECONDS_PER_INCH = 100f + } + + override fun smoothScrollToPosition( + recyclerView: RecyclerView, state: RecyclerView.State?, + position: Int + ) { + val smoothScroller = TopSnappedSmoothScroller(recyclerView.context) + smoothScroller.targetPosition = position + startSmoothScroll(smoothScroller) + } + + private inner class TopSnappedSmoothScroller(context: Context) : LinearSmoothScroller(context) { + + override fun computeScrollVectorForPosition(targetPosition: Int): PointF? { + return this@SmoothScrollLinearLayoutManager + .computeScrollVectorForPosition(targetPosition) + } + + override fun getVerticalSnapPreference(): Int { + return SNAP_TO_START + } + + override fun calculateSpeedPerPixel(displayMetrics: DisplayMetrics): Float { + return MILLISECONDS_PER_INCH / displayMetrics.densityDpi + } + } + + +}