前言
好久没写文章了,赶紧趁着有时间水一篇。今天要分享的是个人在实际开发中积累的那些实用小技巧,以后有新发现也会继续更新下去,方便查看。
正文
1. 简单方法加动效,拒绝生硬
(1) 如何用一行代码加动效:
android:animateLayoutChanges="true"
开启系统默认动画效果,在每次布局发生变化的时候生效,让布局的变化过渡看起来更自然。试一下,有惊喜!
(2) 自定义LayoutAnimation:
//初始化LayoutAnimationController
private LayoutAnimationController getAnimationController() {
final int duration = 180; //动画时长
AnimationSet set = new AnimationSet(true);
//渐变动画
Animation animation = new AlphaAnimation(0.0f, 1.0f);
animation.setDuration(duration);
set.addAnimation(animation);
//平移动画
animation = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 0.0f,Animation.RELATIVE_TO_SELF, 0.0f, Animation.RELATIVE_TO_SELF,-1.0f, Animation.RELATIVE_TO_SELF, 0.0f);
animation.setDuration(duration);
set.addAnimation(animation);
LayoutAnimationController animationController = new LayoutAnimationController(set, 0.5f);
animationController.setOrder(LayoutAnimationController.ORDER_NORMAL);
return animationController;
}
...
//设置LayoutAnimation
View.setLayoutAnimation(getAnimationController();
//显式调用LayoutAnimation
View.startLayoutAnimation();
LayoutAnimation作用于View,可以自定义组合动画,显式调用动画。若对系统动画不满意,可以根据自己的需求写出动画效果。
2. 一行代码加入点击波纹扩散效果
android:foreground="?android:attr/selectableItemBackground"
3. 屏蔽快速点击、重复事件
用于屏蔽快速点击,短时间内的重复多余的事件、双击退出等,避免手动管理。
/**
* 屏蔽快速重复操作事件
*/
private static long lastTime;
private static final int MIN_DELAY_TIME = 1000;
public static boolean isQuickOperating() {
boolean flag = true;
long currentTime = System.currentTimeMillis();
if ((currentTime - lastTime) >= MIN_DELAY_TIME) {
flag = false;
}
lastTime = currentTime;
return flag;
}
4. 判断当前Activity是否已被销毁
通常,在网络请求的回调中会对UI进行更新操作,弹出吐司等。但是在网络状态不佳的情况下,等到异步结果回调时,当前Activity已经被系统销毁,此时进行UI操作就会造成异常,弹出的吐司也让人疑惑。所以,在网络回调中需要先判断一下当前Activity状态,若已销毁,直接return。代码片段如下:
if (this.isFinishing() || this.isDestroyed()) {
return;
}
源码及注释:
/**
* Check to see whether this activity is in the process of finishing,
* either because you called {@link #finish} on it or someone else
* has requested that it finished. This is often used in
* {@link #onPause} to determine whether the activity is simply pausing or
* completely finishing.
*
* @return If the activity is finishing, returns true; else returns false.
*
* @see #finish
*/
public boolean isFinishing() {
return mFinished;
}
/**
* Returns true if the final {@link #onDestroy()} call has been made
* on the Activity, so this instance is now dead.
*/
public boolean isDestroyed() {
return mDestroyed;
}
5. 使用SystemClock.sleep()替代Thread.sleep()
两者使用方法跟作用都类似,但SystemClock.sleep()不会立即抛出InterruptedException,中断事件被推迟到下一个可中断操作中。 可以说非常适合简单的延迟操作了,不用频繁。(说的好像Thread.sleep()方法Try Catch了Exception真的会做什么一样......
6. 线程池的简单使用
原始粗放的形式:
new Thread(new Runnable() {
@Override
public void run() {
// TODO
Log.e("run");
}
}).start();
合理科学的形式:
Runnable command = new Runnable(){
@Override
public void run(){
// TODO
Log.e("run");
}
};
//定长线程池,可控制线程最大并发数,超出的线程会在队列中等待
ExecutorService fixedThreadPool = Executors.newFixedThreadPool(4);
fixedThreadPool.execute(command);
//可缓存线程池,如果线程池长度超出需求,可灵活回收空闲线程,若无线程可回收,则新建
ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
cachedThreadPool.execute(command);
//定长线程池,支持定时及周期性任务执行
ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(4);
// 2000ms后执行
scheduledExecutorService.schedule(command,2000,TimeUnit.MILLISECONDS);
// 延迟10ms后,每隔1000ms执行一次command
scheduledExecutorService.scheduleAtFixedRate(command,10,1000,TimeUnit.MILLISECONDS);
//单线程化线程池,使用唯一工作线程来执行任务,保证所有任务按顺序执行
ExecutorService singleThreadExecutor = Executor.newSingleThreadExecutor;
singleThreadExecutor.execute(command);
7. 自定义BuildConfig字段,方便查看版本信息
buildTypes {
release {
minifyEnabled true
shrinkResources true
signingConfig signingConfigs.release
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
//自定义BuildConfig字段,可通过BuildConfig.buildTime取出,方便查看编译信息
buildConfigField("String", "buildTime", "\"" + new Date().format("yyyy/MM/dd HH:mm:ss") + "\"")
}
}
在应用内埋个彩蛋,结合VERSION_CODE、VERSION_NAME、BUILD_TYPE,就可以方便查看当前APP的版本相关信息了!
8. 模拟点击View
这个功能不多说了,实用!
/**
* 模拟点击,点击该View的xy坐标(5,5)
*
* @param view 模拟点击的View
*/
public static void simulateTouch(View view) {
final long downTime = SystemClock.uptimeMillis();
int[] ints = new int[2];
view.getLocationOnScreen(ints);
view.dispatchTouchEvent(MotionEvent.obtain(downTime, downTime, MotionEvent.ACTION_DOWN,
ints[0] + 5, ints[1] + 5, 0));
view.dispatchTouchEvent(MotionEvent.obtain(downTime, downTime, MotionEvent.ACTION_UP,
ints[0] + 5, ints[1] + 5, 0));
}
9. 使用tools属性工具预览布局
tools属性仅对IDE生效,并不会影响最终打包的应用;
比如TextView需要预览内容,可以使用tools:text属性,如果ImageView默认不显示,而你又要预览,就可以使用tools:visibility属性,避免改动android:visibility过后忘记改回去的尴尬。其他更多属性可以自己去尝试了。
结语
最后,春节马上就要到了,祝大家节日快乐!新的一年,新的进步!
参考资料
- Java(Android)线程池
- 《Android开发艺术探索》