任意View边缘虚化

作者: Ad大成 | 来源:发表于2022-12-29 15:50 被阅读0次
    package com.tencent.wcenter.view;
    
    import android.content.Context;
    import android.content.res.TypedArray;
    import android.graphics.Canvas;
    import android.graphics.LinearGradient;
    import android.graphics.Paint;
    import android.graphics.PorterDuff;
    import android.graphics.PorterDuffXfermode;
    import android.graphics.Shader;
    import android.util.AttributeSet;
    import android.view.View;
    import android.widget.FrameLayout;
    
    import com.tencent.wcenter.R;
    import com.tencent.wcenter.utils.SystemUtils;
    
    /**
     * 任意View边沿透明
     */
    public class EdgeTransparentView extends FrameLayout {
        //初始化画笔
        private Paint mPaint;
        //标记边沿透明
        private int position;
        //边沿透明的宽度
        private float drawSize;
        //顶边透明
        private int topMask = 0x01;
        //底边透明
        private int bottomMask = topMask << 1;
        //左边透明
        private int leftMask = topMask << 2;
        //右边透明
        private int rightMask = topMask << 3;
        //当前view的宽度
        private int mWidth;
        //当前view的高度
        private int mHeight;
    
    
        //自定义view构造方法,在xml中使用时调用
        public EdgeTransparentView(Context context, AttributeSet attrs) {
            this(context, attrs, 0);
        }
        //自定义view,带有自定义styleattr时调用
        public EdgeTransparentView(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            init(context, attrs);
        }
        //初始化属性和变量
        private void init(Context context, AttributeSet attrs) {
            mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
            mPaint.setStyle(Paint.Style.FILL);
            mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT));
    
            //解析自定义属性
            final TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.EdgeTransparentView);
            //默认所有边都具有边沿透明功能
            position = typedArray.getInt(R.styleable.EdgeTransparentView_edge_position, 0);
            //默认宽度20
            drawSize = typedArray.getDimension(R.styleable.EdgeTransparentView_edge_width, SystemUtils.dp2px(getContext(), 20));
            typedArray.recycle();
        }
    
    
        //尺寸改变时候回调
        @Override
        protected void onSizeChanged(int w, int h, int oldw, int oldh) {
            super.onSizeChanged(w, h, oldw, oldh);
            initShader();
            mWidth = getWidth();
            mHeight = getHeight();
        }
    
        //渐变颜色
        private int[] mGradientColors = {0xff15202E , 0x0015202E};
        //渐变位置
        private float[] mGradientPosition = new float[]{0, 1};
    
        private void initShader() {
            mPaint.setShader(new LinearGradient(0, 0, 0, drawSize, mGradientColors, mGradientPosition, Shader.TileMode.CLAMP));
        }
    
        //绘制childview
        @Override
        protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
            int layerSave = canvas.saveLayer(0, 0, getWidth(), getHeight(), null, Canvas.ALL_SAVE_FLAG);
            boolean drawChild = super.drawChild(canvas, child, drawingTime);
            if (position == 0 || (position & topMask) != 0) {
                canvas.drawRect(0, 0, mWidth, drawSize, mPaint);
            }
    
            if (position == 0 || (position & bottomMask) != 0) {
                int save = canvas.save();
                canvas.rotate(180, mWidth / 2, mHeight / 2);
                canvas.drawRect(0, 0, mWidth, drawSize, mPaint);
                canvas.restoreToCount(save);
            }
    
            int offset = (mHeight - mWidth) / 2;
            if (position == 0 || (position & leftMask) != 0) {
                int saveCount = canvas.save();
                canvas.rotate(90, mWidth / 2, mHeight / 2);
                canvas.translate(0, offset);
                canvas.drawRect(0 - offset, 0, mWidth + offset, drawSize, mPaint);
                canvas.restoreToCount(saveCount);
            }
    
            if (position == 0 || (position & rightMask) != 0) {
                int saveCount = canvas.save();
                canvas.rotate(270, mWidth / 2, mHeight / 2);
                canvas.translate(0, offset);
                canvas.drawRect(0 - offset, 0, mWidth + offset, drawSize, mPaint);
                canvas.restoreToCount(saveCount);
            }
    
            canvas.restoreToCount(layerSave);
            return drawChild;
        }
    
    }
    

    使用方法

    
        <LinearLayout
            android:id="@+id/ll_banner_vp_root"
            android:layout_width="match_parent"
            android:gravity="center"
            android:orientation="vertical"
            android:layout_height="@dimen/dp_400">
    虚化BannerViewPager 
            <com.tencent.wcenter.view.EdgeTransparentView
                android:layout_width="wrap_content"
                android:layout_gravity="center_horizontal"
                app:edge_position="left|right"
                app:edge_width="@dimen/dp_80"
                android:layout_marginRight="1dp"
                android:layout_height="@dimen/dp_320">
            <com.youth.banner.view.BannerViewPager
                android:id="@id/bannerViewPager"
                android:layout_gravity="center_horizontal"
                android:layout_width="match_parent"
                android:layout_height="@dimen/dp_320"
                android:clipChildren="false" />
            </com.tencent.wcenter.view.EdgeTransparentView>
    

    相关文章

      网友评论

        本文标题:任意View边缘虚化

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