ShadowView . 外控件阴影

https://github.com/yingLanNull/ShadowImageView

package com.sensethink.meshtalkie.ui.widgt;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.RectF;
import android.os.Build;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;

import com.sensethink.meshtalkie.R;


public class ShadowContainer extends ViewGroup {
    private final float deltaLength;
    private final float cornerRadius;
    private final Paint mShadowPaint;


    public ShadowContainer(Context context) {
        this(context, null);
    }

    public ShadowContainer(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public ShadowContainer(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ShadowContainer);
        int shadowColor = a.getColor(R.styleable.ShadowContainer_containerShadowColor, Color.RED);
//        int shadowColor = Color.RED;
        float shadowRadius = a.getDimension(R.styleable.ShadowContainer_containerShadowRadius, 0);
        deltaLength = a.getDimension(R.styleable.ShadowContainer_containerDeltaLength, 0);
        cornerRadius = a.getDimension(R.styleable.ShadowContainer_containerCornerRadius, 0);
        float dx = a.getDimension(R.styleable.ShadowContainer_deltaX, 0);
        float dy = a.getDimension(R.styleable.ShadowContainer_deltaY, 0);

        a.recycle();
        mShadowPaint = new Paint();
        mShadowPaint.setStyle(Paint.Style.FILL);
        mShadowPaint.setAntiAlias(true);
        mShadowPaint.setColor(shadowColor);
        mShadowPaint.setShadowLayer(shadowRadius, dx, dy, shadowColor);
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
    }

    @Override
    protected void dispatchDraw(Canvas canvas) {

            if (getLayerType() != LAYER_TYPE_SOFTWARE) {
                setLayerType(LAYER_TYPE_SOFTWARE, null);
            }
            View child = getChildAt(0);
            int left = child.getLeft();
            int top = child.getTop();
            int right = child.getRight();
            int bottom = child.getBottom();
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                canvas.drawRoundRect(left, top, right, bottom, cornerRadius, cornerRadius, mShadowPaint);
            } else {
                Path drawablePath = new Path();
                drawablePath.moveTo(left + cornerRadius, top);
                drawablePath.arcTo(new RectF(left, top, left + 2 * cornerRadius, top + 2 * cornerRadius), -90, -90, false);
                drawablePath.lineTo(left, bottom - cornerRadius);
                drawablePath.arcTo(new RectF(left, bottom - 2 * cornerRadius, left + 2 * cornerRadius, bottom), 180, -90, false);
                drawablePath.lineTo(right - cornerRadius, bottom);
                drawablePath.arcTo(new RectF(right - 2 * cornerRadius, bottom - 2 * cornerRadius, right, bottom), 90, -90, false);
                drawablePath.lineTo(right, top + cornerRadius);
                drawablePath.arcTo(new RectF(right - 2 * cornerRadius, top, right, top + 2 * cornerRadius), 0, -90, false);
                drawablePath.close();
                canvas.drawPath(drawablePath, mShadowPaint);
            }

