您当前的位置: 首页 >  动画
  • 0浏览

    0关注

    674博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

Android全屏动画

沙漠一只雕得儿得儿 发布时间:2018-11-26 17:06:27 ,浏览量:0

本文主要参考博客,并做了一点修改:

https://blog.csdn.net/z82367825/article/details/51030866

实现一个全屏动画的效果如下:

主界面的activity.java:

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();

        //此方法为微信插件,可以在微信中自动安装应用程序
        //handleApkIntent();

    }

    private void handleApkIntent() {
        Intent intent = getIntent();
        if (intent != null) {
            Uri uri = intent.getData();
            if (uri != null) {
                String path = uri.getPath();
                if (!TextUtils.isEmpty(path)) {
                    tryUpdate(path);
                }
            }
        }
    }

    private void tryUpdate(String path) {
        try {
            Intent intent = new Intent(Intent.ACTION_VIEW);
            intent.setDataAndType(Uri.fromFile(new File(path)), "application/vnd.android.package-archive");
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            startActivity(intent);
        } catch (Exception e) {

        }

    }

    private void initView() {
        findViewById(R.id.button_show).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                FloatViewControl.getInstance().startAnimation(MainActivity.this);
            }
        });
        findViewById(R.id.button_hide).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                FloatViewControl.getInstance().stopAnimation(MainActivity.this);
            }
        });

    }

}

动画实现的主要代码FloatView:

public class FloatView extends FlowBaseView {
    /**
     * 随机数
     */
    private float mMinStartX;
    private float mMidStartX;
    private float mMaxStartX;

    private float mMinStartY;
    private float mMaxStartY;

    private float mMinVx;
    private float mMaxVx;

    private float mMinVy;
    private float mMaxVy;

    private float mMinAccelerator;
    private float mMaxAccelerator;

    /**
     * 当前是否有动画正在展示
     */
    private boolean mIsShowing = false;

    /**
     * 动画产生间隔时间
     */
    private static final long ANIM_INTERVAL = 600;
    /**
     * 动画持续时间
     */
    private static final long ANIM_DURATION = 3;
    /**
     * 动画是否持续
     */
    private boolean mIsContinue = true;
    /**
     * 动画集合
     */
    private List mAnimatorList;
    /**
     * 左边和右边两个动画,目的是增加表情数量,且不重叠
     */
    private static int DO_ANIM_LEFT = 1;
    private static int DO_ANIM_RIGHT = 2;
    /**
     * 动画Handler
     */
    private AnimHandler mHandler;

    /**
     * 动画Handler定义
     */
    private static class AnimHandler extends Handler {
        private WeakReference mWeakReference;

        public AnimHandler(FloatView floatView) {
            mWeakReference = new WeakReference(floatView);
        }

        @Override
        public void handleMessage(Message msg) {
            if (msg.what == ANIM_MSG) {
                mWeakReference.get().createAnim(DO_ANIM_LEFT);
                mWeakReference.get().createAnim(DO_ANIM_RIGHT);
            }
        }
    }

    /**
     * 动画消息标志
     */
    private static final int ANIM_MSG = 0x99;
    /**
     * 间隔时间产生动画
     */
    private Runnable mRunnable = new Runnable() {
        @Override
        public void run() {
            while (mIsContinue) {
                try {
                    Thread.sleep(ANIM_INTERVAL);
                    Message msg = mHandler.obtainMessage();
                    msg.what = ANIM_MSG;
                    mHandler.sendMessage(msg);
                } catch (Exception e) {
                }
            }
        }
    };


    public FloatView(Context context) {
        super(context);
        init(context);
    }

