标签: android-viewpager2

为什么 Android ViewPager2 类是 final 的?

ViewPager2在我当前的项目中使用时,我想使用setOnTouchListener,但我无法获得任何事件。

我决定扩展 ViewPager2 类以覆盖触摸事件方法,但由于类定义是最终的,因此无法实现。

为什么这个类是最终的,有什么方法可以扩展它以便我可以覆盖触摸事件?

android android-viewpager2

10
推荐指数
1
解决办法
1316
查看次数

ViewPager2/Tabs 的 ViewModel 状态问题

我遵循 MVVM 模式 - 这意味着我为每个 Fragment 都有一个 ViewModel。

我使用 ViewPager2添加了两个选项卡。

我的适配器看起来像这样:

@Override
public Fragment createFragment(int position) {
    switch (position) {
        case 0:
            return new MergedItemsFragment();
        case 1:     
            return new ValidatedMergedItemsFragment();
    }
    return new MergedItemsFragment();
}
Run Code Online (Sandbox Code Playgroud)

选项卡正在工作。但是,我注意到我的 MergedItemsFragment 的 ViewModel 表现得很奇怪。在我添加标签之前,我像这样导航到 Fragment:

NavHostFragment.findNavController(this).navigate(R.id.action_roomFragment_to_itemsFragment);
Run Code Online (Sandbox Code Playgroud)

当我离开那个片段NavHostFragment.findNavController(this).popBackStack()然后返回到那个片段时,我会得到一个新的空 ViewModel。这是有意的。

使用新方法,我正在使用return new MergedItemsFragment(). 当我离开那个片段并稍后返回时,我得到一个包含旧数据的 ViewModel 。这是一个问题,因为旧数据不再相关,因为用户在另一个片段中选择了不同的数据。


更新 #1

我意识到他实际上将所有片段保存在内存中,因为多次调用相同的打印语句。它被调用的次数随着我离开并返回该屏幕的次数而增加。因此,如果我离开并返回 10 次并旋转我的设备,他实际上会执行一行 10 次。任何猜测如何以与 ViewModels 一起工作的方式使用导航组件实现 Tabs/ViewPagers?


更新 #2

我这样设置我的 ViewModel:

@Override
public …
Run Code Online (Sandbox Code Playgroud)

java android android-viewmodel android-architecture-navigation android-viewpager2

10
推荐指数
1
解决办法
1955
查看次数

片段随着 ViewPager2 和 FragmentStateAdapter 消失

我正在构建一个应用程序ViewPager2,该应用程序在滑动时显示不同的片段。我的适配器FragmentStateAdapter此处所述进行扩展。

当我将我的应用程序置于后台然后再次恢复时,当前片段消失了。我需要做什么来确保当前片段正确恢复?

(注意:我问的是FragmentStateAdapter,不是FragmentPagerAdapterFragmentStatePagerAdapter。)

更新 1

我的片段类如下:

class PagerFragment : Fragment() {

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
    val layoutResId: Int = arguments!!.getInt(ARG_LAYOUT_RES_ID)
    return inflater.inflate(layoutResId, container, false)
}

companion object {
    private const val ARG_LAYOUT_RES_ID = "layoutResId"

    fun newInstance(layoutResId: Int): PagerFragment {
        val args = Bundle()
        args.putInt(ARG_LAYOUT_RES_ID, layoutResId)

        val fragment = PagerFragment()
        fragment.arguments = args
        return fragment
    }
}
Run Code Online (Sandbox Code Playgroud)

}

我在创建每个片段时传入所需的布局资源 ID。

我的视图寻呼机适配器类如下:

class …
Run Code Online (Sandbox Code Playgroud)

android androidx android-viewpager2

9
推荐指数
1
解决办法
4868
查看次数

如何修复 ViewPager2 中的“违反设计假设”错误?

我正在使用 ViewPager2、Kotlin 和 AndroidX。当适配器不在索引 0 处并且我更改适配器列表并将当前项设置为索引 0 时,将引发异常。

java.lang.IllegalStateException: Design assumption violated.
        at androidx.viewpager2.widget.ViewPager2.updateCurrentItem(ViewPager2.java:538)
        at androidx.viewpager2.widget.ViewPager2$4.onAnimationsFinished(ViewPager2.java:518)
        at androidx.recyclerview.widget.RecyclerView$ItemAnimator.isRunning(RecyclerView.java:13244)
        at androidx.viewpager2.widget.ViewPager2.onLayout(ViewPager2.java:515)
        at android.view.View.layout(View.java:15596)
Run Code Online (Sandbox Code Playgroud)

在 ViewPager2 的第 537 行中有一个 if 导致异常:

        // Extra checks verifying assumptions
        // TODO: remove after testing
        View snapView1 = mPagerSnapHelper.findSnapView(mLayoutManager);
        View snapView2 = mLayoutManager.findViewByPosition(snapPosition);
        if (snapView1 != snapView2) {
            throw new IllegalStateException("Design assumption violated.");
        }
