最近在重写以前刚入门时做的一个小项目,其中在将listView换成RecyclerView后,列表只加载出了一行。先查看了数据源,发现数据没问题,由于改用RecyclerView重点是重写Adapter,所以重点查看Adapter中代码,经过仔细查证,Adapter中并没有发现问题。最后,发现问题出在Item的布局文件,下面是最外层的布局代码:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"//问题就出在这一行 android:background="@color/white" android:orientation="vertical" >但是布局文件是从老项目直接拷过来的(为了省事),为什么以前用listView的时候没出问题呢?于是又去查看以前的代码,终于找到了原因:
convertView=LayoutInflater.from(mActivity).inflate(R.layout.voteitem, null);上面这行代码大家肯定都很熟悉,这是加载Item布局获得view的方法,而问题就出在这,下面是新写的adapter中的代码:
View view= LayoutInflater.from(mContext).inflate(R.layout.voteitem,parent,false);
对比以上两行代码,区别仅仅是inflate()中传入的参数不一样,这里回忆一下LayoutInflater.inflate()方法
View inflate(@LayoutRes int resource, @Nullable ViewGroup root, boolean attachToRoot)
/** * Inflate a new view hierarchy from the specified xml resource. Throws * {@link InflateException} if there is an error. * * @param resource ID for an XML layout resource to load (e.g., * <code>R.layout.main_page</code>) * @param root Optional view to be the parent of the generated hierarchy (if * <em>attachToRoot</em> is true), or else simply an object that * provides a set of LayoutParams values for root of the returned * hierarchy (if <em>attachToRoot</em> is false.) * @param attachToRoot Whether the inflated hierarchy should be attached to * the root parameter? If false, root is only used to create the * correct subclass of LayoutParams for the root view in the XML. * @return The root View of the inflated hierarchy. If root was supplied and * attachToRoot is true, this is root; otherwise it is the root of * the inflated XML file. */
这些是从官方文档中粘贴过来的,自己归纳一下:
1、root为null,attachToRoot失去作用,返回view,而且会忽略view根对象的LayoutParams属性。
2、root不为null,attachToRoot默认为true,会给加载的布局指定父布局(root),返回的是root。
3、root不为null,attachToRoot为false,则将布局文件最外层所有layout属性进行设置,当该View被添加到父View时,Layout属性自动生效,返回的是View,但根对象的LayoutParams属性保留。
所以原来root为null,布局中layout_height="match_parent"并没有生效,所以在加载列表时没有出现异常。而一旦传入了root,view中LayoutParams属性就会生效,由于这里将高度指定为match_parent,所以一条列表项就占满了屏幕,导致出现这个BUG。将layout_height属性改为wrap_content即可。
这里再提一个概念,关于layout_width和layout_height,这里设置的是view在布局中的大小,即view必须存在于一个布局中。
像Activity中的setContentView(),Android会自动在布局文件最外层嵌套一个FrameLayout(id为content),所以我们在xml中最外层定义的这两个属性才会生效。