版权声明:本文为xing_star原创文章,转载请注明出处!

本文同步自http://javaexception.com/archives/181

最近在做一个需求,是对im聊天消息设置气泡背景,之前呢,设计师没有特别遵循一定的设计规范,导致,气泡背景有的是.9的图片,有的是自己用xml画出来的背景。这样在给聊天消息设置背景的时候出现了不少的问题。

问题场景回溯:

设置背景,我们常用的Api是setBackgroundResource。最开始考虑的比较简单,每条消息都只用setBackgroundResource

接着就碰到了第一个问题,有的消息用的是.9图,有的是xml,整体的效果看起来不是很协调,也就是消息的间隔有大有小,看起来特别丑。

这里我们想到了一个办法,我们需要让不同的气泡上的文本内容看起来间隔差不多,考虑的是设置padding,而不是使用background里面的间隔。对于每一条消息,根据它是什么样的气泡,决定设置padding值的参数。

大致的代码是

setBgContainerPadding(bgContainer, SystemUtils.dip2px(10), SystemUtils.dip2px(4), SystemUtils.dip2px(18), SystemUtils.dip2px(4));
bgContainer.setBackgroundResource(R.drawable.xxx);//设置背景

然后我就掉入了第二个坑中,发现设置了padding后,效果没变化,一时之间找不到原因,很是恼火。只好先放弃这块工作,去忙其他的了,不知道过了多久,灵感来了,想到了调整padding和background的先后顺序。

bgContainer.setBackgroundResource(R.drawable.xxx);//设置背景
setBgContainerPadding(bgContainer, SystemUtils.dip2px(10), SystemUtils.dip2px(4), SystemUtils.dip2px(18), SystemUtils.dip2px(4));

一定得是先设置背景,在设置padding值。不能是先设置padding,再设置背景。https://www.jianshu.com/p/4432b19ec6cd 这篇文章深入分析了下原因,对于这块推荐看这篇文章。

到这里大致的效果就比较接近了,但是还是有些item的气泡背景包裹的内容间隔有问题,感觉是view的复用机制(RecyclerView,ListView的item)在作怪。(此外设置padding值的时候,不要使用view的getPaddingLeft()这样的方法,全部给定具体的数值,从源头上避免复用机制)

于是再次修改代码,代码覆盖各种case,相当于每个itemView都手动设置一遍,padding,气泡背景这块不使用view的复用。

完整的处理气泡的代码如下:

private void setBackground(View bgContainer, int position) {
Conversation conversation = conversationList.get(position);
if (position == 0) {
if (conversation.getIsSend() == Conversation.SEND_RECEIVE_TYPE_SEND) {
bgContainer.setBackgroundResource(R.drawable.balloon_outgoing_normal);//marginLeft marginRight 10dp
setBgContainerPadding(bgContainer, SystemUtils.dip2px(10), SystemUtils.dip2px(4), SystemUtils.dip2px(18), SystemUtils.dip2px(4));
} else {
bgContainer.setBackgroundResource(R.drawable.balloon_incoming_normal);
setBgContainerPadding(bgContainer, SystemUtils.dip2px(18), SystemUtils.dip2px(4), SystemUtils.dip2px(10), SystemUtils.dip2px(4));
}
setBgContainerMargin(bgContainer, SystemUtils.dip2px(10), 0, SystemUtils.dip2px(10), 0);
}
else if (isDifferentTypePre(position)) {
if (conversation.getIsSend() == Conversation.SEND_RECEIVE_TYPE_SEND) {
bgContainer.setBackgroundResource(R.drawable.balloon_outgoing_normal);
setBgContainerPadding(bgContainer, SystemUtils.dip2px(10), SystemUtils.dip2px(4), SystemUtils.dip2px(18), SystemUtils.dip2px(4));
} else {
bgContainer.setBackgroundResource(R.drawable.balloon_incoming_normal);
setBgContainerPadding(bgContainer, SystemUtils.dip2px(18), SystemUtils.dip2px(4), SystemUtils.dip2px(10), SystemUtils.dip2px(4));
}
setBgContainerMargin(bgContainer, SystemUtils.dip2px(10), 0, SystemUtils.dip2px(10), 0);
} else {
lineHeader.setVisibility(View.GONE);
if (conversation.getIsSend() == Conversation.SEND_RECEIVE_TYPE_SEND) {
bgContainer.setBackgroundResource(R.drawable.green_msg);
setBgContainerMargin(bgContainer, 0, SystemUtils.dip2px(0.5f), SystemUtils.dip2px(17), SystemUtils.dip2px(0.5f));
} else {
bgContainer.setBackgroundResource(R.drawable.white_msg);
setBgContainerMargin(bgContainer, SystemUtils.dip2px(17), SystemUtils.dip2px(0.5f), 0, SystemUtils.dip2px(0.5f));
}
setBgContainerPadding(bgContainer, SystemUtils.dip2px(10), SystemUtils.dip2px(4), SystemUtils.dip2px(10), SystemUtils.dip2px(4));
}
}

