2023年7月15日发(作者:)
带你了解BRVAH(BaseRecyclerViewAdapterHelper)这个框架我想做Android的应该都⽐较熟悉了,如果不熟悉的可以百度,这⾥就不啰嗦了。最近在使⽤该框架给横向 RecyclerView 添加底部布局时出现了问题:添加的底部布局(footer_view)的 layout_width 和 layout_height 都是写死的值,但是当 add 进去之后滑动 RecyclerView 到最后⼀个,footer_view 独⾃占据了⼀屏幕,⽽且footer_view ⾼度变成了 wrap_content代码如下//布局样式 xmlns:android="/apk/res/android" xmlns:app="/apk/res-auto" xmlns:tools="/tools" android:id="@+id/cl_random_author_foot" android:layout_width="121dp" android:layout_height="160dp" android:layout_marginEnd="12dp" android:background="@drawable/shape_random_author_item_bg">
* Inflate a view from an XML resource. This convenience method wraps the {@link * LayoutInflater} class, which provides a full range of options for view
inflation.
*
* @param context The Context object for your activity or application.
* @param resource The resource ID to inflate
* @param root A view group that will be the parent. Used to properly inflate the * layout_* parameters.
* @see LayoutInflater
*/public static View inflate(Context context, @LayoutRes int resource, ViewGroup root) {
LayoutInflater factory = (context);
return e(resource, root);}通过源码可以发现,e 通过 (context) 然后调⽤ inflate ⽅法,这与 getLayoutInflater().inflate 最终调⽤的是同⼀个⽅法,只是参数不同。那我们再看⼀下 e(resource, root) ⾥⾯都执⾏了什么。public View inflate(@LayoutRes int resource, @Nullable ViewGroup root) {
return inflate(resource, root, root != null);}这⾥⾯只有⼀句,将参数进⾏了添加,这样后⾯执⾏的就和 e 是同样的代码了。public View inflate(@LayoutRes int resource, @Nullable ViewGroup root, boolean attachToRoot) {
final Resources res = getContext().getResources();
if (DEBUG) {
Log.d(TAG, "INFLATING from resource: "" + ourceName(resource) + "" (" + tring(resource) + ")");
}
final XmlResourceParser parser = out(resource);
try {
return inflate(parser, root, attachToRoot);
} finally {
();
}}这⾥代码很简单,将添加的 view 视图进⾏了解析,然后⼜调⽤了 inflate ⽅法,我们再往下看。public View inflate(XmlPullParser parser, @Nullable ViewGroup root, boolean
attachToRoot) { ....省略.... // Temp is the root view that was found in the xml final View temp = createViewFromTag(root, name, inflaterContext, attrs); Params params = null; if (root != null) {
if (DEBUG) { n("Creating params from root: " + root);
}
// Create layout params that match root, if supplied
params = teLayoutParams(attrs);
if (!attachToRoot) {
// Set the layout params for temp if we are not
// attaching. (If we are, we use addView, below)
outParams(params);
} } ....省略.... //We are supposed to attach all the views we found (int temp) // to root. Do that now. if (root != null && attachToRoot) { w(temp, params);} // Decide whether to return the root that was passed in or the // top view found in xml. if (root == null || !attachToRoot) {
result = temp; } } ....省略....}终于到最核⼼的地⽅了,在调⽤ e 时 root 传⼊的是 null,那到这⼀步⼊参就是 inflate(parser, null, false),因此会直接⾛ reslut =temp 这⼀步,在创建 temp 时会调⽤ ViewGroup 的 generateDefaultLayoutParams() ⽅法将宽⾼全部设置成wrap_content。所以添加的底部布局宽⾼应该都是 wrap_content。⼆、到这⾥我们知道了底部布局为什么⾼度是 wrap_content,但是还有两个疑问:1. 宽度为什么是 match_parent ;2. 怎么让宽⾼都按照设置的值进⾏显⽰。接下来咱们先解决第⼆个问题(怎么让宽⾼都按照设置的值进⾏显⽰),根据源码可以知道要想设置固定值得宽⾼,root 必须不能为空 ⽽且attachToRoot 必须为 false。根据这两个我们可以知道 e 是不能满⾜的了,那咱们就换⽤ e 试试。根据源码可以知道, 会直接⾛到 public View inflate(@LayoutRes int resource, @Nullable ViewGroup root, booleanattachToRoot) 这⼀步,那要想满⾜上⾯两个条件就好办了,⾸先随便找⼀个 ViewGroup 作为 root,然后再让 attachToRoot 等于 false。代码如下:e(er_view_foot_random_author, recyclerViewAuthor, false)效果如下:通过效果图可以发现,⾼度已经不是 wrap_content,同时宽度也没有变成 match_parent ,⼀举两得。但还是有问题:底部布局宽度虽然没有match_parent,但是仍然单独占据了⼀屏幕。通过刚才的分析可以知道,创建底部布局是没有任何问题的了,那么问题⼀定是在添加的时候。那我们就来看看 terView() 这个⽅法吧。/**
* Append footer to the rear of the mFooterLayout.
*
* @param footer
*/public int addFooterView(View footer) {
return addFooterView(footer, -1, AL);}通过源码可以发现,原来是做了默认配置,⽽且是单独添加的⽅向并不是通过 recyclerView 的 layoutManager 来判断⽅向的。那我们就⾃⼰来设置⽅向。terView(randomAuthorFootView, -1, NTAL)再看效果ok,问题全部解决。让我们来总结⼀下:1. getLayoutInflater().inflate() 与 e() 以及 (this).inflate() 最终都是调⽤都是同⼀个⽅法。2. 使⽤ e() 时,root 传 null,则⽣成的 View 宽⾼均为 wrap_content,并不会根据设定的 layout_width 和 layout_height 去显⽰;若 root 不为空,则会将想要⽣成的 view 直接添加到 root 中,并返回 root。3. 使⽤ getLayoutInflater().inflate() 时,若 root 不为空,同时 attachToRoot 为 false,则⽣成的 View 宽⾼为设定的 layout_width 和layout_height 去显⽰;若 root 为空,attachToRoot 为 false,则⽣成的 View 宽⾼均为 wrap_content。
发布者:admin,转转请注明出处:http://www.yc00.com/web/1689428219a246546.html
评论列表(0条)