天天看點

Android平台分享彈出動畫

沒事的時候就喜歡刷刷今日頭條,(不得不吐槽一下,現在的頭條廣告太他媽多了),以前也沒有太在意,這兩天看到個有意思的文章想分享盆友圈時候,突然發現,這個分享平台彈出的動畫挺有趣的,感覺很好玩,但是覺得好像在android端的app上就沒見過,我趕緊把android測試機拿出來試了試,果然:

  • 這是ios版的分享動畫:
Android平台分享彈出動畫
  • 這是android版的分享動畫:
Android平台分享彈出動畫

這我就不開心了,ios搞得,難道android就搞不得.廢話不多說,開搞…

  • 首先,用屬性動畫應該可以搞出來
  • 其次,需要給動畫加個內插補點器interpolator來實作效果
  • 然後,界面優化适配等(沒弄)

interpolator不了解的可以看這個部落格,講的挺細的android之interpolator的用法詳解

這是自定義view的代碼,參考了github上一個項目,但位址忘了,找到了再貼上:

public class ShareView2 extends View {
    private static final float RADIUS = f;//上排距離
    private static final float RADIUS2 = f;//下排距離
    private static final float HEIGHT_VIEW = f;
    private static float DISTANCEPOINT = ;
    private OnDownActionListener2 mDown = null;
    private Point currentPoint1;
    private Point currentPoint2;
    private Point currentPoint3;
    private Point currentPoint4;
    private Point currentPoint5;
    private Point currentPoint6;
    private Point currentPoint7;
    private float startX;
    private float startY;
    private float startY2;
    private float width;
    private float height;
    private Paint mPaint;
    private Bitmap bitmap1;
    private Bitmap bitmap2;
    private Bitmap bitmap3;
    private Bitmap bitmap4;
    private Bitmap bitmap5;
    private Bitmap bitmap6;
    private Bitmap bitmap7;

    public ShareView2(Context context, AttributeSet attrs) {
        super(context, attrs);
        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mPaint.setColor(Color.BLUE);
        // 初始化
        WindowManager wm = (WindowManager) getContext().getSystemService(
                Context.WINDOW_SERVICE);
        height = wm.getDefaultDisplay().getHeight();
        width = wm.getDefaultDisplay().getWidth();

        Log.e("TAG---", "height----" + height);
        Log.e("TAG---", "width----" + width);

        DISTANCEPOINT = width / ;

        bitmap1 = BitmapFactory.decodeResource(getResources(), R.drawable.umeng_socialize_wechat);
        bitmap2 = BitmapFactory.decodeResource(getResources(), R.drawable.umeng_socialize_qq_on);
        bitmap3 = BitmapFactory
                .decodeResource(getResources(), R.drawable.umeng_socialize_wxcircle);
        bitmap4 = BitmapFactory.decodeResource(getResources(), R.drawable.umeng_socialize_qzone_on);
        bitmap5 = BitmapFactory.decodeResource(getResources(), R.drawable.umeng_socialize_sina_on);
        bitmap6 = BitmapFactory.decodeResource(getResources(), R.drawable.umeng_socialize_sms_on);
        bitmap7 = BitmapFactory.decodeResource(getResources(), R.drawable.umeng_socialize_gmail_on);

        System.out.println("bitmap_width  " + bitmap1.getWidth());

        startX = (float) (DISTANCEPOINT - bitmap1.getWidth() / );
        startY = height - RADIUS;
        startY2 = height - RADIUS2;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        if (currentPoint1 == null) {
            currentPoint1 = new Point(startX, startY);
            currentPoint2 = new Point(startX + DISTANCEPOINT, startY);
            currentPoint3 = new Point(startX +  * DISTANCEPOINT, startY);
            currentPoint4 = new Point(startX +  * DISTANCEPOINT, startY);
            currentPoint5 = new Point(startX, startY2);
            currentPoint6 = new Point(startX + DISTANCEPOINT, startY2);
            currentPoint7 = new Point(startX +  * DISTANCEPOINT, startY2);
            canvas.drawBitmap(bitmap1, currentPoint1.getX(),
                    currentPoint1.getY(), mPaint);
            canvas.drawBitmap(bitmap2, currentPoint2.getX(),
                    currentPoint2.getY(), mPaint);
            canvas.drawBitmap(bitmap3, currentPoint3.getX(),
                    currentPoint3.getY(), mPaint);
            canvas.drawBitmap(bitmap4, currentPoint4.getX(),
                    currentPoint4.getY(), mPaint);
            canvas.drawBitmap(bitmap5, currentPoint5.getX(),
                    currentPoint5.getY(), mPaint);
            canvas.drawBitmap(bitmap6, currentPoint6.getX(),
                    currentPoint6.getY(), mPaint);
            canvas.drawBitmap(bitmap7, currentPoint7.getX(),
                    currentPoint7.getY(), mPaint);
            startAnimation(, startX, startY);
            startAnimation(, startX + DISTANCEPOINT, startY);
            startAnimation(, startX +  * DISTANCEPOINT, startY);
            startAnimation(, startX +  * DISTANCEPOINT, startY);
            startAnimation(, startX, startY2);
            startAnimation(, startX + DISTANCEPOINT, startY2);
            startAnimation(, startX +  * DISTANCEPOINT, startY2);
        } else {
            canvas.drawBitmap(bitmap1, currentPoint1.getX(),
                    currentPoint1.getY(), mPaint);
            canvas.drawBitmap(bitmap2, currentPoint2.getX(),
                    currentPoint2.getY(), mPaint);
            canvas.drawBitmap(bitmap3, currentPoint3.getX(),
                    currentPoint3.getY(), mPaint);
            canvas.drawBitmap(bitmap4, currentPoint4.getX(),
                    currentPoint4.getY(), mPaint);
            canvas.drawBitmap(bitmap5, currentPoint5.getX(),
                    currentPoint5.getY(), mPaint);
            canvas.drawBitmap(bitmap6, currentPoint6.getX(),
                    currentPoint6.getY(), mPaint);
            canvas.drawBitmap(bitmap7, currentPoint7.getX(),
                    currentPoint7.getY(), mPaint);
        }
    }

