diff options
Diffstat (limited to 'app/src/main/java/foundation/e/advancedprivacy/features/trackers/TrackersFragment.kt')
-rw-r--r-- | app/src/main/java/foundation/e/advancedprivacy/features/trackers/TrackersFragment.kt | 172 |
1 files changed, 109 insertions, 63 deletions
diff --git a/app/src/main/java/foundation/e/advancedprivacy/features/trackers/TrackersFragment.kt b/app/src/main/java/foundation/e/advancedprivacy/features/trackers/TrackersFragment.kt index 132fa3b..b016c5e 100644 --- a/app/src/main/java/foundation/e/advancedprivacy/features/trackers/TrackersFragment.kt +++ b/app/src/main/java/foundation/e/advancedprivacy/features/trackers/TrackersFragment.kt @@ -28,6 +28,7 @@ import android.text.style.ClickableSpan import android.text.style.ForegroundColorSpan import android.text.style.UnderlineSpan import android.view.View +import android.view.ViewTreeObserver import android.widget.Toast import androidx.core.content.ContextCompat import androidx.core.view.isVisible @@ -35,12 +36,13 @@ import androidx.lifecycle.Lifecycle import androidx.lifecycle.lifecycleScope import androidx.lifecycle.repeatOnLifecycle import androidx.navigation.fragment.findNavController -import androidx.recyclerview.widget.LinearLayoutManager +import androidx.viewpager2.widget.ViewPager2 +import com.google.android.material.tabs.TabLayoutMediator import foundation.e.advancedprivacy.R -import foundation.e.advancedprivacy.common.AppsAdapter import foundation.e.advancedprivacy.common.GraphHolder import foundation.e.advancedprivacy.common.NavToolbarFragment -import foundation.e.advancedprivacy.common.setToolTipForAsterisk +import foundation.e.advancedprivacy.common.extensions.findViewHolderForAdapterPosition +import foundation.e.advancedprivacy.common.extensions.updatePagerHeightForChild import foundation.e.advancedprivacy.databinding.FragmentTrackersBinding import foundation.e.advancedprivacy.databinding.TrackersItemGraphBinding import foundation.e.advancedprivacy.domain.entities.TrackersPeriodicStatistics @@ -50,32 +52,98 @@ import org.koin.androidx.viewmodel.ext.android.viewModel class TrackersFragment : NavToolbarFragment(R.layout.fragment_trackers) { private val viewModel: TrackersViewModel by viewModel() - private var _binding: FragmentTrackersBinding? = null - private val binding get() = _binding!! + private lateinit var binding: FragmentTrackersBinding private var dayGraphHolder: GraphHolder? = null private var monthGraphHolder: GraphHolder? = null private var yearGraphHolder: GraphHolder? = null + private lateinit var tabAdapter: ListsTabPagerAdapter + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - _binding = FragmentTrackersBinding.bind(view) + binding = FragmentTrackersBinding.bind(view) dayGraphHolder = GraphHolder(binding.graphDay.graph, requireContext(), false) monthGraphHolder = GraphHolder(binding.graphMonth.graph, requireContext(), false) yearGraphHolder = GraphHolder(binding.graphYear.graph, requireContext(), false) - binding.apps.apply { - layoutManager = LinearLayoutManager(requireContext()) - setHasFixedSize(true) - adapter = AppsAdapter(R.layout.trackers_item_app) { appUid -> - viewModel.submitAction( - TrackersViewModel.Action.ClickAppAction(appUid) - ) + tabAdapter = ListsTabPagerAdapter(requireContext(), viewModel) + binding.listsPager.adapter = tabAdapter + + TabLayoutMediator(binding.listsTabs, binding.listsPager) { tab, position -> + tab.text = getString( + when (position) { + TAB_APPS -> R.string.trackers_toggle_list_apps + else -> R.string.trackers_toggle_list_trackers + } + ) + }.attach() + + binding.listsPager.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() { + override fun onPageScrollStateChanged(state: Int) { + super.onPageScrollStateChanged(state) + if (state == ViewPager2.SCROLL_STATE_IDLE) { + updatePagerHeight() + } + } + }) + + setupTrackersInfos() + + listenViewModel() + } + + private fun listenViewModel() { + with(viewLifecycleOwner) { + lifecycleScope.launch { + repeatOnLifecycle(Lifecycle.State.STARTED) { + render(viewModel.state.value) + viewModel.state.collect(::render) + } + } + + lifecycleScope.launch { + repeatOnLifecycle(Lifecycle.State.STARTED) { + viewModel.singleEvents.collect(::handleEvents) + } + } + + lifecycleScope.launch { + repeatOnLifecycle(Lifecycle.State.STARTED) { + viewModel.navigate.collect(findNavController()::navigate) + } + } + + lifecycleScope.launch { + repeatOnLifecycle(Lifecycle.State.STARTED) { + viewModel.doOnStartedState() + } + } + } + } + + private fun handleEvents(event: TrackersViewModel.SingleEvent) { + when (event) { + is TrackersViewModel.SingleEvent.ErrorEvent -> { + displayToast(event.error) + } + is TrackersViewModel.SingleEvent.OpenUrl -> { + try { + startActivity(Intent(Intent.ACTION_VIEW, event.url)) + } catch (e: ActivityNotFoundException) { + Toast.makeText( + requireContext(), + R.string.error_no_activity_view_url, + Toast.LENGTH_SHORT + ).show() + } } } + } + private fun setupTrackersInfos() { val infoText = getString(R.string.trackers_info) val moreText = getString(R.string.trackers_info_more) @@ -92,7 +160,7 @@ class TrackersFragment : NavToolbarFragment(R.layout.fragment_trackers) { spannable.setSpan( object : ClickableSpan() { override fun onClick(p0: View) { - viewModel.submitAction(TrackersViewModel.Action.ClickLearnMore) + viewModel.onClickLearnMore() } }, startIndex, endIndex, Spannable.SPAN_INCLUSIVE_EXCLUSIVE @@ -104,71 +172,44 @@ class TrackersFragment : NavToolbarFragment(R.layout.fragment_trackers) { movementMethod = LinkMovementMethod.getInstance() text = spannable } + } - setToolTipForAsterisk( - textView = binding.trackersAppsListTitle, - textId = R.string.trackers_applist_title, - tooltipTextId = R.string.trackers_applist_infos - ) - - viewLifecycleOwner.lifecycleScope.launch { - viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) { - render(viewModel.state.value) - viewModel.state.collect(::render) + private var oldPosition = -1 + private val layoutListener = ViewTreeObserver.OnGlobalLayoutListener { + binding.listsPager.findViewHolderForAdapterPosition(binding.listsPager.currentItem) + .let { currentViewHolder -> + currentViewHolder?.itemView?.let { binding.listsPager.updatePagerHeightForChild(it) } } - } + } - viewLifecycleOwner.lifecycleScope.launch { - viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) { - viewModel.singleEvents.collect { event -> - when (event) { - is TrackersViewModel.SingleEvent.ErrorEvent -> { - displayToast(event.error) - } - is TrackersViewModel.SingleEvent.OpenUrl -> { - try { - startActivity(Intent(Intent.ACTION_VIEW, event.url)) - } catch (e: ActivityNotFoundException) { - Toast.makeText( - requireContext(), - R.string.error_no_activity_view_url, - Toast.LENGTH_SHORT - ).show() - } - } - } - } + private fun updatePagerHeight() { + with(binding.listsPager) { + val position = currentItem + if (position == oldPosition) return + if (oldPosition > 0) { + val oldItem = findViewHolderForAdapterPosition(oldPosition)?.itemView + oldItem?.viewTreeObserver?.removeOnGlobalLayoutListener(layoutListener) } - } - viewLifecycleOwner.lifecycleScope.launch { - viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) { - viewModel.navigate.collect(findNavController()::navigate) - } - } + val newItem = findViewHolderForAdapterPosition(position)?.itemView + newItem?.viewTreeObserver?.addOnGlobalLayoutListener(layoutListener) - viewLifecycleOwner.lifecycleScope.launch { - viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) { - viewModel.doOnStartedState() - } + oldPosition = position + adapter?.notifyItemChanged(position) } } private fun displayToast(message: String) { - Toast.makeText(requireContext(), message, Toast.LENGTH_SHORT) - .show() + Toast.makeText(requireContext(), message, Toast.LENGTH_SHORT).show() } private fun render(state: TrackersState) { state.dayStatistics?.let { renderGraph(it, dayGraphHolder!!, binding.graphDay) } state.monthStatistics?.let { renderGraph(it, monthGraphHolder!!, binding.graphMonth) } state.yearStatistics?.let { renderGraph(it, yearGraphHolder!!, binding.graphYear) } + updatePagerHeight() - state.apps?.let { - binding.apps.post { - (binding.apps.adapter as AppsAdapter?)?.dataSet = it - } - } + tabAdapter.updateDataSet(state.apps, state.trackers) } private fun renderGraph( @@ -191,9 +232,14 @@ class TrackersFragment : NavToolbarFragment(R.layout.fragment_trackers) { override fun onDestroyView() { super.onDestroyView() + kotlin.runCatching { + if (oldPosition >= 0) { + val oldItem = binding.listsPager.findViewHolderForAdapterPosition(oldPosition) + oldItem?.itemView?.viewTreeObserver?.removeOnGlobalLayoutListener(layoutListener) + } + } dayGraphHolder = null monthGraphHolder = null yearGraphHolder = null - _binding = null } } |