安卓 高斯背景模糊popupwindow,彈簧彈出 rebounds

最終類似效果圖,沒有截動畫,gridelayout彈上來的時候是波紋的。



直接上代碼。

public class MyBlurPopWin extends BlurPopupWindow
{
    Context mContext;
    GridLayout gridLayout;
    SpringChain springChain;
    Button closeBtn;
    public MyBlurPopWin(Context context) {
        super(context);
        mContext=context;
    }


    @Override//父類回調,父類創建一個根FrameLayout,這裏用來添加里面的內容。
    public void onCreatView(FrameLayout container) {
        //初始化很多東西,父類。
        super.onCreatView(container);
        //這裏必須用三個參數,並且設置成false才能獲得到layoutparams!!!否則獲得到空的。
        //當然也可以自己設置layoutparams。
        View rootView = LayoutInflater.from(mContext).inflate(R.layout.layout,container,false);
        FrameLayout.LayoutParams frameLayout= (FrameLayout.LayoutParams) rootView.getLayoutParams();
        frameLayout.gravity=Gravity.BOTTOM;
        //rootView.findViewById(R.id.btn).setOnClickListener(this);
        //FrameLayout.LayoutParams layoutParams=new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        //layoutParams.gravity=Gravity.BOTTOM;
        //rootView.setLayoutParams(layoutParams);
        //找到id,view
        gridLayout = (GridLayout) rootView.findViewById(R.id.group);
        closeBtn= (Button) rootView.findViewById(R.id.btn);
        //設置監聽,用來關閉popwin,用到了父類的backpress。
        setClickableItems(closeBtn);
        //添加到父容器。
        container.addView(rootView);
    }

    @Override//show的時候父類動畫的時候調用此函數,在這裏重寫,實現自己需要的函數
    public void onShowAnimStart() {
        Log.e("xxx","onShowAnimStart");
        super.onShowAnimStart();
        springChain =SpringChain.create(50,6,40,7);             //faceBook的rebounds
        for (int i=0;i<gridLayout.getChildCount();i++){
            final View child=gridLayout.getChildAt(i);
            springChain.addSpring(new SimpleSpringListener(){
                @Override
                public void onSpringUpdate(Spring spring) {
                    super.onSpringUpdate(spring);
                    double value=spring.getCurrentValue();
                    child.setTranslationY((float) (value*gridLayout.getMeasuredHeight()));
                }
            });
        }
        for(Spring s:springChain.getAllSprings()){
            s.setCurrentValue(1);
        }

        springChain.setControlSpringIndex(1).getControlSpring().setEndValue(0);
    }

    @Override
    public void onClick(View v) {
        super.onClick(v);
        switch (v.getId()){
            case R.id.btn:
                onBackpressed();
                break;
        }
    }

    @Override
    public boolean onBackpressed() {
        boolean isDismiss=super.onBackpressed();
        if (!isDismiss){
            springChain.setControlSpringIndex(1).getControlSpring().setEndValue(1);
        }
        return isDismiss;
    }
}


用到的高斯模糊popwin


public class BlurPopupWindow {
    PopupWindow mPopupWindow;
    View mRootView;
    FrameLayout mContentView;
    ImageView mBlurImageView;
    Activity mActivity;
    private int mDelayAnim=150;

