Android快捷方式动画

2018-02-26  本文已影响0人  Lynn_R01612x2

一、概述

目标效果

点击应用icon,先显示一段icon动画,动画完成后进入应用

实现原理

在桌面上创建shortcut,点击shortcut时打开一个透明Activity,根据shortcut位置显示动画效果,在动画结束后进入MainActivity

实现效果

shortcut animation.gif

二、实现过程

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动画/和厂商合作。

四、项目地址

https://github.com/Lynn4I/AnimatedIcon

上一篇 下一篇

猜你喜欢

热点阅读