    public FloatView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }

    private void init(Context context) {
        mHandler = new AnimHandler(this);
        mAnimatorList = new ArrayList();

        //X轴弹出表情的起始位置
        mMinStartX = 0;
        mMidStartX = getScreenWidth(context) * 1 / 2;
        mMaxStartX = getScreenWidth(context) * 4 / 5;

        //Y轴弹出表情的起始位置
        mMinStartY = -getScreenHeight(context) * 4 / 5f;
        mMaxStartY = -getScreenHeight(context);

        mMinVx = (getScreenWidth(context) + mMaxStartX) / ANIM_DURATION;
        mMaxVx = getScreenWidth(context) * 1.2f;

        mMinVy = getScreenHeight(context) / 9f;
        mMaxVy = getScreenHeight(context) / 9f;

        mMinAccelerator = getScreenHeight(context) / 2;
        mMaxAccelerator = getScreenHeight(context) / 2;
    }

    /**
     * start
     */
    public void start() {
        new Thread(mRunnable).start();
        mIsShowing = true;
    }

    /**
     * stop
     */
    public void stop() {
        mIsContinue = false;
        mIsShowing = false;
        mHandler.postDelayed(new Runnable() {
            @Override
            public void run() {
                for (ValueAnimator animator : mAnimatorList) {
                    if (animator.isRunning()) {
                        animator.end();
                    }
                }
                mAnimatorList.clear();
            }
        }, 100);
    }

    /**
     * 挂载到某个Activity的最顶层
     *
     * @param activity
     */
    public void attachActivity(Activity activity) {
        ViewParent parent = getParent();
        if (parent != null && parent instanceof ViewGroup) {
            ViewGroup parentView = (ViewGroup) parent;
            parentView.removeView(this);
        }
        FrameLayout decor = (FrameLayout) activity.getWindow().getDecorView();
        FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(
                FrameLayout.LayoutParams.MATCH_PARENT,
                FrameLayout.LayoutParams.MATCH_PARENT);
        decor.addView(this, lp);
        mIsShowing = true;
    }

    /**
     * 从某个Activity移除
     *
     * @param activity
     */
    public void disAttach(Activity activity) {
        FrameLayout decor = (FrameLayout) activity.getWindow().getDecorView();
        decor.removeView(this);
        mIsShowing = false;
    }

    /**
     * 是否正在展示
     *
     * @return
     */
    public boolean isShowing() {
        return mIsShowing;
    }

    /**
     * 创建动画
     */
    private void createAnim(int leftOrRight) {
        //从屏幕上方进入
        float startX = getRandomValue(mMinStartX, mMidStartX);
        switch (leftOrRight) {
            case 1:
                startX = getRandomValue(mMinStartX, mMidStartX);
                break;
            case 2:
                startX = getRandomValue(mMidStartX, mMaxStartX);
                break;
        }
        float startY = getRandomValue(mMinStartY, mMaxStartY);
        float vx = getRandomValue(mMinVx, mMaxVx);
        float vy = getRandomValue(mMinVy, mMaxVy);
        FloatParams params = new FloatParams(startX, startY, vx, vy, getRandomValue(mMinAccelerator, mMaxAccelerator));
        ImageView view = new ImageView(getContext());
        view.setBackgroundDrawable(getResources().getDrawable(R.drawable.heart_eyes));
        startAnim(view, params);
    }

    /**
     * 开始动画
     *
     * @param view
     * @param params
     */
    private void startAnim(final View view, final FloatParams params) {
        LayoutParams lp = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
        addView(view, lp);
        final ValueAnimator valueAnimator = new ValueAnimator();
        mAnimatorList.add(valueAnimator);
        valueAnimator.setDuration(ANIM_DURATION * 1000);
        valueAnimator.setObjectValues(new PointF(params.mStartX, params.mStartY));
        valueAnimator.setInterpolator(new LinearInterpolator());
        valueAnimator.setEvaluator(new TypeEvaluator() {
            @Override
            public PointF evaluate(float fraction, PointF startValue,
                                   PointF endValue) {
                PointF point = new PointF();
                float t = fraction * ANIM_DURATION;
                point.x = params.mStartX;
                point.y = params.mStartY + params.mVy * t + 0.5f * params.mAccelerator * t;
                return point;
            }
        });
        valueAnimator.addListener(new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(Animator animation) {
            }

            @Override
            public void onAnimationRepeat(Animator animation) {
            }

            @Override
            public void onAnimationEnd(Animator animation) {
                if (mIsShowing) {
                    mAnimatorList.remove(valueAnimator);
                    removeView(view);
                }
            }

            @Override
            public void onAnimationCancel(Animator animation) {
            }
        });

        valueAnimator.start();
        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                PointF point = (PointF) animation.getAnimatedValue();
                view.setX(point.x);
                view.setY(-point.y);
            }
        });
    }


    /**
     * Float参数
     */
    private class FloatParams {
        /**
         * 初始的x值
         */
        public float mStartX;
        /**
         * 初始的y值
         */
        public float mStartY;
        /**
         * x轴速度
         */
        public float mVx;
        /**
         * y轴速度
         */
        public float mVy;
        /**
         * 加速度
         */
        public float mAccelerator;

        public FloatParams(float startX, float startY, float vx, float vy,
                           float accelerator) {
            mStartX = startX;
            mStartY = startY;
            mVx = vx;
            mVy = vy;
            mAccelerator = accelerator;
        }
    }

    /**
     * 生成随机数
     */
    private float getRandomValue(float min, float max) {
        return min + (float) (Math.random() * (max - min + 1));
    }
}

