Android simulation message suspension notification (only applicable to in-app--ViewDragHelper, suspension Notification that does not require permission)

package com.zzm.ndkandmaterialdesigndemo;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
import android.os.CountDownTimer;
import android.util.Log;
import android.view.View;
import android.view.animation.LinearInterpolator;

public class MessageRemindUtil {
    public static float moveToPosition = -200f;
    public static int moveDownDuration = 200;
    public static int moveUpDuration = 200;
    public static int disappearTime = 4000;
    public static ObjectAnimator animator;
    public static CountDownTimer countDownTimer;
    private static View target;
    private static MoveUpEndListener moveUpEndListener;

    private static void moveUp(int moveUpDuration, AnimatorListenerAdapter animatorListenerAdapter) {
        float start = target.getY();
        animator = ObjectAnimator.ofFloat(target, "TranslationY", start, moveToPosition);
        animator.setDuration(moveUpDuration);
        animator.setInterpolator(new LinearInterpolator());
        if (animatorListenerAdapter != null) {
            animator.addListener(animatorListenerAdapter);
        } else {
            animator.addListener(new NormalMoveUpListener());
        }
        animator.start();
    }

    private static void moveDown(int moveDownDuration) {
        float start = target.getY();
        target.setVisibility(View.VISIBLE);
        animator = ObjectAnimator.ofFloat(target, "TranslationY", start, 0f);
        animator.setDuration(moveDownDuration);
        animator.setInterpolator(new LinearInterpolator());
        animator.start();
    }

    public static void initial(View view, float moveToPosition1, int moveDownDuration, int moveUpDuration, int disappearTime1) {
        target = view;
        moveToPosition = moveToPosition1;
        disappearTime = disappearTime1;
        float start = view.getY ();
        animator = ObjectAnimator.ofFloat(view, "TranslationY", start, moveToPosition);
        animator.start();
    }


    public static void messageRemind() {
        // reset the timer
        if (countDownTimer != null)
            countDownTimer.cancel();
        countDownTimer = new MyCountDownTimer(disappearTime, 1000);
        countDownTimer.start();
        //3 cases 1. is moving 2. has been hidden 3 has been displayed
        if (animator.isRunning()) {
            // 1 stop running the hidden control and move it to the original position and then move down
            animator.cancel();
            target.setVisibility(View.GONE);
            moveUp(0, new UnNormalMoveUpListener());
        } else if (target.getVisibility() != View.VISIBLE) {
            // 2 normal move down
            moveDown(moveDownDuration);
        } else if (target.getVisibility() == View.VISIBLE) {
            // 3 The hidden control moves up, then moves normally
            target.setVisibility(View.GONE);
            moveUp(0, new UnNormalMoveUpListener());
        }
    }

    //Don't display message reminder when jumping to other interface
    public static void cancelMessageRemind() {
        // cancel the timer
        countDownTimer.cancel();
        //2 cases 1. is moving 3 has been displayed
        if (animator.isRunning()) {
            // 1 stop running the hidden control and move it to the original position
            animator.cancel();
            target.setVisibility(View.GONE);
            moveUp (0, null);
        } else if (target.getVisibility() == View.VISIBLE) {
            // 2 hide the control to move up
            target.setVisibility(View.GONE);
            moveUp (0, null);
        }
    }

    //Slide floatView to let him moveup in advance
    public static void moveOrClickFloatMessageViewToMoveUp() {
        countDownTimer.cancel();
        moveUp(200, new MoveFloatMessageVeiwMoveUpListener());
    }

    public static void setMoveUpEndListener(MoveUpEndListener moveUpEndListener1) {
        moveUpEndListener = moveUpEndListener1;
    }

    //Destroy the timer, and some objects, to avoid memory leaks
    public static void destroyAnything() {
        if (countDownTimer != null) {
            countDownTimer.cancel();
            countDownTimer = null;
        }
        target = null;
        animator = null;
    }

    public interface MoveUpEndListener {
        void floatMessageViewContentViewResume();
    }