这块的代码,也是调整了好久才完善好,我觉得这块还是很值得总结的。希望对大家有用。

总结:

做这块的工作,碰到了2个问题,设置background跟padding的先后顺序,一定得是先设置background再设置padding;第二个是要考虑到view的复用,但是对于气泡,特定的背景padding值而言,要用代码的方式禁用掉view的复用效果。最终的消息聊天气泡效果很让我满意,整个页面的布局效果也很好,仿的特别成功。

参考资料:

https://www.jianshu.com/p/4432b19ec6cd

Android View的background和padding的更多相关文章

  1. Android什么时候进行View中Background的加载

    对大多数Android的开发者来说,最经常的操作莫过于对界面进行布局,View中背景图片的加载是最经常做的.但是我们很少关注这个过程,这篇文章主要解析view中背景图片加载的流程.了解view中背景图 ...

  2. [Android疑难杂症]动态改变Background后Padding无效的问题

    前言 在Layout中指定好background和padding以后,程序里面动态修改background之后padding就失效了,貌似是一个BUG,这里找到了一篇英文文章,简单翻译分享一下. 声明 ...

  3. Android View的绘制流程

    写得太好了,本来还想自己写的,奈何肚里墨水有限,直接转吧.正所谓前人种树,后人乘凉.. View的绘制和事件处理是两个重要的主题,上一篇<图解 Android事件分发机制>已经把事件的分发 ...

  4. Android View各种尺寸位置相关的方法探究

    Android View各种尺寸位置相关的方法探究 本来想做一个View间的碰撞检测之类的. 动手做了才发现不是想象的那么简单. 首先,写好了碰撞检测的工具类如下: package com.mengd ...

  5. 简单研究Android View绘制一 测量过程

    2015-07-27 16:52:58 一.如何通过继承ViewGroup来实现自定义View?首先得搞清楚Android时如何绘制View的,参考Android官方文档:How Android Dr ...

  6. android View层的绘制流程

    还记得前面<Android应用setContentView与LayoutInflater加载解析机制源码分析>这篇文章吗?我们有分析到Activity中界面加载显示的基本流程原理,记不记得 ...

  7. Android View体系(八)从源代码解析View的layout和draw流程

    相关文章 Android View体系(一)视图坐标系 Android View体系(二)实现View滑动的六种方法 Android View体系(三)属性动画 Android View体系(四)从源 ...

  8. android.view.View

    * This class represents the basic building block for user interface components. A View * occupies a ...

  9. Android View系统解析(下)

    转载请注明出处:http://blog.csdn.net/singwhatiwanna/article/details/38426471(来自singwhatiwanna的csdn博客) Androi ...

随机推荐

  1. 牛客竞赛-Who killed Cock Robin

    Who killed Cock Robin? I, said the Sparrow, With my bow and arrow,I killed Cock Robin. Who saw him d ...

  2. 去除npm run dev日志warn记录

    目录 一 babel的一些eslint方法废除了 问题 解决方案 相关文档 二 webpack的loaderUtils.parseQuery()被废弃了 问题 解决方案 相关文档 三 postcss相 ...

  3. Mac 中环境变量的配置

    1. 基本了解 1.1. 查看当前path 在讲解Mac环境变量配置之前,大家可以打开dos框,输入 echo $PATH 查看当前的path. 本机结果: /usr/local/bin:/usr/l ...

  4. CodeForces1006C-Three Parts of the Array

    C. Three Parts of the Array time limit per test 1 second memory limit per test 256 megabytes input s ...

  5. 了解一下Mysql分布式事务及优缺点、使用案例(php+mysql)

    在开发中,为了降低单点压力,通常会根据业务情况进行分表分库,将表分布在不同的库中(库可能分布在不同的机器上),但是一个业务场景可能会同时处理两个表的操作.在这种场景下,事务的提交会变得相对复杂,因为多 ...

  6. Oracle:row_number()、rank()、dense_rank()

    语法:ROW_NUMBER()  OVER(): row_number的用途非常广泛,排序最好用它,它会为查询出来的每一行记录生成一个序号,依次排序且不会重复,注意使用row_number函数时必须要 ...

  7. 基于iCamera测试mt9m034 1280X960 高动态相机模块小结

    基于iCamera测试mt9m034 高动态相机模块小结 首先看看此模块的特性 mt9m034 高动态 CMOS模块 1280*960像素 5.48 V/lux-sec >115db 摄像头模块 ...

  8. 打开TXT文件并显示

    <!DOCTYPE html> <html> <head> <title></title> <script> function ...

  9. Day 04 数据类型基础

    目录 什么是数据类型 为什么对数据分类 整型和浮点型统称为数字类型 整型(int) 作用 定义 使用方法 浮点型(float) 作用 定义 使用方法 强制类型转换 什么是字符串 作用 定义 使用方法 ...

  10. Python3 猜年龄小游戏进阶之函数处理

    在猜年龄的基础上编写登录.注册方法,并且把猜年龄游戏分函数处理 登录函数 注册函数 猜年龄函数 选择奖品函数 # 注册 def register(): '''注册''' count = 0 while ...