一、概述
目标效果:
点击应用icon,先显示一段icon动画,动画完成后进入应用
实现原理:
在桌面上创建shortcut,点击shortcut时打开一个透明Activity,根据shortcut位置显示动画效果,在动画结束后进入MainActivity
实现效果:

二、实现过程
1.创建shortcut
创建shortcut需要申请相关权限
<!--创建快捷方式-->
<uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT" />
<!--删除快捷方式-->
<uses-permission android:name="com.android.launcher.permission.UNINSTALL_SHORTCUT" />
创建ShortcutUtils,实现createShortcut和deleteShortcut方法
/**
* 创建快捷方式
* @param context
* @param name 快捷方式名称
* @param iconId 快捷方式图标id
* @param intent 快捷方式action
* @param isDuplicate 是否重复添加
*/
public static void showShortcut(Context context, String name, int iconId, Intent intent, boolean isDuplicate) {
Intent shortcut = new Intent("com.android.launcher.action.INSTALL_SHORTCUT");
shortcut.putExtra("duplicate", isDuplicate);
shortcut.putExtra(Intent.EXTRA_SHORTCUT_NAME, name);
shortcut.putExtra(Intent.EXTRA_SHORTCUT_ICON, BitmapFactory.decodeResource(context.getResources(), iconId));
shortcut.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, Intent.ShortcutIconResource.fromContext(context, iconId));
shortcut.putExtra(Intent.EXTRA_SHORTCUT_INTENT, intent);
context.sendBroadcast(shortcut);
}
/**
* 删除快捷方式
* @param context
* @param name 快捷方式名称
* @param intent 快捷方式action
* @param isDuplicate 是否重复删除
*/
public static void deleteShortcut(Context context, String name, Intent intent, boolean isDuplicate) {
Intent shortcut = new Intent("com.android.launcher.action.UNINSTALL_SHORTCUT");
shortcut.putExtra("duplicate", isDuplicate);
shortcut.putExtra(Intent.EXTRA_SHORTCUT_NAME, name);
shortcut.putExtra(Intent.EXTRA_SHORTCUT_INTENT, intent);
context.sendBroadcast(shortcut);
}
创建快捷方式
Intent intent = new Intent();
intent.setClass(mContext, AnimatedIconActivity.class);
ShortcutUtils.showShortcut(mContext, "click me", R.mipmap.ic_launcher, intent, false);
2.创建动画Activity
点击快捷方式进入AnimatedIconActivity,AnimatedIconActivity需要
a.设置透明主题
<style name="TransparentTheme" parent="AppTheme">
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:windowNoTitle">true</item>
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowAnimationStyle">@null</item>
<item name="android:actionBarStyle">@null</item>
</style>
b.设置打开关闭动画,需要设置为无动画,不然会影响快捷方式的动画
设置打开时无动画
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
overridePendingTransition(0,0);
setContentView(R.layout.activity_shortcut);
//...
}
设置关闭时无动画
@Override
public void finish() {
super.finish();
overridePendingTransition(android.R.anim.fade_in, 0);
}
c.注册Activity
<activity
android:name="com.lynn.cc.animatedicon.activity.AnimatedIconActivity"
android:theme="@style/TransparentTheme">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
</intent-filter>
</activity>
3.实现动画效果
目前点击快捷方式回进入AnimatedIconActivity,现在要在AnimatedIconActivity中显示动画效果了,demo中实现的是加载进度的动画
a.确定快捷方式动画位置,使用Rect rect = getIntent().getSourceBounds()
获取进入时的shortcut位置,获取到的Rect是整个快捷方式点击区域的位置,根据Rect调整动画view的位置
private void resetPosition(View view, Rect rect) {
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) view.getLayoutParams();
params.topMargin = rect.top - UIUtils.getStatusBarHeight(this); //需要减去statusbar高度
params.leftMargin = rect.left;
params.height = rect.bottom - rect.top;
params.width = rect.right - rect.left;
view.setLayoutParams(params);
}
b.显示动画
public void anim(Animator.AnimatorListener listener){
final View view = findViewById(R.id.line);
UIUtils.measureView(this);
final int width = getMeasuredWidth();
final ViewGroup.LayoutParams params = view.getLayoutParams();
ValueAnimator valueAnimator = ValueAnimator.ofInt(0, 100);
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
params.width = (int) (width * animation.getAnimatedFraction());
view.setLayoutParams(params);
}
});
valueAnimator.addListener(listener);
valueAnimator.setDuration(2000);
valueAnimator.start();
}
c.监听动画完成,进入MainActivity
mShortcutView.anim(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
Intent intent = new Intent(AnimatedIconActivity.this, MainActivity.class);
startActivity(intent);
finish();
}
});
目前demo中只进行了简单的动画,如果需要其他自定义动画,可以修改anim()
中的动画实现方式
三、其他
原先想要做成进入应用和退出应用时launcher icon自动进行动画(类似MIUI系统程序效果),但是目前官方并不支持launcher icon的动画。
使用shortcut+透明Activity一定程度上可以实现这个效果,但是局限性较大,需适配不同手机不同系统版本。
更靠谱的方式是自定义Launcher/google支持launcher icon动画/和厂商合作。
网友评论