    public BlurPopupWindow(Context context) {
        mActivity = (Activity) context;
        if (mActivity.getParent() != null) {
            ViewGroup contentView= (ViewGroup)  mActivity.getParent().getWindow().findViewById(Window.ID_ANDROID_CONTENT);
            mRootView = (ViewGroup) contentView.getChildAt(0);
            mActivity = mActivity.getParent();
        }
        if(mRootView==null){
            ViewGroup contentView= (ViewGroup) mActivity.getWindow().findViewById(Window.ID_ANDROID_CONTENT);
            mRootView = (ViewGroup) contentView.getChildAt(0);
        }
        generateContentView();
        BlurKit.init(mActivity.getApplicationContext());

    }
    public boolean isShowing(){
        if (mPopupWindow != null && mPopupWindow.isShowing()) {
            return true ;
        }
        return false;
    }
    boolean isAnimRuning ;
    public boolean onBackpressed(){
        if (mPopupWindow == null || !mPopupWindow.isShowing()) {
            return true ;
        }
        if(isAnimRuning){
            return true;
        }
        ValueAnimator valueAnimator = ValueAnimator.ofInt(255,0).setDuration(400);
        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {


            @Override
            public void onAnimationUpdate(ValueAnimator valueAnimator) {
                int value = (int) valueAnimator.getAnimatedValue();
                mBlurImageView.setImageAlpha(value);
            }
        });
        valueAnimator.setStartDelay(mDelayAnim);
        valueAnimator.setInterpolator(new DecelerateInterpolator());
        valueAnimator.setRepeatCount(0);
        valueAnimator.addListener(new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(Animator animation) {
            }

            @Override
            public void onAnimationEnd(Animator animation) {
                if (mPopupWindow != null && mPopupWindow.isShowing()) {
                    mPopupWindow.dismiss();
                }
                isAnimRuning = false;

            }

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

            @Override
            public void onAnimationRepeat(Animator animation) {

            }
        });
        valueAnimator.start();
        isAnimRuning = true;
        return false;
    }
    public void onShowAnimStart(){
    }
    public void onShowAnimEnd(){

    }
    public final void dismiss(){
        if (mPopupWindow != null && mPopupWindow.isShowing()) {
            mPopupWindow.dismiss();
        }
        isAnimRuning = false;
    }
    private void generateContentView() {
        mContentView = new FrameLayout(mActivity);
        mPopupWindow = new PopupWindow(mContentView, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
        mBlurImageView = new ImageView(mActivity);
        mBlurImageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
        FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
        mContentView.addView(mBlurImageView, params);
        mPopupWindow.setContentView(mContentView);
        mPopupWindow.setAnimationStyle(0);
//        mPopupWindow.setFocusable(true);
//        mPopupWindow.setTouchable(true);
        mPopupWindow.setOutsideTouchable(false);
        mContentView.setFocusableInTouchMode(true);
        mContentView.setFocusable(true);
        mPopupWindow.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
//        mContentView.setForeground(new ColorDrawable(Color.BLACK));
        mPopupWindow.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
        mContentView.setOnKeyListener(new View.OnKeyListener() {
            @Override
            public boolean onKey(View v, int keyCode, KeyEvent event) {

                if (event.getAction() == KeyEvent.ACTION_DOWN && keyCode == KeyEvent.KEYCODE_BACK) {


                    return true;
                }
                return false;
            }
        });

    }

    public void show() {
        if(!isViewCreated){
            isViewCreated =true;
            onCreatView(mContentView);
        }
        Bitmap bitmap = BlurKit.getInstance().fastBlur(mRootView,10,0.12f);
//        Bitmap bitmap = BlurKit.getInstance().fastBlur(mRootView,5,0.5f);
        mBlurImageView.setImageBitmap(bitmap);
        mBlurImageView.setImageAlpha(0);
        mBlurImageView.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
            @Override
            public boolean onPreDraw() {

                ValueAnimator valueAnimator = ValueAnimator.ofInt(0,255).setDuration(400);
                valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {


                    @Override
                    public void onAnimationUpdate(ValueAnimator valueAnimator) {
                        int value = (int) valueAnimator.getAnimatedValue();
                        mBlurImageView.setImageAlpha(value);
                    }
                });
                valueAnimator.setInterpolator(new DecelerateInterpolator());
                valueAnimator.setRepeatCount(0);
                valueAnimator.addListener(new Animator.AnimatorListener() {
                    @Override
                    public void onAnimationStart(Animator animation) {
                        onShowAnimStart();
                    }

                    @Override
                    public void onAnimationEnd(Animator animation) {
                        isAnimRuning= false;
                        onShowAnimEnd();
                    }

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

                    @Override
                    public void onAnimationRepeat(Animator animation) {

                    }
                });
                valueAnimator.start();
                mBlurImageView.getViewTreeObserver().removeOnPreDrawListener(this);
                isAnimRuning =true;
                return true;
            }
        });

        mPopupWindow.showAtLocation(mRootView, Gravity.CENTER , 0, 0);
    }
    boolean isViewCreated;
    public void onCreatView(FrameLayout container) {


    }
    @SuppressWarnings("unchecked")
    final public <E extends View> E findView(int id) {
        try {
            return (E)mContentView.findViewById(id);
        } catch (ClassCastException e) {

            throw e;
        }
    }

    /* Click listener that avoid double click event in short time*/
    public NoDoubleClickListener mNoDoubleClickListener = new NoDoubleClickListener(){

        @Override
        public void onClickInternal(View v) {
            BlurPopupWindow.this.onClick(v);
        }
    };

    public interface NoDoubleClickListener{
        public void onClickInternal(View v);

    }
    public void onClick(View v){

    }
    /*Set all widget that need to implements OnClick() here*/
    protected void setClickableItems(View... views) {
        if (views != null && views.length > 0) {
            for (View v : views) {
                if (v != null)
                    v.setOnClickListener((new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            BlurPopupWindow.this.onClick(v);
                        }
                    }));
            }
        }
    }
    /*Set all widget that need to implements OnClick() here*/
    protected void setClickableItems(int... residGroup) {
        if (residGroup != null && residGroup.length > 0) {
            for (int resid : residGroup) {
                if (resid != 0) {
                    findView(resid).setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            BlurPopupWindow.this.onClick(v);
                        }
                    });
                }
            }
        }
    }



}



blurPopupwindow用到的工具

public class BlurKit {

    private static BlurKit instance;

    private RenderScript rs;

    public static void init(Context context) {
        if (instance != null) {
            return;
        }

        instance = new BlurKit();
        instance.rs = RenderScript.create(context);
    }

    public Bitmap blur(Bitmap src, int radius) {
        final Allocation input = Allocation.createFromBitmap(rs, src);
        final Allocation output = Allocation.createTyped(rs, input.getType());
        final ScriptIntrinsicBlur script = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs));
        script.setRadius(radius);
        script.setInput(input);
        script.forEach(output);
        output.copyTo(src);
        return src;
    }

    public Bitmap blur(View src, int radius) {
        Bitmap bitmap = getBitmapForView(src, 1f);
        return blur(bitmap, radius);
    }

    public Bitmap fastBlur(View src, int radius, float downscaleFactor) {
        Bitmap bitmap = getBitmapForView(src, downscaleFactor);
        return blur(bitmap, radius);
    }

    private Bitmap getBitmapForView(View src, float downscaleFactor) {
        Bitmap bitmap = Bitmap.createBitmap(
                (int) (src.getWidth() * downscaleFactor),
                (int) (src.getHeight() * downscaleFactor),
                Bitmap.Config.ARGB_4444
        );

        Canvas canvas = new Canvas(bitmap);
        Matrix matrix = new Matrix();
        matrix.preScale(downscaleFactor, downscaleFactor);
        canvas.setMatrix(matrix);
        src.draw(canvas);

        return bitmap;
    }

    public static BlurKit getInstance() {
        if (instance == null) {
            throw new RuntimeException("BlurKit not initialized!");
        }

        return instance;
    }

}










發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章