You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android中禁用ViewPager滑动功能时遭遇显示异常问题

解决CustomViewPager配合AndroidX ViewPager时内容消失的问题

问题背景

创建了CustomViewPager类用于禁用ViewPager的滑动功能,但使用过程中出现ViewPager内容消失的异常,原问题代码如下:

原AdapterViewPager.cs

using System.Collections.Generic;
using Android.Content;
using Android.Util;
using Android.Views;
using AndroidX.Fragment.App;
using AndroidX.ViewPager.Widget;
using Fragment = AndroidX.Fragment.App.Fragment;

namespace Android
{
//NuGet
//ViewPageAdapter
//lifecycle
public class VPAdapter : FragmentStatePagerAdapter
{
    private bool m_enabled;

    List<Fragment> fragments = new List<Fragment>();
    List<string> fragmentsName = new List<string>();

    public VPAdapter(AndroidX.Fragment.App.FragmentManager fragmentManager) : base(fragmentManager)
    {
        fragments = new List<Fragment>();
        fragmentsName = new List<string>();
    }

    public void AddFragment(Fragment fragment, string name)
    {
        fragments.Add(fragment);
        fragmentsName.Add(name);
    }

    public override int Count
    {
        get
        {
            return fragments.Count;
        }

    }

    public override Fragment GetItem(int position)
    {
        return fragments[position];
    }

    public void SetPagingEnabled(bool enabled)
    {
        m_enabled = enabled;
    }
}

public class CustomViewPager : ViewPager
{
    public bool ScrollEnabled;

    public CustomViewPager(Context context, IAttributeSet attrs) : base(context, attrs)
    {
        this.ScrollEnabled = false;
    }

    public override bool OnTouchEvent(MotionEvent e)
    {
        if (this.ScrollEnabled)
        {
            return base.OnTouchEvent(e);
        }
        return false;
    }

    public override bool OnInterceptTouchEvent(MotionEvent e)
    {
        if (this.ScrollEnabled)
        {
            return base.OnInterceptTouchEvent(e);
        }
        return false;
    }
    public void SetPagingEnabled(bool enabled)
    {
        ScrollEnabled = enabled;
    }
}
}

原ActivityMain.cs

//ViewPager
VPAdapter vpAdapter = new VPAdapter(SupportFragmentManager);
//omission
viewPager.Adapter = vpAdapter;

//CustomViewpager
private IAttributeSet attrs;
CustomViewPager customViewPager2 = new CustomViewPager(this, attrs);
customViewPager2.SetPagingEnabled(false);

原activity_main.xml

<Android.CustomViewPager
 android:id="@+id/customViewPager" 
 android:layout_width="match_parent"
 android:layout_height="match_parent">
    <androidx.viewpager.widget.ViewPager
    android:id="@+id/viewPager"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layout_constraintBottom_toTopOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toBottomOf="parent">
    </androidx.viewpager.widget.ViewPager>
</SMP_Android.CustomViewPager>

错误原因分析

  1. 布局嵌套错误:将原生androidx.viewpager.widget.ViewPager嵌套在CustomViewPager中,而CustomViewPager本身就是ViewPager的子类,无需重复嵌套,导致实际显示的CustomViewPager未绑定适配器。
  2. Activity逻辑错误:手动实例化新的CustomViewPager对象但未与布局控件绑定,反而给嵌套的原生ViewPager设置适配器,造成CustomViewPager无内容显示。
  3. 冗余代码:适配器中的m_enabled变量和SetPagingEnabled方法无实际作用,滑动控制逻辑应在CustomViewPager中处理。

修复方案

1. 修改布局文件(activity_main.xml)

移除嵌套的原生ViewPager,直接使用CustomViewPager作为容器:

<Android.CustomViewPager
    android:id="@+id/customViewPager" 
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

2. 清理适配器冗余代码(AdapterViewPager.cs)

移除无用的m_enabled变量和SetPagingEnabled方法:

using System.Collections.Generic;
using Android.Content;
using Android.Util;
using Android.Views;
using AndroidX.Fragment.App;
using AndroidX.ViewPager.Widget;
using Fragment = AndroidX.Fragment.App.Fragment;

namespace Android
{
//NuGet依赖:ViewPageAdapter、lifecycle
public class VPAdapter : FragmentStatePagerAdapter
{
    List<Fragment> fragments = new List<Fragment>();
    List<string> fragmentsName = new List<string>();

    public VPAdapter(FragmentManager fragmentManager) : base(fragmentManager)
    {
        fragments = new List<Fragment>();
        fragmentsName = new List<string>();
    }

    public void AddFragment(Fragment fragment, string name)
    {
        fragments.Add(fragment);
        fragmentsName.Add(name);
    }

    public override int Count => fragments.Count;

    public override Fragment GetItem(int position)
    {
        return fragments[position];
    }
}

public class CustomViewPager : ViewPager
{
    public bool ScrollEnabled;

    public CustomViewPager(Context context, IAttributeSet attrs) : base(context, attrs)
    {
        ScrollEnabled = false;
    }

    public override bool OnTouchEvent(MotionEvent e)
    {
        return ScrollEnabled ? base.OnTouchEvent(e) : false;
    }

    public override bool OnInterceptTouchEvent(MotionEvent e)
    {
        return ScrollEnabled ? base.OnInterceptTouchEvent(e) : false;
    }

    public void SetPagingEnabled(bool enabled)
    {
        ScrollEnabled = enabled;
    }
}
}

3. 修正Activity逻辑(ActivityMain.cs)

绑定布局中的CustomViewPager并设置适配器,同时控制滑动状态:

// 初始化适配器并添加Fragment
VPAdapter vpAdapter = new VPAdapter(SupportFragmentManager);
// 示例:添加Fragment(根据实际需求替换)
vpAdapter.AddFragment(new YourFirstFragment(), "页面1");
vpAdapter.AddFragment(new YourSecondFragment(), "页面2");

// 绑定布局中的CustomViewPager
CustomViewPager customViewPager = FindViewById<CustomViewPager>(Resource.Id.customViewPager);
// 设置适配器
customViewPager.Adapter = vpAdapter;
// 禁用滑动功能
customViewPager.SetPagingEnabled(false);

注意事项

  • 确保CustomViewPager的命名空间在XML布局中正确引用(示例中为Android.CustomViewPager,需与实际命名空间一致)。
  • 必须向适配器中添加至少一个Fragment,否则ViewPager仍会显示为空。
  • 所有依赖库需使用AndroidX版本,避免与Support库混用导致兼容性问题。

内容的提问来源于stack exchange,提问作者yuki yuki

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 20:00:58