Run Code Online (Sandbox Code Playgroud)

这是我更新适配器列表的方式:

adapter.list = newList
adapter.notifyDataSetChanged()
viewpager.setCurrentItem(0, true)
Run Code Online (Sandbox Code Playgroud)

它仅在smoothScroll设置为时发生true

我错过了什么?

编辑: 我使用androidx.viewpager2.widget.ViewPager2可用com.google.android.material:material:1.1.0-alpha08

android kotlin android-viewpager2

9
推荐指数
2
解决办法
3214
查看次数

Viewpager2 FragmentStateAdapter 中的“预期适配器在恢复状态时是‘新鲜’的”

当我尝试重新使用 Viewpager2 FragmentStateAdapter 时,出现此错误。我已经尝试将适配器设置为 null ,onDestroyView但这无济于事。

发生这种情况是因为我使用的是 Jetpack Navigation 库。当我离开片段时,视图被破坏。当我返回时,它被重新创建,我需要再次设置适配器。当我这样做时,适配器内部已经有片段,这会在restoreState().

android android-recyclerview android-viewpager2

9
推荐指数
0
解决办法
613
查看次数

java.lang.IllegalStateException:页面只能偏移一个正数

我在我的预发布报告中收到此错误,但它没有显示对我的 .java 文件的任何引用。任何人都可以对此有所了解吗?

我正在使用ViewPager2(1.0.0) 进行页面转换。

Issue: java.lang.IllegalStateException: Page can only be offset by a positive amount, not by -54
 FATAL EXCEPTION: main
Process: [redacted], PID: 18424
java.lang.IllegalStateException: Page can only be offset by a positive amount, not by -54
    at androidx.viewpager2.widget.ScrollEventAdapter.updateScrollEventValues(ScrollEventAdapter.java:280)
    at androidx.viewpager2.widget.ScrollEventAdapter.onScrolled(ScrollEventAdapter.java:178)
    at androidx.recyclerview.widget.RecyclerView.dispatchOnScrolled(RecyclerView.java:5173)
    at androidx.recyclerview.widget.RecyclerView$ViewFlinger.run(RecyclerView.java:5338)
    at android.view.Choreographer$CallbackRecord.run(Choreographer.java:858)
    at android.view.Choreographer.doCallbacks(Choreographer.java:670)
    at android.view.Choreographer.doFrame(Choreographer.java:603)
    at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:844)
    at android.os.Handler.handleCallback(Handler.java:746)
    at android.os.Handler.dispatchMessage(Handler.java:95)
    at android.os.Looper.loop(Looper.java:148)
    at android.app.ActivityThread.main(ActivityThread.java:5459)
    at java.lang.reflect.Method.invoke(Method.java)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:728)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
Run Code Online (Sandbox Code Playgroud)

我发现这个关于 ViewPager2 的页面参考了一个类似的错误,即 ViewPager2 的错误。

可能相关:

我最近才开始收到此错误。我最近以下列方式更改了我的代码。我正在覆盖该 …

java android android-viewpager2

9
推荐指数
2
解决办法
1260
查看次数

页面包含一个带有 LayoutTransition(或 animateLayoutChanges="true")的 ViewGroup,这会干扰滚动动画

我将 Fragment 与 ViewPager2 一起使用,我注意到在运行 Android 8 或 9 的小米、宇龙、华硕、vivo 等设备中出现了两个相关的 IllegalStateExceptions(我自己无法重现):

Fatal Exception: java.lang.IllegalStateException: Page can only be offset by a positive amount, not by -758
       at androidx.viewpager2.widget.ScrollEventAdapter.updateScrollEventValues(ScrollEventAdapter.java:280)
       at androidx.viewpager2.widget.ScrollEventAdapter.onScrolled(ScrollEventAdapter.java:178)
       at androidx.recyclerview.widget.RecyclerView.dispatchOnScrolled(RecyclerView.java:5173)
       at androidx.recyclerview.widget.RecyclerView$ViewFlinger.run(RecyclerView.java:5338)
       at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1029)
       at android.view.Choreographer.doCallbacks(Choreographer.java:834)
       at android.view.Choreographer.doFrame(Choreographer.java:760)
       at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1015)
       at android.os.Handler.handleCallback(Handler.java:873)
       at android.os.Handler.dispatchMessage(Handler.java:99)
       at android.os.Looper.loop(Looper.java:224)
       at android.app.ActivityThread.main(ActivityThread.java:7083)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:537)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:928)
Run Code Online (Sandbox Code Playgroud)

Fatal Exception: java.lang.IllegalStateException: Page(s) contain a ViewGroup with a LayoutTransition (or animateLayoutChanges="true"), which interferes with the scrolling animation. Make sure to call …
Run Code Online (Sandbox Code Playgroud)

