Pages must fill the whole ViewPager2 (use match_parent)

本文详细剖析了Viewpager2中子视图宽高须为MATCH_PARENT的限制,展示了异常抛出的代码,并提供了解决方案,包括调整布局和动态设置LayoutParams。重点在于理解监听器的作用及XML布局设置的常见误区。

从Viewpager2源码中找出抛出异常的代码

private RecyclerView.OnChildAttachStateChangeListener enforceChildFillListener() {
        return new RecyclerView.OnChildAttachStateChangeListener() {
            @Override
            public void onChildViewAttachedToWindow(@NonNull View view) {
                RecyclerView.LayoutParams layoutParams =
                        (RecyclerView.LayoutParams) view.getLayoutParams();
                if (layoutParams.width != LayoutParams.MATCH_PARENT
                        || layoutParams.height != LayoutParams.MATCH_PARENT) {
                    throw new IllegalStateException(
                            "Pages must fill the whole ViewPager2 (use match_parent)");
                }
            }

            @Override
            public void onChildViewDetachedFromWindow(@NonNull View view) {
                // nothing
            }
        };
    }

如果子view的宽和高不是Match_parent就会抛出异常 ,我们在看下enforceChildFillListener

mRecyclerView.addOnChildAttachStateChangeListener(enforceChildFillListener());

一个注册监听,我们在看下addOnChildAttachStateChangeListener方法

 public void addOnChildAttachStateChangeListener(
            @NonNull OnChildAttachStateChangeListener listener) {
        if (mOnChildAttachStateListeners == null) {
            mOnChildAttachStateListeners = new ArrayList<>();
        }
        mOnChildAttachStateListeners.add(listener);
    }

这个方法就是注册一个监听器,当子视图附加到RecyclerView或从RecyclerView分离时,该监听器就会收到通知, 问题的原因找到了,那么问题就好解决了。
归根结底就是子view的宽和高并没有起到效果,虽然在xml文件中设置了,类似这样

<?xml version="1.0" encoding="UTF-8"?>
<androidx.appcompat.widget.AppCompatImageView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/item_guide_img"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:srcCompat="@mipmap/audio_stop"
    tools:ignore="MissingDefaultResource" />

或者这样都是不行的

<?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"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <androidx.appcompat.widget.AppCompatImageView xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:id="@+id/item_guide_img"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:srcCompat="@mipmap/audio_stop"
        tools:ignore="MissingDefaultResource" />

</LinearLayout>

解决方案有两种:
第一种就是

  View inflate = LayoutInflater.from(parent.getContext())
                    .inflate(R.layout.item_guide_img, parent,false)
  // 我们给view设置父布局

第二种:

  View inflate = LayoutInflater.from(parent.getContext())
                    .inflate(R.layout.item_guide_img, null);
            
            ViewGroup.LayoutParams layoutParams =
                    new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);

            inflate.setLayoutParams(layoutParams);
//动态设置宽和高
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值