    private static class UnNormalMoveUpListener extends AnimatorListenerAdapter {
        @Override
        public void onAnimationEnd(Animator animation) {
            super.onAnimationEnd (animation);
            if (target.getVisibility() == View.VISIBLE)
                target.setVisibility(View.GONE);
            moveDown(moveDownDuration);
        }
    }

    private static class NormalMoveUpListener extends AnimatorListenerAdapter {
        @Override
        public void onAnimationEnd(Animator animation) {
            super.onAnimationEnd (animation);
            if (target.getVisibility() == View.VISIBLE)
                target.setVisibility(View.GONE);
        }
    }

    private static class MoveFloatMessageVeiwMoveUpListener extends AnimatorListenerAdapter {
        @Override
        public void onAnimationEnd(Animator animation) {
            super.onAnimationEnd (animation);
            if (target.getVisibility() == View.VISIBLE)
                target.setVisibility(View.GONE);
            if (moveUpEndListener != null)
                moveUpEndListener.floatMessageViewContentViewResume();
        }
    }

    private static class MyCountDownTimer extends CountDownTimer {

        /**
         * @param millisInFuture    The number of millis in the future from the call
         *                          to {@link #start()} until the countdown is done and {@link #onFinish()}
         *                          is called.
         * @param countDownInterval The interval along the way to receive
         *                          {@link #onTick(long)} callbacks.
         */
        public MyCountDownTimer(long millisInFuture, long countDownInterval) {
            super(millisInFuture, countDownInterval);
        }

        @Override
        public void onTick(long millisUntilFinished) {
            Log.i("zengzeming", "onTick : " + millisUntilFinished / 1000);
        }

        @Override
        public void onFinish() {
            moveUp(moveUpDuration, null);
        }
    }

}
package com.zzm.ndkandmaterialdesigndemo;

import android.animation.FloatEvaluator;
import android.animation.ObjectAnimator;
import android.content.Context;
import android.graphics.Point;
import android.support.v4.widget.ViewDragHelper;
import android.support.v7.widget.CardView;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;

/**
 * Date : 2017/12/21  9:28
 * Author : 22m
 * Description :
 * onFinishInflate
 * onMeasure
 * onSizeChanged
 * onLayout
 */

public class FloatMessageView extends CardView implements MessageRemindUtil.MoveUpEndListener {
    private ViewDragHelper viewDragHelper;
    private View dragedView;
    private Point dragedViewPositionPoint;
    private boolean manualMoved;
    private int dragedViewWidth;
    private int floatMessageViewWidth;
    private int paddingLeft;
    private int paddingRight;

    public FloatMessageView(Context context) {
        super(context);
        initial();
    }

    public FloatMessageView(Context context, AttributeSet attrs) {
        super(context, attrs);
        initial();
    }

