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

@ -7,13 +7,11 @@ import android.os.Bundle
import android.view.Menu import android.view.Menu
import android.view.MenuItem import android.view.MenuItem
import android.view.View import android.view.View
import android.view.ViewGroup
import androidx.appcompat.widget.SearchView import androidx.appcompat.widget.SearchView
import androidx.fragment.app.* import androidx.fragment.app.*
import androidx.lifecycle.LiveData 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.TabLayout
import com.google.android.material.tabs.TabLayoutMediator
import io.legado.app.R import io.legado.app.R
import io.legado.app.base.VMBaseFragment import io.legado.app.base.VMBaseFragment
import io.legado.app.constant.AppConst import io.legado.app.constant.AppConst
@ -33,7 +31,6 @@ import io.legado.app.ui.book.local.ImportBookActivity
import io.legado.app.ui.book.search.SearchActivity import io.legado.app.ui.book.search.SearchActivity
import io.legado.app.ui.filepicker.FilePicker import io.legado.app.ui.filepicker.FilePicker
import io.legado.app.ui.filepicker.FilePickerDialog 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.MainViewModel
import io.legado.app.ui.main.bookshelf.books.BooksFragment import io.legado.app.ui.main.bookshelf.books.BooksFragment
import io.legado.app.utils.* import io.legado.app.utils.*
@ -51,18 +48,12 @@ class BookshelfFragment : VMBaseFragment<BookshelfViewModel>(R.layout.fragment_b
private val binding by viewBinding(FragmentBookshelfBinding::bind) private val binding by viewBinding(FragmentBookshelfBinding::bind)
override val viewModel: BookshelfViewModel by viewModels() override val viewModel: BookshelfViewModel by viewModels()
private val activityViewModel: MainViewModel by activityViewModels() private val activityViewModel: MainViewModel by activityViewModels()
private lateinit var adapter: FragmentStatePagerAdapter
private lateinit var tabLayout: TabLayout private lateinit var tabLayout: TabLayout
private var bookGroupLiveData: LiveData<List<BookGroup>>? = null private var bookGroupLiveData: LiveData<List<BookGroup>>? = null
private val bookGroups = mutableListOf<BookGroup>() private val bookGroups = mutableListOf<BookGroup>()
private val fragmentMap = hashMapOf<Long, BooksFragment>() 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?) { override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) {
tabLayout = binding.titleBar.findViewById(R.id.tab_layout) tabLayout = binding.titleBar.findViewById(R.id.tab_layout)
setSupportToolbar(binding.titleBar.toolbar) setSupportToolbar(binding.titleBar.toolbar)
@ -110,64 +101,15 @@ class BookshelfFragment : VMBaseFragment<BookshelfViewModel>(R.layout.fragment_b
private val selectedGroup: BookGroup private val selectedGroup: BookGroup
get() = bookGroups[tabLayout.selectedTabPosition] get() = bookGroups[tabLayout.selectedTabPosition]
private fun initView() = with(binding) { private fun initView() {
ATH.applyEdgeEffectColor(viewPagerBookshelf) ATH.applyEdgeEffectColor(binding.viewPagerBookshelf)
tabLayout.isTabIndicatorFullWidth = false tabLayout.isTabIndicatorFullWidth = false
tabLayout.tabMode = TabLayout.MODE_SCROLLABLE tabLayout.tabMode = TabLayout.MODE_SCROLLABLE
tabLayout.setSelectedTabIndicatorColor(requireContext().accentColor) tabLayout.setSelectedTabIndicatorColor(requireContext().accentColor)
viewPagerBookshelf.offscreenPageLimit = 1 tabLayout.setupWithViewPager(binding.viewPagerBookshelf)
viewPagerBookshelf.adapter = TabFragmentPageAdapter() binding.viewPagerBookshelf.offscreenPageLimit = 1
TabLayoutMediator(tabLayout, viewPagerBookshelf) { tab, i -> adapter = TabFragmentPageAdapter(childFragmentManager)
tab.text = bookGroups[i].groupName binding.viewPagerBookshelf.adapter = adapter
}.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() { private fun initBookGroupData() {
@ -199,7 +141,7 @@ class BookshelfFragment : VMBaseFragment<BookshelfViewModel>(R.layout.fragment_b
if (data != bookGroups) { if (data != bookGroups) {
bookGroups.clear() bookGroups.clear()
bookGroups.addAll(data) bookGroups.addAll(data)
binding.viewPagerBookshelf.adapter?.notifyDataSetChanged() adapter.notifyDataSetChanged()
selectLastTab() selectLastTab()
} }
} }
@ -309,21 +251,29 @@ class BookshelfFragment : VMBaseFragment<BookshelfViewModel>(R.layout.fragment_b
} }
} }
private inner class TabFragmentPageAdapter : private inner class TabFragmentPageAdapter(fm: FragmentManager) :
FragmentStateAdapter(this) { 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
}
override fun getItemId(position: Int): Long { override fun getItem(position: Int): Fragment {
val group = bookGroups[position] val group = bookGroups[position]
return group.groupId return BooksFragment.newInstance(position, group.groupId)
} }
override fun getItemCount(): Int { override fun getCount(): Int {
return bookGroups.size 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 group = bookGroups[position]
val fragment = BooksFragment.newInstance(position, group.groupId)
fragmentMap[group.groupId] = fragment fragmentMap[group.groupId] = fragment
return fragment return fragment
} }

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

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

Loading…
Cancel
Save