关于LayoutInflater动态加载View到AbsListView和ViewGroup之间的区别

</pre>当我们要加载动态加载一个布局并将它添加到ListView和ViewGroup中时,会出现一些问题,如下例:<p></p><p>首先我们看下要加载的布局文件:</p><p></p><pre name="code" class="java"><?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="100dp"
    android:layout_margin="10dp"
    >
    <TextView
        android:background="@drawable/list_item_bk"
        android:id="@+id/tv_content"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"
        android:text="测试文字"
        android:textSize="16sp" />
</LinearLayout>

在这里我们让根布局的高度为100,宽度匹配父窗口(match_parent = -1),设置它外边距margin为10dp,看似没什么问题,向我们之前关于LayoutInflater的inflate方法和LayoutParam分析(二)中分析的那样,我们为了让根布局的的layout_xx属性生效,我们可以有俩种方式。

1.我们在根布局外在加一层任意的ViewGroup,当然了和我们之前关于LayoutInflater的inflate方法和LayoutParam分析(二)分析的一样,这层布局中的layout_xx属性是不生效的,但却可以达到我们想要的效果。

View v = LayoutInflater.from(context).inflate(R.layout.list_item,null);
xx.addView(v);
或者我们可以动态的为该布局添加一个父布局
LinearLayout l = new LinearLayout(context);
View v = LayoutInflater.from(context).inflate(R.layout.list_item,l,true);
xx.addView(l);

2.如果我们可以得到被添加的View的parent,我们可以这样做。

LayoutInflater.from(context).inflate(R.layout.list_item,parent,true);
当parent不为null并且attachToParent为true,inflate会将被加载的view添加到parent中
或者

View v = LayoutInflater.from(context).inflate(R.alyout.lisst_item,parent,false);
parent.addView(v);

但是当我们要将该布局动态的添加为ListView的item时,第一种方式任然可行,但是第二种方式却不能成功,我们看下例子:

R.layout.list_item如上

ListViewAdapter的inflate代码:

 convertView = mInflater.inflate(R.layout.list_item, parent, false);
这样理论是没问题的,我们看下运行截图:
<img src="https://img-blog.csdn.net/20160809151646512?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="图片" width="300" height="500" />
可以看到我们根部局中设置的layout_width 和layout_height都生效了,但是layout_margin却没有生效,这说明我们这种方式Layoutparams确是被设置了,但是为什么margin没有呢?

Debug一下,
我们先找到convertview的值:

图pain

然后我们看下我们关心的几个值parent,LayoutParams

图片

这里我们可以看到我们在getView 中给我们的parent其实就是我们的ListView。

我们在看下layoutParams

图片

而它的layoutParams也为AbsListView.layoutParams。

我们看下这个AbsListView.LayoutParams和我们之前的LinearLayoyt.LayoutParams做parent时的LinearLayout.LayoutParams的区别

AbsListViewparams

图片

LinearLayoutParams(代表了一类如Relativelayoutparams等)

图片

我们可以看到原来他们继承的父类不同,现在我们大致可以从他们的父类名称找到他们的却别,分别查看LayoutParams和MarginLayoutParams对比:

发现原来Layoutpramas没有margin这些属性,而Marginlayoutparams有

所以当我们从convertview = inflate(R.layout.list_item,parent,null);时,由于parent为AbsListView,所以inflate中会将布局中的layout_xx属性设置给AbsListView.LayoutParams

并将该layoutParams设置给convertview,但是由于该layoutParams继承自ViewGroup.LayoytParams,而该类没有margin这些属性,所以,加载后在listview中,只有layout_width 和layout_height这些在ViewGroup.LayoutParams中有的属性才被正确赋值显示,而margin属性丢失。


知道了问题的原因,解决起来就简单了,我们只要是我们想要正确显示的布局的layoutParams为marginlayoutparams,这样margin便能生效。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值