فهرست منبع

修复安卓10上的一些界面问题,将主页面改为使用ViewPager2

HapeLee 1 سال پیش
والد
کامیت
e7679a3009

+ 25 - 1
app/src/main/java/io/legato/kazusa/base/BaseActivity.kt

@@ -3,6 +3,7 @@ package io.legato.kazusa.base
 import android.annotation.SuppressLint
 import android.content.Context
 import android.content.res.Configuration
+import android.graphics.Color
 import android.os.Build
 import android.os.Bundle
 import android.util.AttributeSet
@@ -33,6 +34,10 @@ import io.legato.kazusa.utils.observeEvent
 import io.legato.kazusa.utils.toastOnUi
 import io.legato.kazusa.utils.windowSize
 import io.legato.kazusa.lib.theme.primaryColor
+import io.legato.kazusa.utils.fullScreen
+import io.legato.kazusa.utils.setNavigationBarColorAuto
+import io.legato.kazusa.utils.setStatusBarColorAuto
+import io.legato.kazusa.utils.themeColor
 
 
 abstract class BaseActivity<VB : ViewBinding>(
@@ -74,7 +79,12 @@ abstract class BaseActivity<VB : ViewBinding>(
         AppContextWrapper.applyLocaleAndFont(this)
         super.onCreate(savedInstanceState)
         WindowCompat.setDecorFitsSystemWindows(window, false)
-        enableEdgeToEdge()
+        if (Build.VERSION.SDK_INT > Build.VERSION_CODES.Q)
+            enableEdgeToEdge()
+        else{
+            window.setNavigationBarColorAuto(themeColor(com.google.android.material.R.attr.colorSurface))
+            setupSystemBar()
+        }
         //window.setNavigationBarColorAuto(themeColor(com.google.android.material.R.attr.colorSurface))
         //setupSystemBar()
         setContentView(binding.root)
@@ -95,6 +105,20 @@ abstract class BaseActivity<VB : ViewBinding>(
         //setupSystemBar()
     }
 
+    open fun setupSystemBar() {
+        if (fullScreen && !isInMultiWindow) {
+            fullScreen()
+        }
+        setStatusBarColorAuto(Color.TRANSPARENT, false, fullScreen)
+        val isDarkTheme = when (resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK) {
+            Configuration.UI_MODE_NIGHT_YES -> true
+            Configuration.UI_MODE_NIGHT_NO,
+            Configuration.UI_MODE_NIGHT_UNDEFINED -> false
+            else -> false
+        }
+        WindowCompat.getInsetsController(window, window.decorView).isAppearanceLightStatusBars = !isDarkTheme
+    }
+
 //    override fun onConfigurationChanged(newConfig: Configuration) {
 //        super.onConfigurationChanged(newConfig)
 //        //findViewById<TitleBar>(R.id.title_bar)

+ 42 - 61
app/src/main/java/io/legato/kazusa/ui/main/MainActivity.kt

@@ -8,7 +8,6 @@ import android.text.format.DateUtils
 import android.view.Gravity
 import android.view.MenuItem
 import android.view.MotionEvent
-import android.view.ViewGroup
 import android.widget.FrameLayout
 import android.widget.ImageView
 import androidx.activity.addCallback
@@ -16,10 +15,10 @@ import androidx.activity.viewModels
 import androidx.core.view.get
 import androidx.core.view.postDelayed
 import androidx.fragment.app.Fragment
-import androidx.fragment.app.FragmentManager
-import androidx.fragment.app.FragmentStatePagerAdapter
+import androidx.fragment.app.FragmentActivity
 import androidx.lifecycle.lifecycleScope
-import androidx.viewpager.widget.ViewPager
+import androidx.viewpager2.adapter.FragmentStateAdapter
+import androidx.viewpager2.widget.ViewPager2
 import com.google.android.material.bottomnavigation.BottomNavigationView
 import com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
 import com.google.android.material.navigation.NavigationBarView
@@ -53,11 +52,9 @@ import io.legato.kazusa.utils.dpToPx
 import io.legato.kazusa.utils.gone
 import io.legato.kazusa.utils.hideSoftInput
 import io.legato.kazusa.utils.observeEvent
-import io.legato.kazusa.utils.setNavigationBarColorAuto
 import io.legato.kazusa.utils.shouldHideSoftInput
 import io.legato.kazusa.utils.showDialogFragment
 import io.legato.kazusa.utils.startActivity
-import io.legato.kazusa.utils.themeColor
 import io.legato.kazusa.utils.toastOnUi
 import io.legato.kazusa.utils.viewbindingdelegate.viewBinding
 import io.legato.kazusa.utils.visible
@@ -91,7 +88,7 @@ class MainActivity : VMBaseActivity<ActivityMainBinding, MainViewModel>(),
     private var bottomMenuCount = 4
     private val realPositions = arrayOf(idBookshelf, idExplore, idRss, idMy)
     private val adapter by lazy {
-        TabFragmentPageAdapter(supportFragmentManager)
+        TabFragmentPageAdapter(this)
     }
 
     private val badge by lazy {
@@ -175,21 +172,16 @@ class MainActivity : VMBaseActivity<ActivityMainBinding, MainViewModel>(),
         }
     }
 
-    override fun onNavigationItemSelected(item: MenuItem): Boolean = binding.run {
-        when (item.itemId) {
-            R.id.menu_bookshelf ->
-                viewPagerMain.setCurrentItem(0, false)
-
-            R.id.menu_discovery ->
-                viewPagerMain.setCurrentItem(realPositions.indexOf(idExplore), false)
-
-            R.id.menu_rss ->
-                viewPagerMain.setCurrentItem(realPositions.indexOf(idRss), false)
-
-            R.id.menu_my_config ->
-                viewPagerMain.setCurrentItem(realPositions.indexOf(idMy), false)
+    override fun onNavigationItemSelected(item: MenuItem): Boolean {
+        val index = when (item.itemId) {
+            R.id.menu_bookshelf -> 0
+            R.id.menu_discovery -> realPositions.indexOf(idExplore)
+            R.id.menu_rss -> realPositions.indexOf(idRss)
+            R.id.menu_my_config -> realPositions.indexOf(idMy)
+            else -> 0
         }
-        return false
+        binding.viewPagerMain.setCurrentItem(index, true)
+        return true
     }
 
     override fun onNavigationItemReselected(item: MenuItem) {
@@ -215,8 +207,9 @@ class MainActivity : VMBaseActivity<ActivityMainBinding, MainViewModel>(),
     private fun initView() = binding.run {
         viewPagerMain.offscreenPageLimit = 3
         viewPagerMain.adapter = adapter
-        viewPagerMain.addOnPageChangeListener(PageChangeCallback())
-        window.setNavigationBarColorAuto(themeColor(com.google.android.material.R.attr.colorSurfaceContainer))
+        viewPagerMain.registerOnPageChangeCallback(PageChangeCallback())
+
+        //window.setNavigationBarColorAuto(themeColor(com.google.android.material.R.attr.colorSurfaceContainer))
     }
 
     /**
@@ -464,45 +457,29 @@ class MainActivity : VMBaseActivity<ActivityMainBinding, MainViewModel>(),
         return id
     }
 
-
-    private inner class PageChangeCallback : ViewPager.SimpleOnPageChangeListener() {
-
+    private inner class PageChangeCallback : ViewPager2.OnPageChangeCallback() {
         override fun onPageSelected(position: Int) {
             pagePosition = position
-            val navView = getNavigationBarView()
-            navView.menu[realPositions[position]].isChecked = true
+            getNavigationBarView().selectedItemId = when (realPositions[position]) {
+                idBookshelf -> R.id.menu_bookshelf
+                idExplore -> R.id.menu_discovery
+                idRss -> R.id.menu_rss
+                idMy -> R.id.menu_my_config
+                else -> R.id.menu_bookshelf
+            }
             updateNavigationRailFab(position)
         }
-
     }
 
-    private inner class TabFragmentPageAdapter(fm: FragmentManager) :
-        FragmentStatePagerAdapter(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) {
-
-        private fun getId(position: Int): Int {
-            return getFragmentId(position)
-        }
 
-        override fun getItemPosition(any: Any): Int {
-            val position = (any as? MainFragmentInterface)?.position ?: return POSITION_NONE
-            val fragmentId = getId(position)
-
-            if (
-                (fragmentId == idBookshelf1 && any is BookshelfFragment1) ||
-                (fragmentId == idBookshelf2 && any is BookshelfFragment2) ||
-                (fragmentId == idBookshelf3 && any is BookshelfFragment3) ||
-                (fragmentId == idExplore && any is ExploreFragment) ||
-                (fragmentId == idRss && any is RssFragment) ||
-                (fragmentId == idMy && any is MyFragment)
-            ) {
-                return POSITION_UNCHANGED
-            }
-            return POSITION_NONE
-        }
+    private inner class TabFragmentPageAdapter(
+        activity: FragmentActivity
+    ) : FragmentStateAdapter(activity) {
 
+        override fun getItemCount(): Int = bottomMenuCount
 
-        override fun getItem(position: Int): Fragment {
-            return when (getId(position)) {
+        override fun createFragment(position: Int): Fragment {
+            val fragment = when (getFragmentId(position)) {
                 idBookshelf1 -> BookshelfFragment1(position)
                 idBookshelf2 -> BookshelfFragment2(position)
                 idBookshelf3 -> BookshelfFragment3(position)
@@ -510,18 +487,22 @@ class MainActivity : VMBaseActivity<ActivityMainBinding, MainViewModel>(),
                 idRss -> RssFragment(position)
                 else -> MyFragment(position)
             }
-        }
 
-        override fun getCount(): Int {
-            return bottomMenuCount
+            fragmentMap[getFragmentId(position)] = fragment
+            return fragment
         }
 
-        override fun instantiateItem(container: ViewGroup, position: Int): Any {
-            val fragment = super.instantiateItem(container, position) as Fragment
-            fragmentMap[getId(position)] = fragment
-            return fragment
+        override fun getItemId(position: Int): Long {
+            return getFragmentId(position).toLong()
         }
 
+        override fun containsItem(itemId: Long): Boolean {
+            return realPositions.map { getFragmentId(it).toLong() }.contains(itemId)
+        }
     }
 
-}
+
+
+}
+
+

+ 65 - 0
app/src/main/java/io/legato/kazusa/ui/widget/NestedScrollableHost.kt

@@ -0,0 +1,65 @@
+package io.legato.kazusa.ui.widget
+
+import android.content.Context
+import android.util.AttributeSet
+import android.view.MotionEvent
+import android.view.View
+import android.view.ViewConfiguration
+import android.widget.FrameLayout
+import androidx.viewpager2.widget.ViewPager2
+import kotlin.math.abs
+import androidx.core.view.isNotEmpty
+
+class NestedScrollableHost @JvmOverloads constructor(
+    context: Context, attrs: AttributeSet? = null
+) : FrameLayout(context, attrs) {
+
+    private var touchSlop = 0
+    private var initialX = 0f
+    private var initialY = 0f
+
+    private val parentViewPager: ViewPager2?
+        get() {
+            var v: View? = parent as? View
+            while (v != null && v !is ViewPager2) {
+                v = v.parent as? View
+            }
+            return v
+        }
+
+    private val child: View?
+        get() = if (isNotEmpty()) getChildAt(0) else null
+
+    init {
+        touchSlop = ViewConfiguration.get(context).scaledTouchSlop
+    }
+
+    override fun onInterceptTouchEvent(ev: MotionEvent): Boolean {
+        handleInterceptTouchEvent(ev)
+        return super.onInterceptTouchEvent(ev)
+    }
+
+    private fun handleInterceptTouchEvent(e: MotionEvent) {
+        val parentVp = parentViewPager ?: return
+
+        when (e.action) {
+            MotionEvent.ACTION_DOWN -> {
+                initialX = e.x
+                initialY = e.y
+                parent.requestDisallowInterceptTouchEvent(true)
+            }
+            MotionEvent.ACTION_MOVE -> {
+                val dx = e.x - initialX
+                val dy = e.y - initialY
+                val isHorizontal = abs(dx) > abs(dy)
+
+                if (isHorizontal) {
+                    val canScroll = child?.canScrollHorizontally(-dx.toInt()) ?: false
+                    parent.requestDisallowInterceptTouchEvent(canScroll)
+                } else {
+                    parent.requestDisallowInterceptTouchEvent(false)
+                }
+            }
+        }
+    }
+}

+ 1 - 1
app/src/main/res/layout/activity_main.xml

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

+ 10 - 5
app/src/main/res/layout/fragment_bookshelf1.xml

@@ -15,6 +15,7 @@
         android:stateListAnimator="@null">
 
         <com.google.android.material.appbar.CollapsingToolbarLayout
+            android:id="@+id/coll_top_bar"
             android:layout_width="match_parent"
             android:layout_height="?attr/collapsingToolbarLayoutMediumSize"
             style="?attr/collapsingToolbarLayoutMediumStyle"
@@ -42,12 +43,16 @@
 
     </com.google.android.material.appbar.AppBarLayout>
 
-    <!-- ViewPager -->
-    <androidx.viewpager2.widget.ViewPager2
-        android:id="@+id/view_pager_bookshelf"
+    <io.legato.kazusa.ui.widget.NestedScrollableHost
         android:layout_width="match_parent"
         android:layout_height="match_parent"
-        android:paddingHorizontal="8dp"
-        app:layout_behavior="@string/appbar_scrolling_view_behavior" />
+        app:layout_behavior="@string/appbar_scrolling_view_behavior">
+        <androidx.viewpager2.widget.ViewPager2
+            android:id="@+id/view_pager_bookshelf"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:paddingHorizontal="8dp" />
+    </io.legato.kazusa.ui.widget.NestedScrollableHost>
+
 
 </androidx.coordinatorlayout.widget.CoordinatorLayout>

+ 8 - 5
app/src/main/res/layout/fragment_bookshelf3.xml

@@ -35,12 +35,15 @@
 
     </com.google.android.material.appbar.AppBarLayout>
 
-    <!-- ViewPager -->
-    <androidx.viewpager2.widget.ViewPager2
-        android:id="@+id/view_pager_bookshelf"
+    <io.legato.kazusa.ui.widget.NestedScrollableHost
         android:layout_width="match_parent"
         android:layout_height="match_parent"
-        android:paddingHorizontal="8dp"
-        app:layout_behavior="@string/appbar_scrolling_view_behavior" />
+        app:layout_behavior="@string/appbar_scrolling_view_behavior">
+        <androidx.viewpager2.widget.ViewPager2
+            android:id="@+id/view_pager_bookshelf"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:paddingHorizontal="8dp" />
+    </io.legato.kazusa.ui.widget.NestedScrollableHost>
 
 </androidx.coordinatorlayout.widget.CoordinatorLayout>

+ 1 - 1
gradle/libs.versions.toml

@@ -28,7 +28,7 @@ jsoupxpath = "2.5.3"
 coroutines = "1.10.2"
 liveeventbus = "1.8.14"
 markwon = "4.6.2"
-material = "1.14.0-alpha04"
+material = "1.14.0-alpha05"
 media = "1.7.1"
 media3 = "1.8.0"
 nanoHttpd = "2.3.1"