From 13b77657c3d17500e424d7dabf149be192628c6b Mon Sep 17 00:00:00 2001 From: gedoor Date: Sat, 5 Jun 2021 11:10:58 +0800 Subject: [PATCH] =?UTF-8?q?viewPager2=203=E5=B1=82=E5=B5=8C=E5=A5=97?= =?UTF-8?q?=E6=9C=89=E9=97=AE=E9=A2=98,=E4=B9=A6=E6=9E=B6=E6=8D=A2?= =?UTF-8?q?=E5=9B=9EviewPager?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../io/legado/app/ui/main/MainActivity.kt | 60 ++++++++------ .../ui/main/bookshelf/BookshelfFragment.kt | 45 +++++----- .../legado/app/ui/main/bookshelf/RootView.kt | 82 ------------------- ...shelfFragment.kt => BookshelfFragment1.kt} | 2 +- app/src/main/res/layout/activity_main.xml | 2 +- .../main/res/layout/fragment_bookshelf.xml | 6 +- 6 files changed, 57 insertions(+), 140 deletions(-) delete mode 100644 app/src/main/java/io/legado/app/ui/main/bookshelf/RootView.kt rename app/src/main/java/io/legado/app/ui/main/bookshelf1/{BookshelfFragment.kt => BookshelfFragment1.kt} (99%) diff --git a/app/src/main/java/io/legado/app/ui/main/MainActivity.kt b/app/src/main/java/io/legado/app/ui/main/MainActivity.kt index 9741e726d..cf4d16957 100644 --- a/app/src/main/java/io/legado/app/ui/main/MainActivity.kt +++ b/app/src/main/java/io/legado/app/ui/main/MainActivity.kt @@ -1,12 +1,16 @@ +@file:Suppress("DEPRECATION") + package io.legado.app.ui.main import android.os.Bundle import android.view.KeyEvent import android.view.MenuItem +import android.view.ViewGroup import androidx.activity.viewModels import androidx.fragment.app.Fragment -import androidx.viewpager2.adapter.FragmentStateAdapter -import androidx.viewpager2.widget.ViewPager2 +import androidx.fragment.app.FragmentManager +import androidx.fragment.app.FragmentStatePagerAdapter +import androidx.viewpager.widget.ViewPager import com.google.android.material.bottomnavigation.BottomNavigationView import io.legado.app.BuildConfig import io.legado.app.R @@ -40,7 +44,7 @@ class MainActivity : VMBaseActivity(), private var bookshelfReselected: Long = 0 private var exploreReselected: Long = 0 private var pagePosition = 0 - private val fragmentMap = hashMapOf() + private val fragmentMap = hashMapOf() private var bottomMenuCount = 2 private val realPositions = arrayOf(0, 1, 2, 3) @@ -54,8 +58,8 @@ class MainActivity : VMBaseActivity(), ATH.applyEdgeEffectColor(viewPagerMain) ATH.applyBottomNavigationColor(bottomNavigationView) viewPagerMain.offscreenPageLimit = 3 - viewPagerMain.adapter = TabFragmentPageAdapter() - viewPagerMain.registerOnPageChangeCallback(PageChangeCallback()) + viewPagerMain.adapter = TabFragmentPageAdapter(supportFragmentManager) + viewPagerMain.addOnPageChangeListener(PageChangeCallback()) bottomNavigationView.elevation = if (AppConfig.elevation < 0) elevation else AppConfig.elevation.toFloat() bottomNavigationView.setOnNavigationItemSelectedListener(this@MainActivity) @@ -110,10 +114,6 @@ class MainActivity : VMBaseActivity(), } } - fun getViewPager(): ViewPager2 { - return binding.viewPagerMain - } - private fun upVersion() { if (LocalConfig.versionCode != appInfo.versionCode) { LocalConfig.versionCode = appInfo.versionCode @@ -210,38 +210,44 @@ class MainActivity : VMBaseActivity(), } } - private inner class PageChangeCallback : ViewPager2.OnPageChangeCallback() { + private inner class PageChangeCallback : ViewPager.SimpleOnPageChangeListener() { + override fun onPageSelected(position: Int) { pagePosition = position binding.bottomNavigationView.menu .getItem(realPositions[position]).isChecked = true } + } - private inner class TabFragmentPageAdapter : - FragmentStateAdapter(this) { + @Suppress("DEPRECATION") + private inner class TabFragmentPageAdapter(fm: FragmentManager) : + FragmentStatePagerAdapter(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) { - override fun containsItem(itemId: Long): Boolean { - return fragmentMap.containsKey(itemId) + private fun getId(position: Int): Int { + return realPositions[position] } - override fun getItemCount(): Int { - return bottomMenuCount + override fun getItemPosition(`object`: Any): Int { + return POSITION_NONE } - override fun getItemId(position: Int): Long { - return realPositions[position].toLong() - } - - override fun createFragment(position: Int): Fragment { - val id = getItemId(position) - val fragment = when (id) { - 0L -> BookshelfFragment() - 1L -> ExploreFragment() - 2L -> RssFragment() + override fun getItem(position: Int): Fragment { + return when (getId(position)) { + 0 -> BookshelfFragment() + 1 -> ExploreFragment() + 2 -> RssFragment() else -> MyFragment() } - fragmentMap[id] = fragment + } + + override fun getCount(): Int { + return bottomMenuCount + } + + override fun instantiateItem(container: ViewGroup, position: Int): Any { + val fragment = super.instantiateItem(container, position) as Fragment + fragmentMap[getId(position)] = fragment return fragment } diff --git a/app/src/main/java/io/legado/app/ui/main/bookshelf/BookshelfFragment.kt b/app/src/main/java/io/legado/app/ui/main/bookshelf/BookshelfFragment.kt index c291a4f99..87ee959f9 100644 --- a/app/src/main/java/io/legado/app/ui/main/bookshelf/BookshelfFragment.kt +++ b/app/src/main/java/io/legado/app/ui/main/bookshelf/BookshelfFragment.kt @@ -5,14 +5,11 @@ import android.os.Bundle import android.view.Menu import android.view.MenuItem import android.view.View +import android.view.ViewGroup import androidx.appcompat.widget.SearchView -import androidx.fragment.app.Fragment -import androidx.fragment.app.activityViewModels -import androidx.fragment.app.viewModels +import androidx.fragment.app.* import androidx.lifecycle.LiveData -import androidx.viewpager2.adapter.FragmentStateAdapter import com.google.android.material.tabs.TabLayout -import com.google.android.material.tabs.TabLayoutMediator import io.legado.app.R import io.legado.app.base.VMBaseFragment import io.legado.app.constant.AppConst @@ -22,7 +19,6 @@ import io.legado.app.data.entities.BookGroup import io.legado.app.databinding.DialogBookshelfConfigBinding import io.legado.app.databinding.DialogEditTextBinding import io.legado.app.databinding.FragmentBookshelfBinding -import io.legado.app.help.AppConfig import io.legado.app.lib.dialogs.alert import io.legado.app.lib.theme.ATH import io.legado.app.lib.theme.accentColor @@ -48,7 +44,7 @@ class BookshelfFragment : VMBaseFragment(R.layout.fragment_b private val binding by viewBinding(FragmentBookshelfBinding::bind) override val viewModel: BookshelfViewModel by viewModels() private val activityViewModel: MainViewModel by activityViewModels() - private lateinit var adapter: FragmentStateAdapter + private lateinit var adapter: FragmentStatePagerAdapter private lateinit var tabLayout: TabLayout private var bookGroupLiveData: LiveData>? = null private val bookGroups = mutableListOf() @@ -109,12 +105,10 @@ class BookshelfFragment : VMBaseFragment(R.layout.fragment_b tabLayout.isTabIndicatorFullWidth = false tabLayout.tabMode = TabLayout.MODE_SCROLLABLE tabLayout.setSelectedTabIndicatorColor(requireContext().accentColor) + tabLayout.setupWithViewPager(binding.viewPagerBookshelf) binding.viewPagerBookshelf.offscreenPageLimit = 1 - adapter = TabFragmentPageAdapter() + adapter = TabFragmentPageAdapter(childFragmentManager) binding.viewPagerBookshelf.adapter = adapter - TabLayoutMediator(tabLayout, binding.viewPagerBookshelf) { tab, i -> - tab.text = bookGroups[i].groupName - }.attach() } private fun initBookGroupData() { @@ -169,7 +163,6 @@ class BookshelfFragment : VMBaseFragment(R.layout.fragment_b .apply { rgLayout.checkByIndex(bookshelfLayout) rgSort.checkByIndex(bookshelfSort) - swShowUnread.isChecked = AppConfig.showUnread } customView { alertBinding.root } okButton { @@ -183,10 +176,6 @@ class BookshelfFragment : VMBaseFragment(R.layout.fragment_b putPrefInt(PreferKey.bookshelfSort, rgSort.getCheckedIndex()) changed = true } - if (AppConfig.showUnread != swShowUnread.isChecked) { - AppConfig.showUnread = swShowUnread.isChecked - changed = true - } if (changed) { activity?.recreate() } @@ -249,25 +238,29 @@ class BookshelfFragment : VMBaseFragment(R.layout.fragment_b }.show() } - private inner class TabFragmentPageAdapter : - FragmentStateAdapter(this) { + private inner class TabFragmentPageAdapter(fm: FragmentManager) : + FragmentStatePagerAdapter(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) { - override fun getItemId(position: Int): Long { - val group = bookGroups[position] - return group.groupId + override fun getPageTitle(position: Int): CharSequence { + return bookGroups[position].groupName } - override fun containsItem(itemId: Long): Boolean { - return fragmentMap.containsKey(itemId) + override fun getItemPosition(`object`: Any): Int { + return POSITION_NONE + } + + override fun getItem(position: Int): Fragment { + val group = bookGroups[position] + return BooksFragment.newInstance(position, group.groupId) } - override fun getItemCount(): Int { + override fun getCount(): Int { return bookGroups.size } - override fun createFragment(position: Int): Fragment { + override fun instantiateItem(container: ViewGroup, position: Int): Any { + val fragment = super.instantiateItem(container, position) as BooksFragment val group = bookGroups[position] - val fragment = BooksFragment.newInstance(position, group.groupId) fragmentMap[group.groupId] = fragment return fragment } diff --git a/app/src/main/java/io/legado/app/ui/main/bookshelf/RootView.kt b/app/src/main/java/io/legado/app/ui/main/bookshelf/RootView.kt deleted file mode 100644 index 4162e6e6e..000000000 --- a/app/src/main/java/io/legado/app/ui/main/bookshelf/RootView.kt +++ /dev/null @@ -1,82 +0,0 @@ -package io.legado.app.ui.main.bookshelf - -import android.content.Context -import android.gesture.GestureOverlayView.ORIENTATION_HORIZONTAL -import android.util.AttributeSet -import android.view.MotionEvent -import android.view.View -import android.view.ViewConfiguration -import android.widget.LinearLayout -import androidx.viewpager2.widget.ViewPager2 -import io.legado.app.R -import io.legado.app.ui.main.MainActivity -import io.legado.app.utils.activity -import kotlin.math.absoluteValue -import kotlin.math.sign - -class RootView : LinearLayout { - - constructor(context: Context) : super(context) - constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) - - private val touchSlop = ViewConfiguration.get(context).scaledTouchSlop - private var initialX = 0f - private var initialY = 0f - - private val parentViewPager: ViewPager2? - get() = (activity as? MainActivity)?.getViewPager() - private val childViewPager: View? - get() = findViewById(R.id.view_pager_bookshelf) - - private fun canChildScroll(orientation: Int, delta: Float): Boolean { - val direction = -delta.sign.toInt() - return when (orientation) { - 0 -> childViewPager?.canScrollHorizontally(direction) ?: false - 1 -> childViewPager?.canScrollVertically(direction) ?: false - else -> throw IllegalArgumentException() - } - } - - override fun onInterceptTouchEvent(e: MotionEvent): Boolean { - handleInterceptTouchEvent(e) - return super.onInterceptTouchEvent(e) - } - - private fun handleInterceptTouchEvent(e: MotionEvent) { - val orientation = parentViewPager?.orientation ?: return - // Early return if child can't scroll in same direction as parent - if (!canChildScroll(orientation, -1f) && !canChildScroll(orientation, 1f)) { - return - } - - if (e.action == MotionEvent.ACTION_DOWN) { - initialX = e.x - initialY = e.y - parent.requestDisallowInterceptTouchEvent(true) - } else if (e.action == MotionEvent.ACTION_MOVE) { - val dx = e.x - initialX - val dy = e.y - initialY - val isVpHorizontal = orientation == ORIENTATION_HORIZONTAL - // assuming ViewPager2 touch-slop is 2x touch-slop of child - val scaledDx = dx.absoluteValue * if (isVpHorizontal) .5f else 1f - val scaledDy = dy.absoluteValue * if (isVpHorizontal) 1f else .5f - - if (scaledDx > touchSlop || scaledDy > touchSlop) { - - if (isVpHorizontal == (scaledDy > scaledDx)) { - // Gesture is perpendicular, allow all parents to intercept - parent.requestDisallowInterceptTouchEvent(false) - } else { - // Gesture is parallel, query child if movement in that direction is possible - if (canChildScroll(orientation, if (isVpHorizontal) dx else dy)) { - // Child can scroll, disallow all parents to intercept - parent.requestDisallowInterceptTouchEvent(true) - } else { - // Child cannot scroll, allow all parents to intercept - parent.requestDisallowInterceptTouchEvent(false) - } - } - } - } - } -} \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/ui/main/bookshelf1/BookshelfFragment.kt b/app/src/main/java/io/legado/app/ui/main/bookshelf1/BookshelfFragment1.kt similarity index 99% rename from app/src/main/java/io/legado/app/ui/main/bookshelf1/BookshelfFragment.kt rename to app/src/main/java/io/legado/app/ui/main/bookshelf1/BookshelfFragment1.kt index ede5e76d4..f37c52e2c 100644 --- a/app/src/main/java/io/legado/app/ui/main/bookshelf1/BookshelfFragment.kt +++ b/app/src/main/java/io/legado/app/ui/main/bookshelf1/BookshelfFragment1.kt @@ -48,7 +48,7 @@ import kotlin.math.max /** * 书架界面 */ -class BookshelfFragment : VMBaseFragment(R.layout.fragment_bookshelf1), +class BookshelfFragment1 : VMBaseFragment(R.layout.fragment_bookshelf1), SearchView.OnQueryTextListener, BaseBooksAdapter.CallBack { diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 80c952ab8..a387ecb36 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -5,7 +5,7 @@ android:layout_height="match_parent" android:orientation="vertical"> - - - - \ No newline at end of file + \ No newline at end of file