RecyclerView中的item的match_parent属性失效问题解决方案。

本文详细解析了在使用RecyclerView时遇到的布局问题及其解决方案,通过对比不同的LayoutInflater方法,深入探讨了为何某些情况下match_parent属性会失效。
部署运行你感兴趣的模型镜像

解决方案:

    1.  item使用RelativeLayout布局,并且布局中的view至少有一个layout_alignParentRight=true
    2. 在adapte中的onCreateViewHolder,使用
  
   public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
//        View view = View.inflate(parent.getContext(), R.layout.item_fra_main2, null);
        View view = mInflater.from(mContext).inflate(R.layout.item_fra_main2, parent, false);
        ViewHolder holder = new ViewHolder(view);
        return holder;
    }

至今为止,Google了一轮都没有找到产生这个问题的原因,小编就不自量力一下,挖个秦始皇出来!

原理说明:

     
  代码一、
  View.inflate(parent.getContext(), R.layout.item_fra_main2, parent);
    对应的是:LayoutInflate.inflate(resource , parent, true);//在RecycleView下奔溃
 
  代码二、
  View.inflate(parent.getContext(), R.layout.item_fra_main2, null);
    对应的是:LayoutInflate.inflate(resource , null, false);//match_parent属性失效
 
   代码三、
    mInflater.from(mContext).inflate(R.layout.item_fra_main2, parent, false);    
    对应的是:LayoutInflate.inflate(resource , parent, false);//就需要这种方案

 

分析一:

    先看代码一的奔溃问题,奔溃的内容是The specified child already has a parent. You must call removeView() on the child's parent first。
    这个问题可以追溯到ListView的原理,RecycleView的基本原理和ListView是一样的,就是布局复用。
   

   
  
   由于Root就是RecycleView,因此,已经有了childView就不应再addView进去了。

分析二、

      现在就看为什么代码二中的match_parent失效问题了,以及代码三的match_parent有效的情况。

     先说代码三,分析原因肯定是跟源码了

   

  

  

 
     从源码中可以看出,传入
 parent 参数,null与非null的分水岭就在于,对childView是否需要setLayoutParams。

     来看看setLayoutParams 里面都做了什么?

     

      

     这里有一段非常的重要,就是childview会去通知parentVIew也去调用这个函数。因此直到最底部的RootView都会被通知调用这个函数。

    

分析三、    

        现在知道分水岭之后。就要看看RecycleView是怎么加载ChildView的了。 

    直接调出RecyclerView.java类,RecycleView中有个mChildHelper变量。  

    


   找到了加载ChildView的入口。继续跟踪到AddView里面(ViewGroup.java)

  

    哈哈!这边又有一个分水岭,从Inflate中的分水岭关于Params的问题,这边就呈现出来了。

   

    如果,Inflate中设置了Parent,那么RecycleView就会使用ChildView配置的params去add ChildView。因此,这时候的match_parent就会生效。

   

分析四、

         那为什么params为null后,addView()函数导致了childview中的match_parent实效呢?导致实际的效果与预想不同,而只是自适应大小。

     再研究下addView的源码:

     里面有句话child.getLayoutParams(),而getLayoutParams方法说明中有句话为:This method may return null if this View is not attached to a parent ViewGroup。意思就是如果没有被添加至父控件时,结果是会返回null的,很显然,到目前的代码跟踪情况来看,vChild还没有被添加至linParent,所以会去调用generateDefaultLayoutParams()方法,而generateDefaultLayoutParams的方法实现如下:

 

protected LayoutParams generateDefaultLayoutParams() { return new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); }


 所以就很明显的造成了子布局android:layout_width="match_parent"属性失效。


分析过程有点复杂,但总算对View加载有了更加清楚的认识!

 问题提供者(geolo:http://blog.youkuaiyun.com/GEOLO)
   
    

您可能感兴趣的与本文相关的镜像

Stable-Diffusion-3.5

Stable-Diffusion-3.5

图片生成
Stable-Diffusion

Stable Diffusion 3.5 (SD 3.5) 是由 Stability AI 推出的新一代文本到图像生成模型,相比 3.0 版本,它提升了图像质量、运行速度和硬件效率

<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" xmlns:app="http://schemas.android.com/apk/res-auto"> <androidx.appcompat.widget.LinearLayoutCompat android:layout_width="match_parent" android:orientation="vertical" android:layout_height="wrap_content"> <androidx.appcompat.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="wrap_content" app:title="" app:navigationIcon="@drawable/back"> </androidx.appcompat.widget.Toolbar> <ImageView android:layout_width="match_parent" android:layout_height="180dp" android:src="@mipmap/picture_8" android:scaleType="centerCrop"/> <androidx.appcompat.widget.LinearLayoutCompat android:layout_width="match_parent" android:layout_margin="10dp" android:orientation="vertical" android:layout_height="wrap_content"> </androidx.appcompat.widget.LinearLayoutCompat> <TextView android:layout_marginTop="5dp" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="泰山,又名岱山、岱宗、岱岳、东岳、泰岳,为五岳之一,有“五岳之首”、“五岳独尊”、“天下第一山”之称,被中外学者称为“中国的奥林匹斯山”,位于山东省中部,隶属于泰安市,绵亘于泰安、济南、淄博三市之间,总面积25000公顷,主峰玉皇顶海拔约1545米"/> </androidx.appcompat.widget.LinearLayoutCompat> </RelativeLayout>
06-24
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值