</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的值:
然后我们看下我们关心的几个值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便能生效。