    public FloatMessageView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initial();
    }

    private void initial() {
        //Initialize viewdraghelper (bind the layout to be fed back), etc.
        viewDragHelper = ViewDragHelper.create(this, 1.0f, new ViewDragHelperCallback());
        MessageRemindUtil.setMoveUpEndListener(this);
        dragedViewPositionPoint = new Point();
        manualMoved = false;
        dragedViewWidth = 0;
        floatMessageViewWidth = 0;
        paddingLeft = 0;
        paddingRight = 0;
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        //The touch event is passed to viewdraghelper to handle
        viewDragHelper.processTouchEvent(event);
        return true;
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        //The interception event is handed over to viewdraghelper to handle
        return viewDragHelper.shouldInterceptTouchEvent(ev);
    }

    @Override
    protected void onFinishInflate() {
        //The layout is loaded and called, you can get the controls in the layout
        super.onFinishInflate();
        dragedView = getChildAt(0);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        //Called when the layout allocates the size for the first time, and when the layout changes
        super.onSizeChanged(w, h, oldw, oldh);
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        //Called when the layout position is determined
        super.onLayout(changed, left, top, right, bottom);
        // getTop(getLeft) is always the original y value of the layout control when it was first loaded
        dragedViewPositionPoint.x = dragedView.getLeft();
        dragedViewPositionPoint.y = dragedView.getTop();
        dragedViewWidth = dragedView.getMeasuredWidth();
        floatMessageViewWidth = getMeasuredWidth();
        paddingLeft = getPaddingLeft();
        paddingRight = getPaddingRight();
    }

    @Override
    public void floatMessageViewContentViewResume() {
        //Move to the original position and the transparency is also set to the original value
        ObjectAnimator animator = ObjectAnimator.ofFloat(dragedView, "TranslationX", 0f, 0f);
        animator.setDuration (0);
        animator.start();
        dragedView.setAlpha(1f);
    }


    public void setDragedViewClickInformation(Object object) {
        dragedView.setTag(object);
        ((TextView) dragedView).setText((CharSequence) object);
    }

    public void setDragedViewClickListener(OnClickListener onClickListener) {
        dragedView.setOnClickListener(onClickListener);
    }

    @Override
    public void computeScroll() {
        //Update some related data of sliding
        super.computeScroll();
        // Determine if it is moving
        if (viewDragHelper.continueSettling(true)) {
            invalidate();
        } else {
            if (manualMoved && dragedView.getX() != dragedViewPositionPoint.x) {
                MessageRemindUtil.moveOrClickFloatMessageViewToMoveUp();
            }
            manualMoved = false;
        }
    }

    private class ViewDragHelperCallback extends ViewDragHelper.Callback {

        @Override
        public boolean tryCaptureView(View child, int pointerId) {
            //You can determine which view can respond to the touch event of the finger
            return true;
        }

        @Override
        public int clampViewPositionHorizontal(View child, int left, int dx) {
            //Control the response of horizontal movement
            return left;
        }

        @Override
        public int clampViewPositionVertical(View child, int top, int dy) {
            //Control the response of vertical movement
            return dragedViewPositionPoint.y;
        }

        @Override
        public int getViewHorizontalDragRange(View child) {
            return floatMessageViewWidth - paddingLeft - paddingRight;
        }

        @Override
        public int getViewVerticalDragRange(View child) {
            return super.getViewVerticalDragRange(child);
        }

        @Override
        public void onViewReleased(View releasedChild, float xvel, float yvel) {
            //The method is called when the finger touches the control and leaves the control
            super.onViewReleased(releasedChild, xvel, yvel);
            int x = dragedViewPositionPoint.x;
            int y = dragedViewPositionPoint.y;
            float dragViewX = releasedChild.getX();
            if (releasedChild == dragedView) {
                if (dragViewX > dragedViewWidth / 3 || (xvel > 500 && dragViewX > 0)) {
                    x = floatMessageViewWidth - paddingLeft - paddingRight;
                } else if (dragViewX < -dragedViewWidth / 3 || (xvel < -500 && dragViewX < 0)) {
                    x = -dragedViewWidth;
                }
                //This method simulates the action of the view dragged by the finger for the released view (can only be called in the onViewReleased method)
                viewDragHelper.settleCapturedViewAt(x, y);
                //Update some data drawn
                invalidate();
            }
        }

        @Override
        public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy) {
            // When the position of the drag view changes, transparent operations can be set
            super.onViewPositionChanged(changedView, left, top, dx, dy);
            manualMoved = true;
            FloatEvaluator floatEvaluator = new FloatEvaluator();
            float total = floatMessageViewWidth / 2;
            float current = Math.abs(left);
            current = current > total ? total : current;
            float ratio = current / total;
            float alpha = floatEvaluator.evaluate(ratio, 1, 0);
            dragedView.setAlpha(alpha);
        }
    }

    /**
     * Steps for usage:
     * 1. Find the controls
     * 2.MessageRemindUtil initialization
     * 3. Set the click listener of DragedView
     * 4. Set the information that can be used by clicking on DragedView
     * 5. Pop up the floating view
     * 6.  4-->5-->4-->5-->4-->5
     */

}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325648994&siteId=291194637