java android android-recyclerview android-viewpager2

9
推荐指数
1
解决办法
1413
查看次数

ViewPager2 崩溃

我正在使用带有 BottomNavigationView 的高级导航组件。

在一个选项卡中,我有 ViewPager2。当我第一次点击 Tab 时工作正常。

尽管第二次出现该选项卡应用程序不断崩溃。如果有人可以帮助,下面是崩溃日志,谢谢。

java.lang.IllegalArgumentException at androidx.core.util.Preconditions.checkArgument(Preconditions.java:36) at androidx.viewpager2.adapter.FragmentStateAdapter.onAttachedToRecyclerView(FragmentStateAdapter.java:140) at androidx.recyclerview.widget.set.RecyclerView() RecyclerView.java:1206) at androidx.recyclerview.widget.RecyclerView.setAdapter(RecyclerView.java:1158) at androidx.viewpager2.widget.ViewPager2.setAdapter(ViewPager2.java:460) at com。.ui.home.history.HistoryFragment.setupAdapter(HistoryFragment.kt:25) 在 com。.ui.home.history.HistoryFragment.viewSetup(HistoryFragment.kt:21) at com.****.base.BaseFragment.onViewCreated(BaseFragment.kt:37) at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager. java:332) 在 androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1187) 在 androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1356) 在 androidx.fragment.app.FragmentManager.moveFragmentToFragmentManager.moveFragment(FragmentManager.java:1187) .java:1434) 在 androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1497) 在 androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:2625) 在 androidx.fragment.app.FragmentManager.dispatchCreatedActivity FragmentManager.java:2577) 在 androidx.fragment.app.Fragment.performActivityCreated(Fragment.java:2722) 在 androidx.fragment.app.FragmentStateManager。activityCreated(FragmentStateManager.java:346) at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1188) at androidx.fragment.app.FragmentManager.addAddedFragments(FragmentManager.java:2224) at androidx.fragment.app.Fragment .executeOpsTogether(FragmentManager.java:1997) 在 androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:1953) 在 androidx.fragment.app.FragmentManager.execPendingActions(FragmentManager.java:1849) FragmentManager$4.run(FragmentManager.java:413) at android.os.Handler.handleCallback(Handler.java:873) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loop( Looper.java:193) at android.app.ActivityThread.main(ActivityThread.java:6940) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os。RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:537) 在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)

这是我的片段代码:

private val …
Run Code Online (Sandbox Code Playgroud)

android android-recyclerview android-jetpack android-viewpager2 android-jetpack-navigation

9
推荐指数
3
解决办法
3142
查看次数

返回父片段时会重新创建 ViewPager2 内的片段

我的一个片段中有一个ViewPager2(我们称之为片段 A)。viewpager 使用 aFragmentStateAdapter创建许多片段作为子片段(我们将这些片段称为片段children)。当用户单击片段 A 中的按钮时,我将其替换为片段 B。

现在,当用户单击设备后退按钮返回到片段 A 时,我可以看到系统自动恢复了子项(它们没有显示在 viewpager 中,但调用了它们的 onCreateView 方法并将保存的包传递到他们)。如何避免这种行为。我不希望孩子被自动重新创建和恢复。

android android-fragments android-viewpager android-viewpager2

9
推荐指数
2
解决办法
1094
查看次数

ViewPager2 无法动态添加删除片段

在索引处删除/添加片段会导致 Viewpager2 出现意外行为。这是不可能的,ViewPager但预计可以与Viewpager2. 它会导致重复的片段和不同步TabLayout这是一个重现此问题的演示项目。有一个切换按钮可以删除片段并将其重新附加到特定索引处。在这种情况下,附加的片段应该是绿色的,但它是蓝色的,不知何故有 2 个蓝色片段。

这是我的适配器的外观

class ViewPager2Adapter(activity: FragmentActivity) : FragmentStateAdapter(activity) {
    val fragmentList: MutableList<FragmentName> = mutableListOf()

    override fun getItemCount(): Int {
        return fragmentList.size
    }

    override fun createFragment(position: Int): Fragment {
        return when (fragmentList[position]) {
            FragmentName.WHITE -> WhiteFragment()
            FragmentName.RED -> RedFragment()
            FragmentName.GREEN -> GreenFragment()
            FragmentName.BLUE -> BlueFragment()
        }
    }

    fun add(fragment: FragmentName) {
        fragmentList.add(fragment)
        notifyDataSetChanged()
    }

    fun add(index: Int, fragment: FragmentName) {
        fragmentList.add(index, fragment)
        notifyDataSetChanged()
    }

    fun remove(index: Int) …
Run Code Online (Sandbox Code Playgroud)

android android-fragments android-viewpager android-viewpager2

8
推荐指数
1
解决办法
2126
查看次数