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

使用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的宽度吗?

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

我们在设计布局时为了美观往往需要对控件设置 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留给你们思考一下
} 

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

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()的过程中会再次测量并确定各控件的长宽,覆盖之前的设置。

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

(0)

相关推荐

  • Android使用Recyclerview实现图片水平自动循环滚动效果

    简介: 本篇博客主要介绍的是如何使用RecyclerView实现图片水平方向自动循环(跑马灯效果) 效果图:  思路: 1.准备m张图片 1.使用Recyclerview实现,返回无数个(实际Interge.MAXVALUE)item,第n个item显示第n%m张图片 3.使用recyclerview.scrollBy  每个一段时间水平滚动一段距离 4.通过layoutManager.findFirstVisibleItemPosition()获取当前显示的第一个View是第几个item,上面

  • Android用RecyclerView实现动态添加本地图片

    本文介绍了Android用RecyclerView实现动态添加本地图片,分享给大家,具体如下: 本文所用的多图选择的library来自:https://github.com/lovetuzitong/MultiImageSelector 简单介绍一下用法: 1.跳转到图片选择页面: Intent intent = new Intent(PassengerSetActivity.this, MultiImageSelectorActivity.class); intent.putExtra(Mul

  • Android_RecyclerView实现上下滚动广告条实例(带图片)

    前言 公司新项目首页有个类似京东/淘宝滚动广告条,查了一下大概都是两种实现方式,一是textview,如果只有文字的话是可行的,但我们这个上面还有个小图片,所以pass:二是两个viewGroup,使用动画交替滚动,可以实现,就是显得很麻烦,于是偷懒的我就想着用recyclerView来解决这个小问题! 思路 这个滚动广告条高度通常是固定的,用一个固定高度的viewGroup来包裹一个recyclerView,recylerView的item布局设置一个minHeight为viewGroup的高

  • Android添加图片到ListView或者RecyclerView显示

    先上图 点击+号就去选择图片 实际上这个添加本身就是一个ListView或者 RecyclerView 只是布局有些特殊 item <?xml version="1.0" encoding="utf-8"?> <liu.myrecyleviewchoosephoto.view.SquareRelativeLayout xmlns:android="http://schemas.android.com/apk/res/android&quo

  • Android中RecyclerView 滑动时图片加载的优化

    RecyclerView 滑动时的优化处理,在滑动时停止加载图片,在滑动停止时开始加载图片,这里用了Glide.pause 和Glide.resume.这里为了避免重复设置增加开销,设置了一个标志变量来做判断. mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { @Override public void onScrollStateChanged(RecyclerView recyclerView, in

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

    使用RecyclerView的过程中,由于设置了LayoutManager的关系,控件(的background)往往不能通过指定长宽为match_parent.wrap_content来实现长宽大小相同. 面对的问题: 以指定GridLayout(Horizental)布局为例:控件的实际宽度受制于一行分割为几列,粗略来说 宽度 = RecyclerView宽度 ÷ 列数 由于这个过程是运行时确定的,长度预先并不知道宽度的确切值,这会造成长宽不匹配的现象(如图) 图中logo的宽度严格限制在Gr

  • 详解CSS玩转图片Base64编码

    什么是 base64 编码? 我不是来讲概念的,直接切入正题,图片的 base64 编码就是可以将一副图片数据编码成一串字符串,使用该字符串代替图像地址. 这样做有什么意义呢?我们知道,我们所看到的网页上的每一个图片,都是需要消耗一个 http 请求下载而来的(所有才有了 csssprites 技术的应运而生,但是 csssprites 有自身的局限性,下文会提到). 没错,不管如何,图片的下载始终都要向服务器发出请求,要是图片的下载不用向服务器发出请求,而可以随着 HTML 的下载同时下载到本

  • 详解opencv去除背景算法的方法比较

    目录 背景减除法 (1)BackgroundSubtractorMOG (2)BackgroundSubtractorMOG2 (3)BackgroundSubtractorGMG 帧差法 最近做opencv项目时,使用肤色分割的方法检测目标物体时,背景带来的干扰非常让人头痛.于是先将背景分割出去,将影响降低甚至消除.由于初次接触opencv,叙述不当的地方还请指正. 背景减除法 (以下文字原文来源于https://docs.opencv.org/3.4.7/d8/d38/tutorial_bg

  • css为图片设置背景图片

    CSS的功能是非常强大的,对于元素的表现以及页面的布局,都提供了非常强大的功能,这主要在于我们灵活的运行,在这方面提供了丰富且富含价值的各种教程与信息.对于图片的使用,其实更多的是在内容层.根据WEB标准的思路,表现层的图片,已经都被分离到CSS中去了.只有作为内容的图片才能以IMG标签插入在页面中,这也是一直强调的语义. 为图片设置背景图片,是一个非常搞的实例.这句话或许就感觉有点好玩.我们为以IMG标签引入页面的图片设置背景图片.这样的应用范围或许并不大,但可以锻炼你的思路,让你理解元素在H

  • jpanel设置背景图片的二个小例子

    这个Jpanel可以动态加载一个图片做背景 复制代码 代码如下: import java.awt.Graphics;import java.awt.Image;import java.awt.Toolkit; import javax.swing.JPanel; /** * 一个可以动态加载一个图片做背景的Jpanel */public class ImagePanel extends JPanel{ Image im; //构造函数制定Jpanel的大小 public ImagePanel(I

  • 详解JAVA生成将图片存入数据库的sql语句实现方法

    详解JAVA生成将图片存入数据库的sql语句实现方法 实现代码: 注释很清楚,不在重述~ public class Image2Hex { public static void main(String[] args) { try{ //存放图片的文件夹 File list = new File("d:/qmx"); File[] lists = list.listFiles(); String name; //生成的语句存放文件 PrintWriter pw = new PrintWr

  • Vue项目中设置背景图片方法

    在Vue项目开发中我们经常要向页面中添加背景图片,可是当我们在样式中添加了背景图片后,编译打包后,配置到服务器上时,由于路径解析的问题,图片并不能够正确的显示出来,如下CSS样式: background:url("../../assets/head.jpg"); 这个时候我们就要考虑使用其他的方式了,node中提供了一种比较有效的方式来解决这个问题: 1.在data中定义如下: export default { name: 'productdetailspage', data() {

  • PyQt5 实现给窗口设置背景图片的方法

    QPalette类可以十分简单的达到设置窗口背景图片的目的 def use_palette(self): self.setWindowTitle("设置背景图片") window_pale = QtGui.QPalette() window_pale.setBrush(self.backgroundRole(), QtGui.QBrush(QtGui.QPixmap("F:\A_code\PyQT_Demo\\back_ground.png"))) self.set

  • IntelliJ IDEA 2020如何设置背景图片的方法步骤

    使用idea总看小黑框很难受?眼睛疼?看不清?试试按照你的风格来定制一哈! 1.首先我们选择idea的最左上角的file 2.选择settings 3.找到Appearance&Behavior 4.点击Appearance 5.选择Background Image 之后会就可以开始设置背景图片啦O(∩_∩)O 具体的设置如图所示 图片路径最好不要更改,因为更改后idea就找不到背景图的位置了,需要我们重新设置 设置好了你们都懂点ok就好啦 到此这篇关于IntelliJ IDEA 2020如何设

  • 详解springboot设置默认参数Springboot.setDefaultProperties(map)不生效解决

    我们都知道springboot 由于内置tomcat(中间件)直接用启动类就可以启动了. 而且我们有时想代码给程序设置一些默认参数,所以使用方法Springboot.setDefaultProperties(map) SpringApplication application = new SpringApplication(startClass); // Map<String, Object> params = new HashMap<>(); params.put("l

随机推荐