pull/921/head
gedoor 4 years ago
parent 2894e0dadb
commit f9f577724c
  1. 79
      app/src/main/java/io/legado/app/ui/main/MainActivity.kt
  2. 98
      app/src/main/java/io/legado/app/ui/main/bookshelf/BookshelfFragment.kt
  3. 2
      app/src/main/res/layout/activity_main.xml
  4. 2
      app/src/main/res/layout/fragment_bookshelf.xml

@ -3,12 +3,10 @@ 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.fragment.app.FragmentManager
import androidx.fragment.app.FragmentStatePagerAdapter
import androidx.viewpager.widget.ViewPager
import androidx.viewpager2.adapter.FragmentStateAdapter
import androidx.viewpager2.widget.ViewPager2
import com.google.android.material.bottomnavigation.BottomNavigationView
import io.legado.app.BuildConfig
import io.legado.app.R
@ -36,14 +34,15 @@ import io.legado.app.utils.toastOnUi
class MainActivity : VMBaseActivity<ActivityMainBinding, MainViewModel>(),
BottomNavigationView.OnNavigationItemSelectedListener,
BottomNavigationView.OnNavigationItemReselectedListener,
ViewPager.OnPageChangeListener by ViewPager.SimpleOnPageChangeListener() {
BottomNavigationView.OnNavigationItemReselectedListener {
override val viewModel: MainViewModel by viewModels()
private var exitTime: Long = 0
private var bookshelfReselected: Long = 0
private var exploreReselected: Long = 0
private var pagePosition = 0
private val fragmentMap = hashMapOf<Int, Fragment>()
private val fragmentMap = hashMapOf<Long, Fragment>()
val viewPager get() = binding.viewPagerMain
override fun getViewBinding(): ActivityMainBinding {
return ActivityMainBinding.inflate(layoutInflater)
@ -53,8 +52,21 @@ class MainActivity : VMBaseActivity<ActivityMainBinding, MainViewModel>(),
ATH.applyEdgeEffectColor(viewPagerMain)
ATH.applyBottomNavigationColor(bottomNavigationView)
viewPagerMain.offscreenPageLimit = 3
viewPagerMain.adapter = TabFragmentPageAdapter(supportFragmentManager)
viewPagerMain.addOnPageChangeListener(this@MainActivity)
viewPagerMain.adapter = TabFragmentPageAdapter()
viewPagerMain.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() {
override fun onPageSelected(position: Int) {
viewPagerMain.isUserInputEnabled = (viewPagerMain.currentItem != 0)
pagePosition = position
when (position) {
0, 1, 3 -> bottomNavigationView.menu.getItem(position).isChecked = true
2 -> if (AppConfig.isShowRSS) {
bottomNavigationView.menu.getItem(position).isChecked = true
} else {
bottomNavigationView.menu.getItem(3).isChecked = true
}
}
}
})
bottomNavigationView.elevation =
if (AppConfig.elevation < 0) elevation else AppConfig.elevation.toFloat()
bottomNavigationView.setOnNavigationItemSelectedListener(this@MainActivity)
@ -92,14 +104,14 @@ class MainActivity : VMBaseActivity<ActivityMainBinding, MainViewModel>(),
if (System.currentTimeMillis() - bookshelfReselected > 300) {
bookshelfReselected = System.currentTimeMillis()
} else {
(fragmentMap[0] as? BookshelfFragment)?.gotoTop()
(fragmentMap[0L] as? BookshelfFragment)?.gotoTop()
}
}
R.id.menu_explore -> {
if (System.currentTimeMillis() - exploreReselected > 300) {
exploreReselected = System.currentTimeMillis()
} else {
(fragmentMap[1] as? ExploreFragment)?.compressExplore()
(fragmentMap[1L] as? ExploreFragment)?.compressExplore()
}
}
}
@ -120,18 +132,6 @@ class MainActivity : VMBaseActivity<ActivityMainBinding, MainViewModel>(),
}
}
override fun onPageSelected(position: Int) = with(binding) {
pagePosition = position
when (position) {
0, 1, 3 -> bottomNavigationView.menu.getItem(position).isChecked = true
2 -> if (AppConfig.isShowRSS) {
bottomNavigationView.menu.getItem(position).isChecked = true
} else {
bottomNavigationView.menu.getItem(3).isChecked = true
}
}
}
override fun onKeyUp(keyCode: Int, event: KeyEvent?): Boolean {
event?.let {
when (keyCode) {
@ -186,36 +186,29 @@ class MainActivity : VMBaseActivity<ActivityMainBinding, MainViewModel>(),
}
}
private inner class TabFragmentPageAdapter(fm: FragmentManager) :
FragmentStatePagerAdapter(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) {
private inner class TabFragmentPageAdapter :
FragmentStateAdapter(this) {
private fun getId(position: Int): Int {
override fun getItemId(position: Int): Long {
return when (position) {
2 -> if (AppConfig.isShowRSS) 2 else 3
else -> position
else -> position.toLong()
}
}
override fun getItemPosition(`object`: Any): Int {
return POSITION_NONE
override fun getItemCount(): Int {
return if (AppConfig.isShowRSS) 4 else 3
}
override fun getItem(position: Int): Fragment {
return when (getId(position)) {
0 -> BookshelfFragment()
1 -> ExploreFragment()
2 -> RssFragment()
override fun createFragment(position: Int): Fragment {
val id = getItemId(position)
val fragment = when (id) {
0L -> BookshelfFragment()
1L -> ExploreFragment()
2L -> RssFragment()
else -> MyFragment()
}
}
override fun getCount(): Int {
return if (AppConfig.isShowRSS) 4 else 3
}
override fun instantiateItem(container: ViewGroup, position: Int): Any {
val fragment = super.instantiateItem(container, position) as Fragment
fragmentMap[getId(position)] = fragment
fragmentMap[id] = fragment
return fragment
}

@ -7,11 +7,13 @@ 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.*
import androidx.lifecycle.LiveData
import androidx.viewpager2.adapter.FragmentStateAdapter
import androidx.viewpager2.widget.ViewPager2
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
@ -31,6 +33,7 @@ import io.legado.app.ui.book.local.ImportBookActivity
import io.legado.app.ui.book.search.SearchActivity
import io.legado.app.ui.filepicker.FilePicker
import io.legado.app.ui.filepicker.FilePickerDialog
import io.legado.app.ui.main.MainActivity
import io.legado.app.ui.main.MainViewModel
import io.legado.app.ui.main.bookshelf.books.BooksFragment
import io.legado.app.utils.*
@ -48,12 +51,18 @@ class BookshelfFragment : VMBaseFragment<BookshelfViewModel>(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: FragmentStatePagerAdapter
private lateinit var tabLayout: TabLayout
private var bookGroupLiveData: LiveData<List<BookGroup>>? = null
private val bookGroups = mutableListOf<BookGroup>()
private val fragmentMap = hashMapOf<Long, BooksFragment>()
private var currentPosition = 0 //当前滑动位置
private var oldPosition = 0 //上一个滑动位置
private var currentState = 0 //记录当前手指按下状态
private var scrolledPixList = mutableListOf<Int>() //记录手指滑动时的像素坐标记录
private val mainActivity get() = activity as MainActivity
override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) {
tabLayout = binding.titleBar.findViewById(R.id.tab_layout)
setSupportToolbar(binding.titleBar.toolbar)
@ -101,15 +110,64 @@ class BookshelfFragment : VMBaseFragment<BookshelfViewModel>(R.layout.fragment_b
private val selectedGroup: BookGroup
get() = bookGroups[tabLayout.selectedTabPosition]
private fun initView() {
ATH.applyEdgeEffectColor(binding.viewPagerBookshelf)
private fun initView() = with(binding) {
ATH.applyEdgeEffectColor(viewPagerBookshelf)
tabLayout.isTabIndicatorFullWidth = false
tabLayout.tabMode = TabLayout.MODE_SCROLLABLE
tabLayout.setSelectedTabIndicatorColor(requireContext().accentColor)
tabLayout.setupWithViewPager(binding.viewPagerBookshelf)
binding.viewPagerBookshelf.offscreenPageLimit = 1
adapter = TabFragmentPageAdapter(childFragmentManager)
binding.viewPagerBookshelf.adapter = adapter
viewPagerBookshelf.offscreenPageLimit = 1
viewPagerBookshelf.adapter = TabFragmentPageAdapter()
TabLayoutMediator(tabLayout, viewPagerBookshelf) { tab, i ->
tab.text = bookGroups[i].groupName
}.attach()
viewPagerBookshelf.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() {
//页面滚动的位置信息回调: position 当前滚动到哪个页面,positionOffset 位置偏移百分比, positionOffsetPixels 当前所在页面偏移量
//此回调会触发完onPageScrollStateChanged 的 state 值为1时后面才触发回调
override fun onPageScrolled(
position: Int,
positionOffset: Float,
positionOffsetPixels: Int
) {
currentPosition = position
if (currentState == 1) {
//手指按下滑动坐标记录
scrolledPixList.add(positionOffsetPixels)
}
}
// 滚动状态改变回调,state的值分别有0,1,2 ;
// 0为ViewPager所有事件(1,2)已结束触发
// 1为在viewPager里按下并滑动触发多次
// 2是手指抬起触发
override fun onPageScrollStateChanged(state: Int) {
currentState = state
if (state == 0) {
if (currentPosition == oldPosition) {
when (currentPosition) {
0 -> {
if (scrolledPixList.size > 1 && scrolledPixList.last() == 0 || scrolledPixList.last() - scrolledPixList[0] > 0) {
//有可能出现滑到一半放弃的情况也是可以出现currentPosition == oldPositon=0,则先判断是否是往右滑时放弃
return
}
//若还有上一个bottom fragment页面则切换
mainActivity.viewPager.currentItem.takeIf { it > 0 }
?.also { mainActivity.viewPager.setCurrentItem(it - 1, true) }
}
(viewPagerBookshelf.adapter as FragmentStateAdapter).itemCount - 1 -> {
//若还有下一个bottom fragment页面则切换
mainActivity.viewPager.currentItem.takeIf { it < mainActivity.viewPager.adapter!!.itemCount - 1 }
?.also { mainActivity.viewPager.setCurrentItem(it + 1, true) }
}
}
}
oldPosition = currentPosition
scrolledPixList.clear()//清空滑动记录
}
}
})
}
private fun initBookGroupData() {
@ -141,7 +199,7 @@ class BookshelfFragment : VMBaseFragment<BookshelfViewModel>(R.layout.fragment_b
if (data != bookGroups) {
bookGroups.clear()
bookGroups.addAll(data)
adapter.notifyDataSetChanged()
binding.viewPagerBookshelf.adapter?.notifyDataSetChanged()
selectLastTab()
}
}
@ -251,29 +309,21 @@ class BookshelfFragment : VMBaseFragment<BookshelfViewModel>(R.layout.fragment_b
}
}
private inner class TabFragmentPageAdapter(fm: FragmentManager) :
FragmentStatePagerAdapter(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) {
override fun getPageTitle(position: Int): CharSequence {
return bookGroups[position].groupName
}
override fun getItemPosition(`object`: Any): Int {
return POSITION_NONE
}
private inner class TabFragmentPageAdapter :
FragmentStateAdapter(this) {
override fun getItem(position: Int): Fragment {
override fun getItemId(position: Int): Long {
val group = bookGroups[position]
return BooksFragment.newInstance(position, group.groupId)
return group.groupId
}
override fun getCount(): Int {
override fun getItemCount(): Int {
return bookGroups.size
}
override fun instantiateItem(container: ViewGroup, position: Int): Any {
val fragment = super.instantiateItem(container, position) as BooksFragment
override fun createFragment(position: Int): Fragment {
val group = bookGroups[position]
val fragment = BooksFragment.newInstance(position, group.groupId)
fragmentMap[group.groupId] = fragment
return fragment
}

@ -5,7 +5,7 @@
android:layout_height="match_parent"
android:orientation="vertical">
<androidx.viewpager.widget.ViewPager
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/view_pager_main"
android:layout_width="match_parent"
android:layout_height="0dp"

@ -13,7 +13,7 @@
app:title="@string/bookshelf"
app:contentLayout="@layout/view_tab_layout_min" />
<androidx.viewpager.widget.ViewPager
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/view_pager_bookshelf"
android:layout_width="match_parent"
android:layout_height="match_parent" />

Loading…
Cancel
Save