    @SuppressLint("NewApi")
    private void startAnimation(int flag, float startX, float startY) {
        Point startPoint = new Point(startX, startY);
        Point endPoint = new Point(startX, startY - HEIGHT_VIEW);
        ValueAnimator anim = ValueAnimator.ofObject(new PointEvaluator(),
                startPoint, endPoint);

        switch (flag) {
            case :
                anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                    @SuppressLint("NewApi")
                    @Override
                    public void onAnimationUpdate(ValueAnimator animation) {
                        currentPoint1 = (Point) animation.getAnimatedValue();
                        invalidate();
                    }
                });
                anim.setInterpolator(new AnticipateOvershootInterpolator());
                anim.setDuration();
                anim.start();
                break;
            case :
                anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                    @SuppressLint("NewApi")
                    @Override
                    public void onAnimationUpdate(ValueAnimator animation) {
                        currentPoint2 = (Point) animation.getAnimatedValue();
                        invalidate();
                    }
                });
                anim.setInterpolator(new AnticipateOvershootInterpolator());
                anim.setDuration();
                anim.setStartDelay();
                anim.start();
                break;
            case :
                anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                    @SuppressLint("NewApi")
                    @Override
                    public void onAnimationUpdate(ValueAnimator animation) {
                        currentPoint3 = (Point) animation.getAnimatedValue();
                        invalidate();
                    }
                });
                anim.setInterpolator(new AnticipateOvershootInterpolator());
                anim.setDuration();
                anim.setStartDelay();
                anim.start();
                break;
            case :
                anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                    @SuppressLint("NewApi")
                    @Override
                    public void onAnimationUpdate(ValueAnimator animation) {
                        currentPoint4 = (Point) animation.getAnimatedValue();
                        invalidate();
                    }
                });
                anim.setInterpolator(new AnticipateOvershootInterpolator());
                anim.setDuration();
                anim.setStartDelay();
                anim.start();
                break;
            case :
                anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                    @SuppressLint("NewApi")
                    @Override
                    public void onAnimationUpdate(ValueAnimator animation) {
                        currentPoint5 = (Point) animation.getAnimatedValue();
                        invalidate();
                    }
                });
                anim.setInterpolator(new AnticipateOvershootInterpolator());
                anim.setDuration();
                anim.setStartDelay();
                anim.start();
                break;
            case :
                anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                    @SuppressLint("NewApi")
                    @Override
                    public void onAnimationUpdate(ValueAnimator animation) {
                        currentPoint6 = (Point) animation.getAnimatedValue();
                        invalidate();
                    }
                });
                anim.setInterpolator(new AnticipateOvershootInterpolator());
                anim.setDuration();
                anim.setStartDelay();
                anim.start();
                break;
            case :
                anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                    @SuppressLint("NewApi")
                    @Override
                    public void onAnimationUpdate(ValueAnimator animation) {
                        currentPoint7 = (Point) animation.getAnimatedValue();
                        invalidate();
                    }
                });
                anim.setInterpolator(new AnticipateOvershootInterpolator());
                anim.setDuration();
                anim.setStartDelay();
                anim.start();
                break;

            default:
                break;
        }
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        setMeasuredDimension((int) width, (int) height);
    }

    @SuppressLint("ClickableViewAccessibility")
    @Override
    public boolean onTouchEvent(MotionEvent event) {

        float x = event.getX();
        float y = event.getY();
        if (event.getAction() == MotionEvent.ACTION_UP) {
            System.out.println("up");
        } else if (event.getAction() == MotionEvent.ACTION_DOWN) {

            int result = ;
            result = isClick(x, y);

            switch (result) {
                case :
                    mDown.OnDown();
                    return true;
                case :
                    mDown.OnDown();
                    return true;
                case :
                    mDown.OnDown();
                    return true;
                case :
                    mDown.OnDown();
                    return true;
                case :
                    mDown.OnDown();
                    return true;
                case :
                    mDown.OnDown();
                    return true;
                case :
                    mDown.OnDown();
                    return true;

                default:
                    break;
            }
        }
        mDown.OnDown();
        return super.onTouchEvent(event);
    }

    private int isClick(float x, float y) {

        if (y > startY - HEIGHT_VIEW
                && y < startY - HEIGHT_VIEW + bitmap1.getHeight() && x > startX
                && x < startX + bitmap1.getWidth()) {
            return ;
        }
        if (y > startY - HEIGHT_VIEW
                && y < startY - HEIGHT_VIEW + bitmap1.getHeight()
                && x > startX + DISTANCEPOINT
                && x < startX + DISTANCEPOINT + bitmap1.getWidth()) {
            return ;
        }
        if (y > startY - HEIGHT_VIEW
                && y < startY - HEIGHT_VIEW + bitmap1.getHeight()
                && x > startX +  * DISTANCEPOINT
                && x < startX +  * DISTANCEPOINT + bitmap1.getWidth()) {
            return ;
        }
        if (y > startY - HEIGHT_VIEW
                && y < startY - HEIGHT_VIEW + bitmap1.getHeight()
                && x > startX +  * DISTANCEPOINT
                && x < startX +  * DISTANCEPOINT + bitmap1.getWidth()) {
            return ;
        }
        if (y > startY2 - HEIGHT_VIEW
                && y < startY2 - HEIGHT_VIEW + bitmap1.getHeight()
                && x > startX
                && x < startX + bitmap1.getWidth()) {
            return ;
        }
        if (y > startY2 - HEIGHT_VIEW
                && y < startY2 - HEIGHT_VIEW + bitmap1.getHeight()
                && x > startX + DISTANCEPOINT
                && x < startX + DISTANCEPOINT + bitmap1.getWidth()) {
            return ;
        }
        if (y > startY2 - HEIGHT_VIEW
                && y < startY2 - HEIGHT_VIEW + bitmap1.getHeight()
                && x > startX +  * DISTANCEPOINT
                && x < startX +  * DISTANCEPOINT + bitmap1.getWidth()) {
            return ;
        }
        return ;
    }

    // 為每個接口設定監聽器
    public void setOnDownActionListener(OnDownActionListener2 down) {
        mDown = down;
    }

    public interface OnDownActionListener2 {
        public void OnDown(int clickPoint);
    }

}
           

