ViewPager2在我当前的项目中使用时,我想使用setOnTouchListener,但我无法获得任何事件。
我决定扩展 ViewPager2 类以覆盖触摸事件方法,但由于类定义是最终的,因此无法实现。
为什么这个类是最终的,有什么方法可以扩展它以便我可以覆盖触摸事件?
我遵循 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
我正在构建一个应用程序ViewPager2,该应用程序在滑动时显示不同的片段。我的适配器FragmentStateAdapter按此处所述进行扩展。
当我将我的应用程序置于后台然后再次恢复时,当前片段消失了。我需要做什么来确保当前片段正确恢复?
(注意:我问的是FragmentStateAdapter,不是FragmentPagerAdapter或FragmentStatePagerAdapter。)
更新 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) 我正在使用 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
当我尝试重新使用 Viewpager2 FragmentStateAdapter 时,出现此错误。我已经尝试将适配器设置为 null ,onDestroyView但这无济于事。
发生这种情况是因为我使用的是 Jetpack Navigation 库。当我离开片段时,视图被破坏。当我返回时,它被重新创建,我需要再次设置适配器。当我这样做时,适配器内部已经有片段,这会在restoreState().
我在我的预发布报告中收到此错误,但它没有显示对我的 .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 的错误。
可能相关:
我最近才开始收到此错误。我最近以下列方式更改了我的代码。我正在覆盖该 …
我将 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) 我正在使用带有 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
我的一个片段中有一个ViewPager2(我们称之为片段 A)。viewpager 使用 aFragmentStateAdapter创建许多片段作为子片段(我们将这些片段称为片段children)。当用户单击片段 A 中的按钮时,我将其替换为片段 B。
现在,当用户单击设备后退按钮返回到片段 A 时,我可以看到系统自动恢复了子项(它们没有显示在 viewpager 中,但调用了它们的 onCreateView 方法并将保存的包传递到他们)。如何避免这种行为。我不希望孩子被自动重新创建和恢复。
android android-fragments android-viewpager android-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