1.颜色透明度计算html
若是UI在设计图中标注的颜色是这样的
#FF0000(10%不透明度)
,那就须要进行颜色透明度的计算。前端
a.颜色:java
Android中颜色值一般遵循RGB/ARGB标准,使用时一般以“#
”字符开头,以16进制表示。python
好比
#FF99CC00
:FF 是透明度,99是红色值,CC是绿色值,00是蓝色值程序员
b.透明度数据库
好比,透明=0阶,50%透明=127阶,不透明=255阶后端
好比,透明度10%,也就是不透明度90%数组
c.计算步骤bash
假设,UI给出的颜色是#FFFFFF(40%透明度)
,计算步骤以下:并发
#99FFFFFF
为了节约时间,这里直接给出最终计算结果,查表就好啦!
2.SpannableString类
有时候为了美观和醒目,会给一个TextView中显示的文字设置不一样的大小或颜色等样式,笨方法是分别设置多个Textview,聪明方法固然就是用本节介绍的富文本工具SpannableString了!
a.方法
//设置字符串指定区间内的格式
setSpan(Object what, int start, int end, int flags)
复制代码
参数含义:
ForegroundColorSpan
前景色&BackgroundColorSpan
背景色RelativeSizeSpan
相对大小&AbsoluteSizeSpan
绝对大小(单位:像素px)StrikethroughSpan
中划线&UnderlineSpan
下划线SuperscriptSpan
上标&SubscriptSpan
下标StyleSpan
可设置粗体new StyleSpan(Typeface.BOLD)
、斜体new StyleSpan(Typeface.ITALIC)
[
和]
表示包括,符号(
和)
表示不包括,四种属性:
Spanned.SPAN_INCLUSIVE_EXCLUSIVE
: [起始下标,结束下标)Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
:(起始下标,结束下标)Spanned.SPAN_INCLUSIVE_INCLUSIVE
:[起始下标,结束下标]Spanned.SPAN_EXCLUSIVE_INCLUSIVE
: (起始下标,结束下标]更多效果见:SpannableString 你应该知道的那些效果显示
b.示例
还记得以前说的占位符吗?详见周记(二),这里配合占位符给出个小例子,来一招双剑合璧~
//string.xml
<string name="total">共 %1$d 元</string>
//设置金额的颜色为白色,大小为36像素
public void setTotalText(int total) {
SpannableString spannableString = new SpannableString(getResources().getString(R.string.total, total));
ForegroundColorSpan color = new ForegroundColorSpan(Color.parseColor("#FFFFFF"));
spannableString.setSpan(color, 2, 2 + String.valueOf(total).length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
spannableString.setSpan(new AbsoluteSizeSpan(36), 2, 2 + String.valueOf(total).length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
mTotalText.setText(spannableString);
}
复制代码
3.快速切换到主线程更新UI的三种方法
a.Activity.runOnUiThread(Runnable)
把更新UI的代码建立在Runnable中,并传给 Activity.runOnUiThread()
handler.post()
将其放入UI线程的消息队列中new Thread(){
public void run() {
//此时在子线程
((MainActivity) context).runOnUiThread(new Runnable() {
@Override
public void run() {
//此时已经回到主线程,注意要强转到主线程的MainActivity
}
});
};
}.start();
复制代码
b.View.post(Runnable)
mTextView.post(new Runnable() {
@Override
//可快速更新该view
public void run() {
mTextView.setText("xxx");
//也能够更新其余view
mIageView.setBackgroundResource(R.drawable.icon);
}
});
复制代码
还有View.postDelayed(Runnable, long)
,其中long表示延迟的毫秒数,示例以下。
//5秒倒计时跳转到下个页面
index=5;
mTextView.postDelayed(new Runnable() {
@Override
public void run() {
mTextView.setText("" + index);
index--;
if (index == 0) {
Intent intent = new Intent(MainActivity.this, SecondActivity.class);
startActivity(intent);
} else {
mTextView.postDelayed(this, 1000);
}
}
}, 1000);
复制代码
c.Handler.post(Runnable)
&Handler.post(Runnable,long)
有关Handler机制详见要点提炼|开发艺术之消息机制
//假设在子线程,须要获取主线程的Looper和Queue
new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
//此时已经回到主线程
}
});
复制代码
固然还能够用AsyncTask、IntentService、HandlerThread,详见要点提炼|开发艺术之线程,还有许多开源框架,由于这里强调快速,因此其余这些可自行了解~
4.RecycleView的item动画
临上线前一刻UI又想调整动画,由于RecycleView自己有给item设置一些增长和删除的动画效果,若是要自定义就须要重写一些方法了,以前在要点提炼|开发艺术之Animation介绍过Android的三种动画,因此不过是大同小异,这里给出一个自定义的增长动画小例子理解一下。
//设置动画开始前初始状态
@Override
protected void preAnimateAddImpl(RecyclerView.ViewHolder holder) {
//设置锚点,这里以item的中心点为锚点放大
holder.itemView.setPivotX(holder.itemView.getWidth() / 2);
holder.itemView.setPivotY(holder.itemView.getHeight() / 2);
holder.itemView.setAlpha(0);//初始状态为彻底透明
}
//设置动画放大效果,这里的效果是先放大1.2倍再缩小到原样,透明度0到1
@Override
protected void animateAddImpl(final RecyclerView.ViewHolder holder) {
final DefaultAddVpaListener listener = new DefaultAddVpaListener(holder);
ViewCompat.animate(holder.itemView)//为当前item开启一个动画
.scaleX(1.2f)//x方向放大1.2倍
.scaleY(1.2f)//y方向放大1.2倍
.setDuration(300)//动画持续时间300ms
.alpha(1)//动画结束时为彻底不透明
.setInterpolator(mInterpolator)//设置插值器
.setListener(new ViewPropertyAnimatorListener(){//设置动画监听器,包括动画开始、结束和取消
@Override
public void onAnimationStart(View view) {
listener.onAnimationStart(view);
}
@Override
public void onAnimationEnd(View view) {
//上一个动画结束后300ms再缩小item到原大小,持续时间200ms
ViewCompat.animate(holder.itemView)
.scaleX(1f)
.scaleY(1f)
.setDuration(200)//动画持续时间200ms
.setInterpolator(mInterpolator)
.setListener(new ViewPropertyAnimatorListener(){
@Override
public void onAnimationStart(View view) {
listener.onAnimationStart(view);
}
@Override
public void onAnimationEnd(View view) {
listener.onAnimationEnd(view);
}
@Override
public void onAnimationCancel(View view) {
listener.onAnimationCancel(view);
}
})
.setStartDelay(300)//延迟300ms启动动画
.start();
}
@Override
public void onAnimationCancel(View view) {
listener.onAnimationCancel(view);
}
})
.start();//启动动画
}
复制代码
这里只给了动画实现,至于怎么和Adapter配合到item上的全过程参考文章 RecyclerView的动画实现(移除、添加、改变、移动)和自定义动画的实现。
5.使用Rxjava实现点击防抖动
以前测试提了个bug,是由快速点击Button致使的,听闻个人表情以下,为了周全考虑到用户各类习惯这操做也是很疯狂了。解决思路是给按钮点击添加防抖处理,在必定时间内不管点击多少次都只调用一次事件,这里用了Rxjava去实现,文章贴下Android RxJava 实战系列:功能防抖。
传统办法是进行先后两次点击时间间隔判断,若是大于设定的时间间隔再执行点击事件,代码以下:
public abstract class OnMultiClickListener implements View.OnClickListener {
public static final int MIN_CLICK_DELAY_TIME = 1000;
private long lastClickTime = 0;
@Override
public void onClick(View v) {
long currentTime = Calendar.getInstance().getTimeInMillis();
if (currentTime - lastClickTime > MIN_CLICK_DELAY_TIME) {
lastClickTime = currentTime;
onMultiClick(v);
}
}
public abstract void onMultiClick(View v);//具体点击事件
}
复制代码
6.Java基础之异常机制
当一个程序出现错误时,多是如下三种错误:
- 语法错误:如缺乏必要的标点符号、关键字输入错误、数据类型不匹配等,在编译器对程序进行编译的过程当中,会把检测到的语法错误以提示的方式列举出来,故又称为编译错误。
- 运行时错误:如空指针异常,数组越界,除数为零、数据库链接失败等,迫使程序终止,有特定的发生条件。
- 逻辑错误:在语法上是有效的,可是在逻辑上是错误的,此类问题很差调试。
这里说的Java异常处理机制主要是指处理运行时错误。
a.Throwable继承层次结构,可见分红两大类Error和Exception。
Error
(错误):指程序没法恢复的异常状况,表示运行应用程序中较严重的问题。
Virtual MachineError
(Java虚拟机运行错误)、NoClassDefFoundError
(类定义错误)。Exception
(异常):指程序有可能恢复的异常状况,表示程序自己能够处理的异常。又分两大类:
RuntimeException
(运行时异常):由程序自身的问题致使产生的异常。
NullPointerException
(空指针异常)、IndexOutOfBoundsException
(下标越界异常)。FileNotFoundException
(文件不存在异常)。附:常见的异常及其含义如图
b.异常处理机制
(1)捕捉异常:由系统自动抛出异常
try
捕获异常:用于监控,若发生异常,会抛出异常类所产生的对象并马上结束执行,并转向异常处理catch块。catch
处理异常:若抛出的异常对象属于catch内所定义的异常类,则进入catch中的对应代码段继续运行程序,反之进入finally块。经常使用方法:
e.getMessage()
:返回异常对象的一个简短描述e.toString()
:获取异常对象的详细信息e.printStackTrace()
:在控制台上打印异常对象和它的追踪信息finally
最终处理:不管是否捕获或处理异常,finally块里的语句都会被执行。在如下4种特殊状况下,finally块才不会被执行:
System.exit()
退出程序try {
// 可能会发生异常的程序代码
} catch (异常类1 异常变量) {
// 捕获并处理try抛出的异常类型Type1
} catch (异常类2 异常变量) {
// 捕获并处理try抛出的异常类型Type2
} finally {
// 不管是否发生异常,都将执行的语句块
}
复制代码
注意:
- 一个try、catch、finally之间不能插入其它代码
- catch可有多个,try和finally只能有一个
- try后面必须至少跟着catch和finally其中的一个
(2)抛出异常:在方法中将异常对象显性地抛出,以后异常会沿着调用层次向上抛出,交由调用它的方法来处理。
throws
:声明抛出的异常,位置在方法名后、异常类型前throw
:抛出异常,通常在方法体内部(3)自定义异常:继承Execption类或其子类,实现步骤以下:
getMessage()
throws
声明该方法可能抛出的异常throw
将异常抛出//1.自定义的异常类
class MyException extends Exception {
String message;
public MyException(String ErrorMessagr) {
super(ErrorMessagr) ;
}
public String getMessage() {
return message;
}
}
public class Demo {
public static void main(String[] args) {
//4.调用方法时捕获和处理
try {
test();
} catch (MyException e) {
System.out.println(e.getMessage());
e.printStackTrace();
}
}
//2.在方法头声明可能出现的异常
public static void test() throws MyException{
try {
int i = 10/0;
System.out.println("i="+i);
} catch (ArithmeticException e) {
//3.在适当状况下抛出异常
throw new MyException("This is MyException");
}
}
}
复制代码
推荐阅读:java程序错误类型及异常处理
7.一些小感悟
转瞬一周又过去了,项目终于发版上线了,新的一期需求评审也如期而至,感受一切都在渐入佳境,收获也沉甸甸的,愈加以为不虚此行。(这是感悟略长的节奏啊...)
上周有幸遇上同事们每半年的绩效考核,因而旁听了整个项目前端组的述职大会,几个小时下来,感悟颇深。想起大一曾修过一门有关职业规划的课程,让我意识到大学千万不能荒度,要有计划地准备和积累求职的筹码和资本,不要最后才发现简历一无全部,这门课深入的影响了我整个大学,我想大概此次述职大会也或多或少地影响我将来的职业生涯吧。
首先是述职的内容,分红两个部分,第一部分是对上期工做的回顾,包括作了什么、有什么价值,遇到并解决的问题、影响取得业绩的障碍、上期作的好的地方,作的很差的地方以及我的成长收获;第二部分是下期工做计划,包括工做内容、我的成长计划以及给团队建议(如业务、技术、文化等)。
听罢不由感慨身边的牛人真的不少,有的人能保质保量的完成业务需求,而且经过必定的关键指标和数据来衡量和评价,好比线上报错统计、各类异常现象数目统计、用户访问量等等;有的人有良好的开发流程规范,有整理和产出各种研发文档的好习惯;有的人注重代码质量,不断重构代码、优化性能、奉行『异常的考虑要大于功能的实现』;有的人在工做之余仍不忘学习,好比深刻理解公司框架源码、维护我的wiki并发表高质量的技术文章、积极主动进行组内知识分享、加入公司读书协会并坚持打卡取得多本赠书奖励......
其中一个小姐姐的有个细节显得不同凡响,就是她提早就准备好了答辩稿并使用PPT的演讲者模式,使得整个答辩很流畅自如。可能由于本身自己商科出身也有些答辩经历,自认为答辩前要准备好的不只是一个质量高的PPT,还须要有答辩稿配合、并进行必定的语速和仪态练习,虽然无关于开发技术,但真的会增添很多亮色,给人很好的听觉体验。
这阵子也在陆陆续续进行code review,由于有个梳理整个项目业务逻辑的任务,因此很认真的边听边想边作记录,全程只有一个感觉--『不明觉厉』,你们都全神贯注的检查每一个实现,不放过任何一个可能存在的异常,或者提出更好的解决思路。虽然指出的不少关键点我都有所闻,但因为缺乏项目实践,没有学以至用,因此很难一会儿联系到某个场景,愈加感受本身任重而道远。
最后不得再也不次夸奖一番我风格迥异的同事们,真的是个很可爱的团队呢。严肃内敛、务实又靠谱和平易近人、认真又负责的两位宝爸--组长和导师,工做严谨爱钻研、生活却不失浪漫的的话题达人超哥,热爱运动、喜欢分水果、开朗风趣、才艺俱佳的颜值担当田丰大哥哥,还有稳重憨厚、技术全能、个人学习榜样杨宇大哥哥,他就是那种天天早上背单词、早来一小时看英文技术书、GitHub各类自写的千stars的开源框架、只看美剧来学英文、先后端通吃、脑瓜里各类知识百宝库、倒是和我年龄最近的那我的。有这些的小伙伴,实习都是件很开心的事啊!