详解RecyclerView设置背景图片长宽一样(以GridLayoutManager为例)

详解RecyclerView设置背景图片长宽一样(以GridLayoutManager为例),第1张

概述使用RecyclerView的过程中,由于设置了LayoutManager的关系,控件(的background)往往不能通过指定长宽为match_parent、wrap_content来实现长宽大小相同。

使用RecyclerVIEw的过程中,由于设置了LayoutManager的关系,控件(的background)往往不能通过指定长宽为match_parent、wrap_content来实现长宽大小相同。

面对的问题:

以指定GrIDLayout(HoriZental)布局为例:控件的实际宽度受制于一行分割为几列,粗略来说 宽度 = RecyclerVIEw宽度 ÷ 列数 由于这个过程是运行时确定的,长度预先并不知道宽度的确切值,这会造成长宽不匹配的现象(如图)


图中logo的宽度严格限制在GrIDLayout的每一小格的宽度范围内,长度(在没有父控件的限制下)为初始值。

这里的初始值有两个含义:

①在layout布局文件中指定了长度为“xxdp”等确定值。

②长度指定为“wrap_content” ―― 当背景为矢量图,长度为对应drawable文件中确定的androID:height ;当背景为点阵图,长度为该图分辨率的宽度。

这就使得我们看到的实际效果不是拉成了瘦瘦高高的长竹竿,就是压缩成了矮矮胖胖的矮冬瓜。

我们当然可以在调试时得到控件宽度,再指定其为logo的长度。这样在调试机器上看起来确实长宽相等了,但这真的解决了根本问题吗?

我们的软件要运行在多种分辨率的屏幕下,死板的规定长度必然使得在部分机型下长宽失衡。

因此解决这个问题治标治本的手段在于根据logo的实际宽度来确定长度,令height = wIDth。

怎么求宽度?

接下来就是如何获取wIDth的问题了。

根据上面的公式 宽度 = recyclerVIEw的宽度 ÷ 列数且recyclerVIEw宽度 = grIDLayoutManager.getWIDth();列数 = grIDLayoutManage.getSpanCount();

我们可以轻松获得wIDth = grIDLayoutManager.getWIDth()/grIDLayoutManage.getSpanCount();

当然,为了得到grIDLayoutManager实例,我们需要将它作为RecyclerAdapter构造方法中的参数传入:

public RecyclerSysWebAdapter(Context context,ArrayList<IndexItem> List,OnItemClickListener Listener,GrIDLayoutManager glm) {     this.List = List;     this.context = context;     this.Listener = Listener;     this.glm = glm; }

recyclerVIEw调用方代码如下:

GrIDLayoutManager glm_sys = new GrIDLayoutManager(getContext(),7);//分为7列 recycler_sys.setLayoutManager(glm_sys); //设置布局管理器 recycler_sys.setAdapter(new RecyclerSysWebAdapter(getContext(),item_List_sys,onItemClickListener_sys,glm_sys)); 

接下来就是在RecyclerAdapter中指定logo的长度为该值就行啦:

public voID onBindVIEwHolder(SysWebHolder holder,final int position) {     ...//这里省略处理获取button实例的代码     VIEwGroup.LayoutParams parm = holder.button_img.getLayoutParams(); //获取button背景的LayoutParams实例     parm.height = glm.getWIDth()/glm.getSpanCount()         - holder.button_img.getpaddingleft(); } 

在这里顺便提一下LayoutParams类。该类通过指定wIDth \ height 向父布局说明自己想要的尺寸信息,父布局将根据该信息尽可能满足它。

好了,这样一来我们成功的使得logo长宽相等喽!

还有一件事

你以为这样就结束了?是不是还忘了点什么?

我们来看一下上述设置的实际效果:


哎哎哎!虽然效果有改善,怎么还是长方形的?!

静下心仔细想一下,我们获取的宽度真的是logo的宽度吗?


刚才算出来的值怎么看都像是①号距离啊喂!

我们在设计布局时为了美观往往需要对控件设置 margin 及padding 让彼此间保持一定的距离。我们在获取宽度时当然也要考虑到这个因素了!

获取margin的具体值代码如下:

VIEwGroup.LayoutParams parm = holder.button_img.getLayoutParams(); ((VIEwGroup.marginLayoutParams)parm).leftmargin; 

我们需要显式地将 layoutParams 实例转换为 marginLayoutParams方能获取作为成员变量margin值。

这里获取margin值参考自这篇文章:http://blog.csdn.net/yunxiaoxiaoyun/article/details/22314407点击打开链接

获取padding代码如下(默认paddingleft == paddingRight):

button.getpaddingleft(); 

综合起来代码如下:

public voID onBindVIEwHolder(SysWebHolder holder,final int position) {     ...//省略获取button实例的代码     VIEwGroup.LayoutParams parm = holder.button_img.getLayoutParams();     parm.height = glm.getWIDth()/glm.getSpanCount()         - 2*holder.button_img.getpaddingleft() - 2*((VIEwGroup.marginLayoutParams)parm).leftmargin;//margin为什么要乘以2留给你们思考一下 } 

现在问题彻底解决啦!我们观察一下结果:


PS:差点忘了说,必须要注意的!

recycler_sys = act.findVIEwByID(R.ID.recycler_sys_website); GrIDLayoutManager glm_sys = new GrIDLayoutManager(getContext(),sys_column); recycler_sys.setLayoutManager(glm_sys); recycler_sys.setAdapter(new RecyclerSysWebAdapter(getContext(),glm_sys)); 

请注意我的调用顺序为在setLayoutManager()之后再调用setAdapter()。

若调换两语句顺序会导致设置的长度失效!

具体机理未深究,我猜测原因在于setLayoutManager()的过程中会再次测量并确定各控件的长宽,覆盖之前的设置。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程小技巧。

总结

以上是内存溢出为你收集整理的详解RecyclerView设置背景图片长宽一样(以GridLayoutManager为例)全部内容,希望文章能够帮你解决详解RecyclerView设置背景图片长宽一样(以GridLayoutManager为例)所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/web/1143374.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-31
下一篇 2022-05-31

发表评论

登录后才能评论

评论列表(0条)

保存