其中,用到的類:

public class Point {

    private float x;
    private float y;

    public Point(float x, float y) {
        this.x = x;
        this.y = y;
    }

    public float getX() {
        return x;
    }

    public float getY() {
        return y;

    }
}
           
public class PointEvaluator2 implements TypeEvaluator{  

    @Override  
    public Object evaluate(float fraction, Object startValue, Object endValue) {  
        Point startPoint = (Point) startValue;  
        Point endPoint = (Point) endValue;  
        float x = startPoint.getX() + fraction * (endPoint.getX() - startPoint.getX());  
        float y = startPoint.getY() + fraction * (endPoint.getY() - startPoint.getY());  
        Point point = new Point(x, y);  
        return point;
    }  

           

然後,在布局檔案share_pop_window2中使用:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
    android:layout_width="match_parent"  
    android:layout_height="600dp"
    >
    <cn.heshi.sharedemo.widget.ShareView2
        android:id="@+id/share_view"
        android:layout_width="match_parent"
        android:layout_height="600dp" 
         android:background="@android:color/transparent" 
        android:layout_alignParentBottom="true" />
</RelativeLayout> 
           

自定義popwindow:

public class SharePopWindow2 extends PopupWindow implements ShareView2.OnDownActionListener2 {
        private View sharePopWindow;  
        private ShareView2 shareView;
        private OnClickPointListener2 onclickPointListener;
        public SharePopWindow2(Activity context ) {  
            super(context);  
            LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            sharePopWindow=inflater.inflate(R.layout.share_pop_window2, null);
            shareView=(ShareView2) sharePopWindow.findViewById(R.id.share_view);
            shareView.setOnDownActionListener(this);
            this.setContentView(sharePopWindow);  
            //設定SelectPicPopupWindow彈出窗體的寬  
            this.setWidth(LayoutParams.MATCH_PARENT);  
            //設定SelectPicPopupWindow彈出窗體的高  
            this.setHeight();
            //設定SelectPicPopupWindow彈出窗體可點選  
            this.setFocusable(true);  
            //設定SelectPicPopupWindow彈出窗體動畫效果  
            this.setAnimationStyle(R.style.popWindow_animation);
            //執行個體化一個ColorDrawable顔色為半透明  
            ColorDrawable dw = new ColorDrawable();  
            //設定SelectPicPopupWindow彈出窗體的背景  
            this.setBackgroundDrawable(dw);
}
        public void setOnClickPointListener(OnClickPointListener2 onclickPointListener){
            this.onclickPointListener=onclickPointListener;

        }
        public interface OnClickPointListener2 {
            public void OnClickPoint(int clickPoint);
          }
        @Override
        public void OnDown(int clickPoint) {
            onclickPointListener.OnClickPoint(clickPoint);

        }
}
           

最後在activity中為按鈕添加點選事件,彈出popwindow:

shareButton1.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {

                // 執行個體化SelectPicPopupWindow
                sharePopWindow2 = new SharePopWindow2(MainActivity.this);

                SharePopWindow2.OnClickPointListener2 onClickPointListener = new SharePopWindow2.OnClickPointListener2() {

                    @Override
                    public void OnClickPoint(int clickPoint) {
                        switch (clickPoint) {
                        case :
                            Toast.makeText(MainActivity.this, "wx",
                                    Toast.LENGTH_SHORT).show();
                            break;
                        case :
                            Toast.makeText(MainActivity.this, "qq",
                                    Toast.LENGTH_SHORT).show();
                            break;
                        case :
                            Toast.makeText(MainActivity.this, "circle",
                                    Toast.LENGTH_SHORT).show();
                            break;
                        case :
                            Toast.makeText(MainActivity.this, "qzone",
                                    Toast.LENGTH_SHORT).show();
                            break;
                        case :
                            Toast.makeText(MainActivity.this, "weibo",
                                    Toast.LENGTH_SHORT).show();
                            break;
                        case :
                            Toast.makeText(MainActivity.this, "sms",
                                    Toast.LENGTH_SHORT).show();
                            break;
                        case :
                            Toast.makeText(MainActivity.this, "email",
                                    Toast.LENGTH_SHORT).show();
                            break;
                        default:
                            sharePopWindow2.dismiss();
                            break;
                        }
                    }
                };
                sharePopWindow2.setOnClickPointListener(onClickPointListener);
                // 顯示視窗
                sharePopWindow2.showAtLocation(
                        MainActivity.this.findViewById(R.id.share_button),
                        Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL, , ); // 設定layout在PopupWindow中顯示的位置
            }
        });
           

最後上效果圖:

Android平台分享彈出動畫

請原諒我做的渣渣gif圖檔…

代碼稍後會弄到github,或者上傳到csdn,下班回家…