From 0413dbffa2b6904ede759ed883213f02d324d56c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kuba=20Szczodrzy=C5=84ski?= Date: Sun, 5 Apr 2020 21:40:12 +0200 Subject: [PATCH] [Messages] Implement saving list position on message open. --- .../szczodrzynski/edziennik/MainActivity.kt | 13 ++++------ .../edziennik/data/db/dao/TeacherDao.kt | 9 ++++--- .../lazypager/FragmentLazyPagerAdapter.kt | 2 +- .../ui/modules/base/lazypager/LazyFragment.kt | 2 ++ .../edziennik/ui/modules/debug/LabFragment.kt | 5 ++++ .../ui/modules/messages/MessagesFragment.kt | 25 +++++++++++++++++++ .../modules/messages/MessagesListFragment.kt | 22 ++++++++++++++++ app/src/main/res/layout/lab_fragment.xml | 7 ++++++ 8 files changed, 72 insertions(+), 13 deletions(-) diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/MainActivity.kt b/app/src/main/java/pl/szczodrzynski/edziennik/MainActivity.kt index d229e8c9..85b4f887 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/MainActivity.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/MainActivity.kt @@ -20,7 +20,6 @@ import androidx.appcompat.widget.PopupMenu import androidx.core.graphics.ColorUtils import androidx.lifecycle.Observer import androidx.navigation.NavOptions -import androidx.recyclerview.widget.RecyclerView import com.danimahardhika.cafebar.CafeBar import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.mikepenz.iconics.IconicsColor @@ -69,7 +68,6 @@ import pl.szczodrzynski.edziennik.ui.modules.homework.HomeworkFragment import pl.szczodrzynski.edziennik.ui.modules.login.LoginActivity import pl.szczodrzynski.edziennik.ui.modules.messages.MessageFragment import pl.szczodrzynski.edziennik.ui.modules.messages.MessagesFragment -import pl.szczodrzynski.edziennik.ui.modules.messages.MessagesListFragmentOld import pl.szczodrzynski.edziennik.ui.modules.messages.compose.MessagesComposeFragment import pl.szczodrzynski.edziennik.ui.modules.notifications.NotificationsListFragment import pl.szczodrzynski.edziennik.ui.modules.settings.ProfileManagerFragment @@ -889,9 +887,6 @@ class MainActivity : AppCompatActivity(), CoroutineScope { } app.profileLoad(id) { MessagesFragment.pageSelection = -1 - MessagesListFragmentOld.tapPositions = intArrayOf(RecyclerView.NO_POSITION, RecyclerView.NO_POSITION) - MessagesListFragmentOld.topPositions = intArrayOf(RecyclerView.NO_POSITION, RecyclerView.NO_POSITION) - MessagesListFragmentOld.bottomPositions = intArrayOf(RecyclerView.NO_POSITION, RecyclerView.NO_POSITION) setDrawerItems() // the drawer profile is updated automatically when the drawer item is clicked @@ -916,9 +911,10 @@ class MainActivity : AppCompatActivity(), CoroutineScope { loadTarget(target, arguments) } } - private fun loadTarget(target: NavTarget, arguments: Bundle? = null) { - d("NavDebug", "loadTarget(target = $target, arguments = $arguments)") + private fun loadTarget(target: NavTarget, args: Bundle? = null) { + d("NavDebug", "loadTarget(target = $target, args = $args)") + val arguments = args ?: navBackStack.firstOrNull { it.first.id == target.id }?.second ?: Bundle() bottomSheet.close() bottomSheet.removeAllContextual() bottomSheet.toggleGroupEnabled = false @@ -966,6 +962,7 @@ class MainActivity : AppCompatActivity(), CoroutineScope { navBackStack.removeAt(navBackStack.lastIndex) } navTarget = target + navArguments = arguments return@let null }?.let { @@ -975,7 +972,7 @@ class MainActivity : AppCompatActivity(), CoroutineScope { R.anim.task_open_enter, R.anim.task_open_exit ) - navBackStack.add(navTarget to arguments) + navBackStack.add(navTarget to navArguments) navTarget = target navArguments = arguments } diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/db/dao/TeacherDao.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/db/dao/TeacherDao.kt index d886cd2d..27b9b869 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/data/db/dao/TeacherDao.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/db/dao/TeacherDao.kt @@ -1,10 +1,8 @@ package pl.szczodrzynski.edziennik.data.db.dao import androidx.lifecycle.LiveData -import androidx.room.Dao -import androidx.room.Insert -import androidx.room.OnConflictStrategy -import androidx.room.Query +import androidx.room.* +import androidx.sqlite.db.SupportSQLiteQuery import pl.szczodrzynski.edziennik.data.db.entity.Teacher @Dao @@ -18,6 +16,9 @@ interface TeacherDao { @Insert(onConflict = OnConflictStrategy.IGNORE) fun addAllIgnore(teacherList: List) + @RawQuery + fun query(query: SupportSQLiteQuery): Int + @Query("DELETE FROM teachers WHERE profileId = :profileId") fun clear(profileId: Int) diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/base/lazypager/FragmentLazyPagerAdapter.kt b/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/base/lazypager/FragmentLazyPagerAdapter.kt index 4aae09ee..d6205596 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/base/lazypager/FragmentLazyPagerAdapter.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/base/lazypager/FragmentLazyPagerAdapter.kt @@ -10,7 +10,7 @@ import androidx.swiperefreshlayout.widget.SwipeRefreshLayout class FragmentLazyPagerAdapter( fragmentManager: FragmentManager, swipeRefreshLayout: SwipeRefreshLayout, - private val fragments: List> + val fragments: List> ) : LazyPagerAdapter(fragmentManager, swipeRefreshLayout) { override fun getPage(position: Int) = fragments[position].first override fun getPageTitle(position: Int) = fragments[position].second diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/base/lazypager/LazyFragment.kt b/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/base/lazypager/LazyFragment.kt index 1d011510..b5f26172 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/base/lazypager/LazyFragment.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/base/lazypager/LazyFragment.kt @@ -4,6 +4,7 @@ package pl.szczodrzynski.edziennik.ui.modules.base.lazypager +import android.os.Bundle import androidx.fragment.app.Fragment import androidx.recyclerview.widget.RecyclerView @@ -11,6 +12,7 @@ abstract class LazyFragment : Fragment() { private var isPageCreated = false internal var position = -1 internal var swipeRefreshLayoutCallback: ((position: Int, isEnabled: Boolean) -> Unit)? = null + internal var onPageDestroy: ((position: Int, outState: Bundle?) -> Unit?)? = null /** * Called when the page is first shown, or if previous diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/debug/LabFragment.kt b/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/debug/LabFragment.kt index 7fbea1a6..35f16c20 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/debug/LabFragment.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/debug/LabFragment.kt @@ -9,6 +9,7 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.fragment.app.Fragment +import androidx.sqlite.db.SimpleSQLiteQuery import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Job @@ -55,5 +56,9 @@ class LabFragment : Fragment(), CoroutineScope { } } } + + b.rodo.onClick { + app.db.teacherDao().query(SimpleSQLiteQuery("UPDATE teachers SET teacherSurname = \"\" WHERE profileId = ${App.profileId}")) + } } } diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/messages/MessagesFragment.kt b/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/messages/MessagesFragment.kt index 4e2e50e7..043cce7d 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/messages/MessagesFragment.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/messages/MessagesFragment.kt @@ -52,20 +52,34 @@ class MessagesFragment : Fragment(), CoroutineScope { return } + val args = arguments + val pagerAdapter = FragmentLazyPagerAdapter( fragmentManager ?: return, b.refreshLayout, listOf( MessagesListFragment().apply { + onPageDestroy = this@MessagesFragment.onPageDestroy arguments = Bundle("messageType" to Message.TYPE_RECEIVED) + args?.getBundle("page0")?.let { + arguments?.putAll(it) + } } to getString(R.string.messages_tab_received), MessagesListFragment().apply { + onPageDestroy = this@MessagesFragment.onPageDestroy arguments = Bundle("messageType" to Message.TYPE_SENT) + args?.getBundle("page1")?.let { + arguments?.putAll(it) + } } to getString(R.string.messages_tab_sent), MessagesListFragment().apply { + onPageDestroy = this@MessagesFragment.onPageDestroy arguments = Bundle("messageType" to Message.TYPE_DELETED) + args?.getBundle("page2")?.let { + arguments?.putAll(it) + } } to getString(R.string.messages_tab_deleted) ) ) @@ -93,4 +107,15 @@ class MessagesFragment : Fragment(), CoroutineScope { activity.gainAttentionFAB() } + + private val onPageDestroy = { position: Int, outState: Bundle? -> + arguments?.putBundle("page$position", outState) + } + + override fun onDestroy() { + super.onDestroy() + (b.viewPager.adapter as? FragmentLazyPagerAdapter)?.fragments?.forEach { + it.first.onDestroy() + } + } } diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/messages/MessagesListFragment.kt b/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/messages/MessagesListFragment.kt index 02831fda..3f40a629 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/messages/MessagesListFragment.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/messages/MessagesListFragment.kt @@ -11,6 +11,7 @@ import android.view.ViewGroup import androidx.core.view.isVisible import androidx.lifecycle.Observer import androidx.recyclerview.widget.LinearLayoutManager +import androidx.recyclerview.widget.RecyclerView.NO_POSITION import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Job @@ -50,6 +51,8 @@ class MessagesListFragment : LazyFragment(), CoroutineScope { override fun onPageCreated(): Boolean { startCoroutineTimer(100L) { val messageType = arguments.getInt("messageType", Message.TYPE_RECEIVED) + var topPosition = arguments.getInt("topPosition", NO_POSITION) + var bottomPosition = arguments.getInt("bottomPosition", NO_POSITION) teachers = withContext(Dispatchers.Default) { app.db.teacherDao().getAllNow(App.profileId) @@ -87,6 +90,16 @@ class MessagesListFragment : LazyFragment(), CoroutineScope { adapter.notifyDataSetChanged() setSwipeToRefresh(messageType in Message.TYPE_RECEIVED..Message.TYPE_SENT && items.isNullOrEmpty()) + (b.list.layoutManager as? LinearLayoutManager)?.let { layoutManager -> + if (topPosition != NO_POSITION && topPosition > layoutManager.findLastCompletelyVisibleItemPosition()) { + b.list.scrollToPosition(topPosition) + } else if (bottomPosition != NO_POSITION && bottomPosition < layoutManager.findFirstCompletelyVisibleItemPosition()) { + b.list.scrollToPosition(bottomPosition) + } + topPosition = NO_POSITION + bottomPosition = NO_POSITION + } + // show/hide relevant views b.progressBar.isVisible = false if (items.isNullOrEmpty()) { @@ -98,4 +111,13 @@ class MessagesListFragment : LazyFragment(), CoroutineScope { } }) }; return true } + + override fun onDestroy() { + super.onDestroy() + if (!isAdded) return + onPageDestroy?.invoke(position, Bundle( + "topPosition" to (b.list.layoutManager as? LinearLayoutManager)?.findFirstCompletelyVisibleItemPosition(), + "bottomPosition" to (b.list.layoutManager as? LinearLayoutManager)?.findLastCompletelyVisibleItemPosition() + )) + } } diff --git a/app/src/main/res/layout/lab_fragment.xml b/app/src/main/res/layout/lab_fragment.xml index e664e76c..d6988c69 100644 --- a/app/src/main/res/layout/lab_fragment.xml +++ b/app/src/main/res/layout/lab_fragment.xml @@ -40,6 +40,13 @@ android:layout_height="wrap_content" android:text="Set last 10 as unseen" android:textAllCaps="false" /> + +