如何在xml中设置 RecyclerView的 LayoutManager以及为什么不要这样做
原文:Android DTT #13 — How To Set RecyclerView’s LayoutManager in XML and Why You Shouldn’t
绝大多数关于RecyclerView的教程在讲到如何设置LayoutManager的时候都是这样写的:
public void onCreate(Bundle savedInstanceState) {
....
RecyclerView rv = (RecyclerView) findViewById(R.id.rv);
rv.setLayoutManager(new LinearLayoutManager(this));
....
}
实际上谷歌 “RecyclerView tutorial”这个关键词的前5个结果都是用的这种方式,包括来自 developers.android.com 的那篇也是。这就造成了Java代码是设置LayoutManager的唯一方式的印象。但实际上还有一个xml属性:app:layoutManager。下面是文档中关于这个属性的描述:
所要使用的布局管理器的类名称
这个类必须继承了android.support.v7.widget.RecyclerView$LayoutManager 并且有一个默认的或者带(android.content.Context, android.util.AttributeSet, int, int)签名的构造函数。
我们可以在xml中指定完全限定类名来使用LinearLayoutManager:
<android.support.v7.widget.RecyclerView
android:id="@+id/rv"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layoutManager="android.support.v7.widget.LinearLayoutManager"
/>
这跟前面的Java代码是等效的。一个垂直的reverseLayout为false的LinearLayoutManager。
如果想改变布局方向,可以使用 android:orientation="horizontal",同样还可以使用app:reverseLayout, app:stackFromEnd, app:spanCount等属性。
你也可以在xml中使用 GridLayoutManager 和 StaggeredGridLayoutManager。如果你使用一个自定义的LayoutManager,注意在自定义的类中提供所需的构造函数。
为什么Java代码的方式更受欢迎?
我以为这是support library的一个新功能,虽然现在用的人不多,但是今后会变得流行。但是并没有这样,原因是反射的问题。
我一直在思考它是如何工作的。因为属性一般只能提供很简单的值,比如integer, string等。但是为什么它可以提供一个对象?在稍微深入了下RecyclerView的源码之后我发现它使用了反射来实力化xml中给出的LayoutManager。你可以在这个类的createLayoutManager(Context, String, AttributeSet)函数中找到。
反射对于一个资源有限的系统来说是不好的。它非常慢,一般要尽量避免使用。
幸运的是我们知道了另一种设置LayoutManager的方法,但是也要记住尽量不要这样用。
ADTT (Android 开发提示与技巧) 是我打算在5月完成的31篇系列博客,这里是目录。