        super.dispatchDraw(canvas);
    }



    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        if (getChildCount() != 1) {
            throw new IllegalStateException("子View只能有一个");
        }
        int measuredWidth = getMeasuredWidth();
        int measuredHeight = getMeasuredHeight();
        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        View child = getChildAt(0);
        LayoutParams layoutParams = (LayoutParams) child.getLayoutParams();
        int childBottomMargin = (int) (Math.max(deltaLength, layoutParams.bottomMargin) + 1);
        int childLeftMargin = (int) (Math.max(deltaLength, layoutParams.leftMargin) + 1);
        int childRightMargin = (int) (Math.max(deltaLength, layoutParams.rightMargin) + 1);
        int childTopMargin = (int) (Math.max(deltaLength, layoutParams.topMargin) + 1);
        int widthMeasureSpecMode;
        int widthMeasureSpecSize;
        int heightMeasureSpecMode;
        int heightMeasureSpecSize;
        if (widthMode == MeasureSpec.UNSPECIFIED){
            widthMeasureSpecMode = MeasureSpec.UNSPECIFIED;
            widthMeasureSpecSize = MeasureSpec.getSize(widthMeasureSpec);
        }else {
            if (layoutParams.width == LayoutParams.MATCH_PARENT) {
                widthMeasureSpecMode = MeasureSpec.EXACTLY;
                widthMeasureSpecSize = measuredWidth - childLeftMargin - childRightMargin;
            } else if (LayoutParams.WRAP_CONTENT == layoutParams.width) {
                widthMeasureSpecMode = MeasureSpec.AT_MOST;
                widthMeasureSpecSize = measuredWidth - childLeftMargin - childRightMargin;
            } else {
                widthMeasureSpecMode = MeasureSpec.EXACTLY;
                widthMeasureSpecSize = layoutParams.width;
            }
        }
        if (heightMode == MeasureSpec.UNSPECIFIED){
            heightMeasureSpecMode = MeasureSpec.UNSPECIFIED;
            heightMeasureSpecSize = MeasureSpec.getSize(heightMeasureSpec);
        }else {
            if (layoutParams.height == LayoutParams.MATCH_PARENT) {
                heightMeasureSpecMode = MeasureSpec.EXACTLY;
                heightMeasureSpecSize = measuredHeight - childBottomMargin - childTopMargin;
            } else if (LayoutParams.WRAP_CONTENT == layoutParams.height) {
                heightMeasureSpecMode = MeasureSpec.AT_MOST;
                heightMeasureSpecSize = measuredHeight - childBottomMargin - childTopMargin;
            } else {
                heightMeasureSpecMode = MeasureSpec.EXACTLY;
                heightMeasureSpecSize = layoutParams.height;
            }
        }
        measureChild(child, MeasureSpec.makeMeasureSpec(widthMeasureSpecSize, widthMeasureSpecMode), MeasureSpec.makeMeasureSpec(heightMeasureSpecSize, heightMeasureSpecMode));
        int parentWidthMeasureSpec = MeasureSpec.getMode(widthMeasureSpec);
        int parentHeightMeasureSpec = MeasureSpec.getMode(heightMeasureSpec);
        int height = measuredHeight;
        int width = measuredWidth;
        int childHeight = child.getMeasuredHeight();
        int childWidth = child.getMeasuredWidth();
        if (parentHeightMeasureSpec == MeasureSpec.AT_MOST){
            height = childHeight + childTopMargin + childBottomMargin;
        }
        if (parentWidthMeasureSpec == MeasureSpec.AT_MOST){
            width = childWidth + childRightMargin + childLeftMargin;
        }
        if (width < childWidth + 2 * deltaLength){
            width = (int) (childWidth + 2 * deltaLength);
        }
        if (height < childHeight + 2 * deltaLength){
            height = (int) (childHeight + 2 * deltaLength);
        }
        if (height != measuredHeight || width != measuredWidth){
            setMeasuredDimension(width, height);
        }
    }

    static class LayoutParams extends MarginLayoutParams{

        public LayoutParams(Context c, AttributeSet attrs) {
            super(c, attrs);
        }

        public LayoutParams(int width, int height) {
            super(width, height);
        }

        public LayoutParams(MarginLayoutParams source) {
            super(source);
        }

        public LayoutParams(ViewGroup.LayoutParams source) {
            super(source);
        }
    }

    @Override
    protected ViewGroup.LayoutParams generateDefaultLayoutParams() {
        return new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
    }

    @Override
    protected ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) {
        return new LayoutParams(p);
    }

    @Override
    public ViewGroup.LayoutParams generateLayoutParams(AttributeSet attrs) {
        return new LayoutParams(getContext(), attrs);
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        View child = getChildAt(0);
        int measuredWidth = getMeasuredWidth();
        int measuredHeight = getMeasuredHeight();
        int childMeasureWidth = child.getMeasuredWidth();
        int childMeasureHeight = child.getMeasuredHeight();
        child.layout((measuredWidth - childMeasureWidth) / 2, (measuredHeight - childMeasureHeight) / 2, (measuredWidth + childMeasureWidth) / 2, (measuredHeight + childMeasureHeight) / 2);
    }
}

    <declare-styleable name="ShadowContainer">
        <attr name="containerShadowColor" format="color"/>
        <attr name="containerShadowRadius" format="dimension"/>
        <attr name="containerDeltaLength" format="dimension"/>
        <attr name="containerCornerRadius" format="dimension"/>
        <attr name="deltaX" format="dimension"/>
        <attr name="deltaY" format="dimension"/>
    </declare-styleable>

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要在 Android 中添加左右侧阴影,可以使用以下两种方法: 1. 使用 9-Patch 图片 可以使用 9-Patch 图片来添加阴影。9-Patch 图片是一种特殊的 PNG 图片,其中包含了一个黑色像素边框,用于定义图片的拉伸区域和不可拉伸区域。可以在拉伸区域的边缘添加阴影。 2. 使用自定义 View 可以创建一个自定义 View,重写它的 onDraw() 方法,在 View 的左右两侧绘制阴影。以下是示例代码: ```java public class ShadowView extends View { private Paint mPaint; private int mShadowWidth; private int mShadowColor; public ShadowView(Context context) { super(context); init(); } public ShadowView(Context context, AttributeSet attrs) { super(context, attrs); init(); } public ShadowView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); } private void init() { mPaint = new Paint(); mPaint.setStyle(Paint.Style.FILL); mPaint.setAntiAlias(true); mShadowWidth = 10; // 阴影宽度 mShadowColor = Color.parseColor("#80000000"); // 阴影颜色 } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); int width = getWidth(); int height = getHeight(); // 绘制左侧阴影 mPaint.setShader(new LinearGradient(0, 0, mShadowWidth, 0, mShadowColor, Color.TRANSPARENT, Shader.TileMode.CLAMP)); canvas.drawRect(0, 0, mShadowWidth, height, mPaint); // 绘制右侧阴影 mPaint.setShader(new LinearGradient(width - mShadowWidth, 0, width, 0, Color.TRANSPARENT, mShadowColor, Shader.TileMode.CLAMP)); canvas.drawRect(width - mShadowWidth, 0, width, height, mPaint); } } ``` 在布局文件中添加该 View 即可: ```xml <com.example.myapp.ShadowView android:layout_width="match_parent" android:layout_height="wrap_content" android:background="#ffffff" /> ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值