基础工具类FlowBaseView.java

public class FlowBaseView extends RelativeLayout {
    
    public static float sDensity = 1.0f;
    public static int sDensityDpi;
    public static float sFontDensity;

    public static float sScaleX = 1f;
    public static float sScaleY = 1f;

    /**
     * 默认设计的大小为720×1080
     */
    public static float sDefaultWidth = 720;
    public static float sDefaultHeight = 1080;
    
    /**
     * 触摸距离
     */
    public static int sTouchSlop;


    public FlowBaseView(Context context) {
        super(context);
        resetDensity(context);
    }
    
    public FlowBaseView(Context context, AttributeSet attrs) {
        super(context, attrs);
        resetDensity(context);
    }
    

    /**
     * dip/dp转像素
     *
     * @param dipValue dip或 dp大小
     * @return 像素值
     */
    public static int dip2px(float dipValue) {
        return (int) (dipValue * sDensity + 0.5f);
    }

    /**
     * 像素转dip/dp
     *
     * @param pxValue 像素大小
     * @return dip值
     */
    public static int px2dip(float pxValue) {
        final float scale = sDensity;
        return (int) (pxValue / scale + 0.5f);
    }

    /**
     * sp转px
     *
     * @param spValue sp大小
     * @return 像素值
     */
    public static int sp2px(float spValue) {
        final float scale = sDensity;
        return (int) (scale * spValue);
    }

    /**
     * px转sp
     *
     * @param pxValue 像素大小
     * @return sp值
     */
    public static int px2sp(float pxValue) {
        final float scale = sDensity;
        return (int) (pxValue / scale);
    }
    
    public synchronized static void resetDensity(Context context) {
        if (context != null && null != context.getResources()) {
            DisplayMetrics metrics = context.getResources().getDisplayMetrics();
            sDensity = metrics.density;
            sFontDensity = metrics.scaledDensity;
            sDensityDpi = metrics.densityDpi;

            sScaleX = getScreenWidth(context)/sDefaultWidth;
            sScaleY = getScreenHeight(context)/sDefaultHeight;
            try {
                final ViewConfiguration configuration = ViewConfiguration.get(context);
                if (null != configuration) {
                    sTouchSlop = configuration.getScaledTouchSlop();
                }
            } catch (Throwable e) {
                e.printStackTrace();
            }
        }
    }
    /**
     * 获取屏幕宽度
     * @param context
     * @return
     */
    public static int getScreenWidth(Context context) {
        DisplayMetrics metrics = context.getResources().getDisplayMetrics();
        return metrics.widthPixels;
    }

    /**
     * 获取屏幕高度
     * @param context
     * @return
     */
    public static int getScreenHeight(Context context) {
        DisplayMetrics metrics = context.getResources().getDisplayMetrics();
        return metrics.heightPixels;
    }
}

获取FloatView的工具类FloatViewControl.java:

public class FloatViewControl {
    private static FloatViewControl sInstance;
    private FloatViewControl(){
        //构造方法私有化
    }
    public static synchronized FloatViewControl getInstance(){
        if(sInstance == null)
            sInstance = new FloatViewControl();
        return sInstance;
    }
    
    
    private FloatView mFloatView;

    public void startAnimation(Activity activity) {
        if (mFloatView == null) {
            mFloatView = new FloatView(activity);
            mFloatView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
            mFloatView.attachActivity(activity);
            mFloatView.start();
        }
    }

    public void stopAnimation(Activity activity) {
        if (mFloatView != null) {
            mFloatView.stop();
            mFloatView.disAttach(activity);
            mFloatView = null;
        }
    }
    
}

主界面activity_main.xml:



    
    

    

本文的可运行项目地址:

https://github.com/buder-cp/base_component_learn/tree/master/FloatView

关注
打赏
1657159701
查看更多评论
立即登录/注册

微信扫码登录

0.0498s