android.support.v4.view.ViewPager cannot be cast to com.custom.NoScrollViewPager 解决方案

本文介绍了一个在Android应用开发中遇到的问题,当尝试禁用ViewPager滑动时出现的ClassCastException异常。通过自定义NoScrollViewPager类并正确修改布局文件,成功解决了这一常见难题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近在写一个Android APP的过程中,由于用到了禁止滑动的Viewpager,我采用了前辈大牛提供的解决方案,

网址如下:https://blog.youkuaiyun.com/yilei0033/article/details/79444099

简单来说,是自定义一个继承ViewPager的类:NoScrollViewPager,重写了onInterceptTouchEvent(MotionEvent event)及添加了setNoScroll(boolean noScroll)方法。在运行时,报出了这样的一个异常:

01-20 11:12:12.890: E/AndroidRuntime(32097): Caused by: java.lang.ClassCastException: android.support.v4.view.ViewPager cannot be cast to com.example.library.NoScrollViewPager

这个异常,我记得在我写上一个APP的时候就遇到过,这次又被困扰了一段时间,特此写下来提醒自己。

先附上我项目中的代码:

首先,是自定义的NoScrollViewPager,继承了android.support.v4.view.ViewPager 。

NoScrollViewPager.java
public class NoScrollViewPager extends android.support.v4.view.ViewPager {
	private boolean isCanScroll = false;

	public NoScrollViewPager(Context context) {
		super(context);
		// TODO Auto-generated constructor stub
	}

	public NoScrollViewPager(Context context, AttributeSet attrs) {
		super(context, attrs);
	}

	public void setScanScroll(boolean isCanScroll) {
		this.isCanScroll = isCanScroll;
	}

	@Override
	public void scrollTo(int x, int y) {
		super.scrollTo(x, y);
	}

	@SuppressLint("ClickableViewAccessibility")
	@Override
	public boolean onTouchEvent(MotionEvent arg0) {
		// TODO Auto-generated method stub
		if (isCanScroll) {
			return super.onTouchEvent(arg0);
		} else {
			return false;
		}

	}

	@Override
	public boolean onInterceptTouchEvent(MotionEvent arg0) {
		// TODO Auto-generated method stub
		if (isCanScroll) {
			return super.onInterceptTouchEvent(arg0);
		} else {
			return false;
		}
	}

	@Override
	public void setCurrentItem(int item, boolean smoothScroll) {
		// TODO Auto-generated method stub
		super.setCurrentItem(item, smoothScroll);
	}

	@Override
	public void setCurrentItem(int item) {
		// TODO Auto-generated method stub
		super.setCurrentItem(item, false);
	}
}

 接下来,是我自定义的ViewPagerFragment,构造函数中以layout的id为参数绑定布局文件,从而实现代码复用。

其中,mViewPager是android.support.v4.view.ViewPager类型。

SingleViewPagerFragment.java
public class SingleViewPagerFragment extends Fragment {

	// TabLayout
	protected TabLayout mTabLayout;
	// ViewPager
	protected ViewPager mViewPager;
	// Title
	protected List<String> mTitle;
	// Fragment
	protected List<Fragment> mFragment;
	// View
	protected View view;

	private int layout;
	
	public SingleViewPagerFragment(int layout) {
		// TODO Auto-generated constructor stub
		this.layout = layout;
	}
	
	public SingleViewPagerFragment() {
		// TODO Auto-generated constructor stub
	}
	
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		// this.requestWindowFeature(Window.FEATURE_NO_TITLE);//去掉标题栏
	}

	/*
	 * 初始化数据
	 */
	@SuppressLint("InflateParams")
	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		if (view != null) {
			ViewGroup parent = (ViewGroup) view.getParent();
			if (parent != null) {
				parent.removeView(view);
			}
			return view;
		}
		view = inflater.inflate(layout, null);

		initData();
		initView(view);
		return view;
	}
	
	protected void initData() {

		mTitle = new ArrayList<String>();
		mFragment = new ArrayList<Fragment>();
		// DatabaseQuery.CollegeMkdirs();//创建下载文件的目录
	}

	/*
	 * 初始化view
	 */
	protected void initView(View v) {

	}
}

下面是layout文件:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <android.support.v4.view.ViewPager
        android:id="@+id/main_ViewPager"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1" />
    

    <android.support.design.widget.TabLayout
        android:id="@+id/main_TabLayout"
        style="@style/Base.Widget.Design.TabLayout"
        android:layout_width="match_parent"
        android:layout_height="60dip"
        android:background="#FAFAFA"
        app:tabGravity="fill"
        app:tabMode="fixed"
        app:tabPaddingBottom="-1dp"
        app:tabPaddingEnd="-1dp"
        app:tabPaddingStart="-1dp"
        app:tabPaddingTop="-1dp" />

</LinearLayout>

 最后,是具体的ViewPager,继承了我自定义的SingleViewPagerFragment,并在initView中,使用以下代码:

mViewPager = (NoScrollViewPager) v.findViewById(R.id.main_ViewPager);

