版权声明:本文为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. iOS-使用Xcode自带单元测试UnitTest

    ![Uploading QQ20160129-3_262826.png . . .]####什么是单元测试?一听到单元测试这个词感觉很高端,其实单元测试就是为你的方法多专门写一个测试函数.以保证你的方 ...

  2. SpringMVC实现上传下载功能

    配置资源(jar包) 将前端页面整理好: 写核心的几个配置文件(applicationContext+wed.xml+jdbc.properties+log4j+springMVC.xml) 都是在s ...

  3. 2017 ACM/ICPC 沈阳 G题 Infinite Fraction Path

    The ant Welly now dedicates himself to urban infrastructure. He came to the kingdom of numbers and s ...

  4. Swift Playground词法分析器DEMO

    正在看极客时间宫文学老师的编译原理之美,用swift playground写了一个第二课"int age >= 45"的词法解析DEMO 为了保持原课程代码,DEMO用了顺序 ...

  5. 【搞定Jvm面试】 Java 内存区域揭秘附常见面试题解析

    本文已经收录自笔者开源的 JavaGuide: https://github.com/Snailclimb ([Java学习+面试指南] 一份涵盖大部分Java程序员所需要掌握的核心知识)如果觉得不错 ...

  6. zabbix系列-Grafana4.6.3+Zabbix 的安装部署

    zabbix系列(五) Grafana4.6.3+Zabbix 的安装部署 伟创享 2019-07-31 11:27:18 使用了一段时间Grafana,感觉还挺好用的.部分效果图如下: ​ zabb ...

  7. 一些demo

    绑定端口demo: #include <stdio.h> #include <sys/socket.h> #include <stdlib.h> #include ...

  8. 【CSS】343- CSS Grid 网格布局入门

    CSS Grid(网格) 布局使我们能够比以往任何时候都可以更灵活构建和控制自定义网格.Grid(网格) 布局使我们能够将网页分成具有简单属性的行和列. 它还能使我们在不改变任何HTML的情况下,使用 ...

  9. 日地拉格朗日L2点轨道的卫星运行

    看了嫦娥四号通信的中继卫星,不明白是怎么运行的,下面的演示解除了我的疑问. https://lt.cjdby.net/thread-2479933-1-2.html

  10. Vue大纲

    Vue框架 Vue ---- vue的基本使用 文本/事件/属性指令 补充: js面向对象 js函数 Vue ---- 表单指令 条件指令 循环指令 分隔符 过滤器 计算属性 监听属性 Vue --- ...