美文网首页
自定义弹窗尖角(上下左右)

自定义弹窗尖角(上下左右)

作者: biubiubiuboy | 来源:发表于2020-05-27 16:22 被阅读0次

    弹窗自定义尖角,先看下效果图。


    图1.png 图2.jpg 图3.jpg

    删除按钮的位置不确定,还要根据按钮位置来确定弹窗实在按钮上方还是下方展示,尖角有可能在左边,也可能在右边或者中间。(为什么自定义呢?UI不会切点9。。。。)代码

    public class CornerPopupWindow extends PopupWindow {
    
        private CornerRelativeLayout cornerView;
    
        private Context context;
    
        public CornerPopupWindow(Context context) {
            this.context = context;
            setWidth(ViewGroup.LayoutParams.MATCH_PARENT);
            setHeight(ViewGroup.LayoutParams.WRAP_CONTENT);
    
            setFocusable(true);
            setOutsideTouchable(false);
            setClippingEnabled(false);
    
        }
    
        public void setCornerView(View view) {//弹窗内布局
            cornerView = new CornerRelativeLayout(context);
            cornerView.setBackgroundColor(Color.TRANSPARENT);
            cornerView.addView(view);
            setContentView(cornerView);
        }
    
        /**
         * 显示弹窗
         */
        public void show(View view) {//view为删除点击的按钮
            CornerRelativeLayout.CornerLegOrientation orientation = null;
            final int anchorLoc[] = new int[2];
            final int windowPos[] = new int[2];
            // 获取锚点View在屏幕上的左上角坐标位置
            view.getLocationOnScreen(anchorLoc);
            final int anchorHeight = view.getHeight();
            // 获取屏幕的高宽
            final int screenHeight = PublicViewUtils.getDisplayHeight(view.getContext());
            final int screenWidth = PublicViewUtils.getDisplayWidth(view.getContext());
            // 测量contentView
            cornerView.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
            // 计算contentView的高宽
            final int windowHeight = cornerView.getMeasuredHeight();
            final int windowWidth = cornerView.getMeasuredWidth();
            // 判断需要向上弹出还是向下弹出显示
            final boolean isNeedShowUp = (screenHeight - anchorLoc[1] - anchorHeight < windowHeight);
            if (isNeedShowUp) {
                windowPos[0] = screenWidth - windowWidth;
                windowPos[1] = anchorLoc[1] - windowHeight;
                orientation = CornerRelativeLayout.CornerLegOrientation.BOTTOM;
            } else {
                windowPos[0] = screenWidth - windowWidth;
                windowPos[1] = anchorLoc[1] + anchorHeight;
                orientation = CornerRelativeLayout.CornerLegOrientation.TOP;
            }
    
            if (!this.isShowing()) {
                cornerView.setCornerParams(anchorLoc[0] + view.getWidth()/2, orientation, 0.75f); // 设置气泡布局方向及尖角偏移
                showAtLocation(view, Gravity.TOP | Gravity.START, 0, windowPos[1]);
            } else {
                this.dismiss();
            }
        }
    }
    

    尖角(只添加了上下,左右可以在renderCornerLegMatrix添加)

    public class CornerRelativeLayout extends RelativeLayout {
    
        public enum CornerLegOrientation {
            TOP, BOTTOM
        }
    
        public  int PADDING = 30;
        public  float STROKE_WIDTH = 2.0f;
    
        public  float CORNER_RADIUS = 8.0f;
    
        public  int SHADOW_COLOR = Color.argb(100, 0, 0, 0);
    
        private Paint mFillPaint = null;
        private final Path mPath = new Path();
        private final Path mCornerPath = new Path();
        private final Paint mPaint = new Paint(Paint.DITHER_FLAG);
    
        private float mCornerLegOffset = 0.75f;
    
        private CornerLegOrientation mCornerLegOrientation = CornerLegOrientation.TOP;
    
        private int xLocation;
    
        public CornerRelativeLayout(Context context) {
            this(context, null);
        }
    
        public CornerRelativeLayout(Context context, AttributeSet attrs) {
            this(context, attrs, 0);
        }
    
        public CornerRelativeLayout(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
            init(context, attrs);
        }
    
        private void init(final Context context, final AttributeSet attrs) {
    
            //setGravity(Gravity.CENTER);
            ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
            setLayoutParams(params);
            if (attrs != null) {
                TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.corner);
    
                try {
                    PADDING = a.getDimensionPixelSize(R.styleable.corner_padding, PADDING);
                    SHADOW_COLOR = a.getInt(R.styleable.corner_shadowColor, SHADOW_COLOR);
                    STROKE_WIDTH = a.getFloat(R.styleable.corner_buStrokeWidth, STROKE_WIDTH);
                    CORNER_RADIUS = a.getFloat(R.styleable.corner_buCornerRadius, CORNER_RADIUS);
                } finally {
                    if (a != null) {
                        a.recycle();
                    }
                }
            }
            mPaint.setColor(SHADOW_COLOR);
            mPaint.setStyle(Style.FILL);
            mPaint.setStrokeCap(Cap.BUTT);
            mPaint.setAntiAlias(true);
            mPaint.setStrokeWidth(STROKE_WIDTH);
            mPaint.setStrokeJoin(Paint.Join.MITER);
            mPaint.setPathEffect(new CornerPathEffect(CORNER_RADIUS));
            if (Build.VERSION.SDK_INT >= 11) {
                setLayerType(LAYER_TYPE_SOFTWARE, mPaint);
            }
            mFillPaint = new Paint(mPaint);
            mFillPaint.setColor(Color.WHITE);
            mFillPaint.setShader(new LinearGradient(100f, 0f, 100f, 200f, Color.WHITE, Color.WHITE, TileMode.CLAMP));
    
            if (Build.VERSION.SDK_INT >= 11) {
                setLayerType(LAYER_TYPE_SOFTWARE, mFillPaint);
            }
            mPaint.setShadowLayer(2f, 2F, 5F, SHADOW_COLOR);
            renderCornerLegPrototype();
            setPadding(PADDING, PADDING, PADDING, PADDING);
    
        }
    
        @Override
        protected void onConfigurationChanged(Configuration newConfig) {
            super.onConfigurationChanged(newConfig);
        }
    
        /**
         * 尖角path
         */
        private void renderCornerLegPrototype() {
            mCornerPath.moveTo(0, 0);
            mCornerPath.lineTo(PADDING * 1.5f, -PADDING / 1.5f);
            mCornerPath.lineTo(PADDING * 1.5f, PADDING / 1.5f);
            mCornerPath.close();
        }
    
        public void setCornerParams(int xLocation, final CornerLegOrientation cornerLegOrientation, final float cornerOffset) {
            this.xLocation = xLocation;
            mCornerLegOffset = cornerOffset;
            this.mCornerLegOrientation = cornerLegOrientation;
        }
    
        /**
         * 根据显示方向,获取尖角位置矩阵
         * @param width
         * @param height
         * @return
         */
        private Matrix renderCornerLegMatrix(final float width, final float height) {
    
            float dstX = 0;
            float dstY = 0;
            final Matrix matrix = new Matrix();
    
            switch (mCornerLegOrientation) {
                case TOP:
                    dstX = xLocation;
                    dstY = 0;
                    matrix.postRotate(90);
                    break;
    
                case BOTTOM:
                    dstY = height;
                    dstX = xLocation;
                    matrix.postRotate(270);
                    break;
            }
    
            matrix.postTranslate(dstX, dstY);
            return matrix;
        }
    
        @Override
        protected void onDraw(Canvas canvas) {
            final float width = canvas.getWidth();
            final float height = canvas.getHeight();
    
            mPath.rewind();
            mPath.addRoundRect(new RectF(PADDING, PADDING, width - PADDING, height - PADDING), CORNER_RADIUS, CORNER_RADIUS, Direction.CW);//画圆角举行
            mPath.addPath(mCornerPath, renderCornerLegMatrix(width, height));//添加尖角
    
            canvas.drawPath(mPath, mPaint);
            canvas.scale((width - STROKE_WIDTH) / width, (height - STROKE_WIDTH) / height, width / 2f, height / 2f);
            canvas.drawPath(mPath, mFillPaint);
        }
    }
    

    使用:

    CornerPopupWindow mPopupWindow = new CornerPopupWindow(context);
    mPopupWindow.setCornerView(view);
    PublicViewUtils.backgroundAlpha(context, 0.4f);
    mPopupWindow.show(按钮);
    

    相关文章

      网友评论

          本文标题:自定义弹窗尖角(上下左右)

          本文链接:https://www.haomeiwen.com/subject/ctwwahtx.html