获取NoScroolViewPager。结果出现了题目所述异常。

//MainViewPagerFragment.java
public class MainViewPagerFragment extends SingleViewPagerFragment {
	public MainViewPagerFragment(int layout) {
		super(layout);
		// TODO Auto-generated constructor stub
	}

	@Override
	public void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
	}

	public MainViewPagerFragment() {
		// TODO Auto-generated constructor stub
	}
	
	protected void initData() {
		super.initData();
		mTitle.add("发 单");
		mTitle.add("抢 单");
		mTitle.add("我 的");

		mFragment.add(new DeliverFragment());
		mFragment.add(new ReceiveFragment());
		mFragment.add(new UserFragment());
		// DatabaseQuery.CollegeMkdirs();//创建下载文件的目录
	}

	@Override
	protected void initView(View v) {
		// TODO Auto-generated method stub
		mTabLayout = (TabLayout) v.findViewById(R.id.main_TabLayout);
		mViewPager = (NoScrollViewPager) v.findViewById(R.id.main_ViewPager);
		super.initView(v);
		// 添加适配器
		MainPagerAdapter myFragmentPagerAdapter = new MainPagerAdapter(getActivity().getSupportFragmentManager(),
				mFragment, mTitle, this.getActivity());
		mViewPager.setAdapter(myFragmentPagerAdapter);
		mViewPager.setOffscreenPageLimit(mTabLayout.getTabCount());

		// mViewPager
		mViewPager.addOnPageChangeListener(new OnPageChangeListener() {

			@Override
			public void onPageSelected(int arg0) {
				// TODO Auto-generated method stub
				mTabLayout.getTabAt(arg0).select();
			}

			@Override
			public void onPageScrolled(int arg0, float arg1, int arg2) {
				// TODO Auto-generated method stub

			}

			@Override
			public void onPageScrollStateChanged(int arg0) {
				// TODO Auto-generated method stub

			}
		});

		mTabLayout.setupWithViewPager(mViewPager);
		for (int i = 0; i < mTabLayout.getTabCount(); i++) {
			mTabLayout.getTabAt(i).setCustomView(myFragmentPagerAdapter.getTabView(i));
		}
		mTabLayout.setSelectedTabIndicatorColor(Color.WHITE);
		// this.reflex(mTabLayout);
		mTabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {

			@SuppressWarnings("deprecation")
			@Override
			public void onTabUnselected(Tab tab) {
				// TODO Auto-generated method stub
				switch (tab.getPosition()) {
				case 0:
					tab.getCustomView().findViewById(R.id.item_text).setBackgroundResource(R.drawable.empty_tab);
					break;
				case 1:
					tab.getCustomView().findViewById(R.id.item_text).setBackgroundResource(R.drawable.empty_tab);
					break;
				case 2:
					tab.getCustomView().findViewById(R.id.item_text).setBackgroundResource(R.drawable.empty_tab);
					break;
				}
				TextView textView = (TextView) tab.getCustomView().findViewById(R.id.item_text);
				textView.setTextColor(getResources().getColor(R.color.colorAccent));
			}

			@SuppressWarnings("deprecation")
			@Override
			public void onTabSelected(Tab tab) {
				// TODO Auto-generated method stub
				switch (tab.getPosition()) {
				case 0:
					tab.getCustomView().findViewById(R.id.item_text).setBackgroundResource(R.drawable.tab0);
					break;
				case 1:
					tab.getCustomView().findViewById(R.id.item_text).setBackgroundResource(R.drawable.tab1);
					break;
				case 2:
					tab.getCustomView().findViewById(R.id.item_text).setBackgroundResource(R.drawable.tab2);
					break;
				}
				TextView textView = (TextView) tab.getCustomView().findViewById(R.id.item_text);
				textView.setTextColor(getResources().getColor(R.color.colorSelected));
				mViewPager.setCurrentItem(tab.getPosition());
			}

			@Override
			public void onTabReselected(Tab arg0) {
				// TODO Auto-generated method stub

			}
		});
		mViewPager.setCurrentItem(0);
		mTabLayout.getTabAt(0).select();
	}
}

引发异常的原因,是我仅仅在Fragment中获取NoScroolViewPager时将之强制转化,并没有在layout中将android.support.v4.view.ViewPager替换为我自定义的NoScrollViewPager,正确的layout文件如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <com.example.library.NoScrollViewPager
        android:id="@+id/main_ViewPager"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1" />
    

    <android.support.design.widget.TabLayout
        android:id="@+id/main_TabLayout"
        style="@style/Base.Widget.Design.TabLayout"
        android:layout_width="match_parent"
        android:layout_height="60dip"
        android:background="#FAFAFA"
        app:tabGravity="fill"
        app:tabMode="fixed"
        app:tabPaddingBottom="-1dp"
        app:tabPaddingEnd="-1dp"
        app:tabPaddingStart="-1dp"
        app:tabPaddingTop="-1dp" />

</LinearLayout>

弱智错误。。。。再也不想被它困扰!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值