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

 更新时间:2017年12月15日 11:39:12   作者:Bthsky  
这篇文章主要介绍了详解RecyclerView设置背景图片长宽一样(以GridLayoutManager为例),小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

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

面对的问题:

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

pre

图中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长宽相等喽!

还有一件事

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

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

mid

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

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

detail

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

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

获取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留给你们思考一下 
} 

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

now

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() 
  ,item_list_sys,onItemClickListener_sys,glm_sys)); 

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

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

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

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

相关文章

  • Android判断json格式将错误信息提交给服务器

    Android判断json格式将错误信息提交给服务器

    今天小编就为大家分享一篇关于Android判断json格式将错误信息提交给服务器,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-03-03
  • Android入门教程之ListView的应用示例

    Android入门教程之ListView的应用示例

    这篇文章主要介绍了Android入门教程之ListView的应用,结合简单实例形式分析了Android中listview的简单创建与使用步骤,需要的朋友可以参考下
    2016-10-10
  • Android使用线程更换壁纸

    Android使用线程更换壁纸

    这篇文章主要为大家详细介绍了Android使用线程更换壁纸的方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-11-11
  • Android实现自动变换大小的ViewPager

    Android实现自动变换大小的ViewPager

    ViewPager使用适配器类将数据和view的处理分离,ViewPager的适配器叫PagerAdapter,这是一个抽象类,不能实例化,所以它有两个子类:FragmentPagerAdapter 和 FragmentStatePagerAdapter,这两个都是处理页面为Fragment的情况
    2022-11-11
  • Android编程实现分页加载ListView功能示例

    Android编程实现分页加载ListView功能示例

    这篇文章主要介绍了Android编程实现分页加载ListView功能,结合实例形式分析了listview分页加载的原理、实现技巧与相关注意事项,需要的朋友可以参考下
    2017-02-02
  • Android为按钮控件绑定事件的五种实现方式

    Android为按钮控件绑定事件的五种实现方式

    本篇文章主要是介绍了Android为按钮控件绑定事件的五种实现方式,具有一定的参考价值,感兴趣的小伙伴们可以参考一下。
    2016-11-11
  • 分享10个很棒的学习Android开发的网站

    分享10个很棒的学习Android开发的网站

    我推荐的网站,都是我在学习Android 开发过程中发现的好网站,给初学者一些建议,少走一些弯路
    2015-03-03
  • Android中ADB命令用法大结局

    Android中ADB命令用法大结局

    adb全名android debug bridge 安卓调试桥,下面这篇文章主要给大家介绍了关于Android中ADB命令用法的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考借鉴,下面随着小编来一起学习学习吧
    2018-08-08
  • 利用SurfaceView实现下雨与下雪动画效果详解(Kotlin语法)

    利用SurfaceView实现下雨与下雪动画效果详解(Kotlin语法)

    这篇文章主要给大家介绍了关于利用SurfaceView实现下雨与下雪动画效果的相关资料,需要一些基本的View知识和会一些基础Kotlin语法,文中给出了详细的示例代码供大家参考学习,需要的朋友们下面随着小编来一起学习学习吧。
    2017-09-09
  • Android高级界面组件之拖动条和评星条的功能实现

    Android高级界面组件之拖动条和评星条的功能实现

    这篇文章主要介绍了Android高级界面组件之拖动条和评星条的实现实例,需要的的朋友参考下
    2017-03-03

最新评论