View.inflate和LayoutInflater.inflate方法区别及源码

本文探讨了View.inflate和LayoutInflater.inflate的区别。在实现列表条目加颜色功能时,使用View.inflate遇到问题,通过查看源码发现其设置layoutParams的条件。因列表调用getView时已设置父布局,不能给View.inflate设置root,还给出了两种解决方法。

        View.inflate和LayoutInflater.inflate都是我们平时常用的方法,一直来回用也没有注意两者的区别,做一个列表让条目加上颜色的功能,使用View.inflate总是不能实现,于是找了下源码。

我们首先看一看View.inflate的调用:

public static View inflate(Context context, @LayoutRes int resource, ViewGroup root) {
        LayoutInflater factory = LayoutInflater.from(context);
        return factory.inflate(resource, root);
    }
  public View inflate(@LayoutRes int resource, @Nullable ViewGroup root){
        /**
        请仔细看这个位置,root != null,也就是说当我们在View.inflate中第三个参数
        给的是null,那么attachToRoot就已经指定了false
        */
        return inflate(resource, root, root != null);
    }

下面是核心的部分:

             
            if (root != null) {
                        if (DEBUG) {
                            System.out.println("Creating params from root: " +
                                    root);
                        }
                        // Create layout params that match root, if supplied
                        params = root.generateLayoutParams(attrs);
                        if (!attachToRoot) {
                            // Set the layout params for temp if we are not
                            // attaching. (If we are, we use addView, below)
                            //只有当root不为空并且attachToRoot不为空时temp才会有赋值
                            temp.setLayoutParams(params);
                        }
                    }

                    if (DEBUG) {
                        System.out.println("-----> start inflating children");
                    }

                    // Inflate all children under temp against its context.
                    rInflateChildren(parser, temp, attrs, true);

                    if (DEBUG) {
                        System.out.println("-----> done inflating children");
                    }

                    // We are supposed to attach all the views we found (int temp)
                    // to root. Do that now.
                    if (root != null && attachToRoot) {
                        root.addView(temp, params);
                    }

从上面我们能看出,只有当root以及attachToRoot不为空时,temp会设置layoutParams,也就是说如果需要对列表的条目的父控件做处理,那么root我们必须设置不为空,但是列表中,我们不能给View.inflate设置root,因为无论使用listview还是recycleView,调用getVIew的时候就已经设置过父布局了,如果这个时候我们传入root,会报出 The specified child already has a parent. " "You must call removeView() on the child's parent first

所以解决方法:

1 使用LayoutInflater.from(viewGroup.getContext()).inflate(android.R.layout.aaa, viewGroup,false));

2 给你的布局多套用一层,你不是说最外层的设置不起作用了吗,只能绘制加进去的view,那么我就把我原来的父控件外面再套一层,使用的时候设置父控件下面一级的布局,当然这个会造成布局的过度重绘,不建议。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值