android 直线 阴影,如何在android中的linearlayout周围显示阴影?

您可以将以下类用于xml标记:

import android.annotation.SuppressLint;

import android.content.Context;

import android.content.res.TypedArray;

import android.graphics.Bitmap;

import android.graphics.BlurMaskFilter;

import android.graphics.Canvas;

import android.graphics.Color;

import android.graphics.Paint;

import android.graphics.PorterDuff;

import android.graphics.Rect;

import android.os.Build;

import android.support.annotation.FloatRange;

import android.util.AttributeSet;

import android.view.ViewGroup;

import android.view.ViewTreeObserver;

import android.widget.FrameLayout;

import com.webappmate.weeassure.R;

/**

* Created by GIGAMOLE on 13.04.2016.

*/

public class ShadowLayout extends FrameLayout {

// Default shadow values

private final static float DEFAULT_SHADOW_RADIUS = 30.0F;

private final static float DEFAULT_SHADOW_DISTANCE = 15.0F;

private final static float DEFAULT_SHADOW_ANGLE = 45.0F;

private final static int DEFAULT_SHADOW_COLOR = Color.DKGRAY;

// Shadow bounds values

private final static int MAX_ALPHA = 255;

private final static float MAX_ANGLE = 360.0F;

private final static float MIN_RADIUS = 0.1F;

private final static float MIN_ANGLE = 0.0F;

// Shadow paint

private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG) {

{

setDither(true);

setFilterBitmap(true);

}

};

// Shadow bitmap and canvas

private Bitmap mBitmap;

private final Canvas mCanvas = new Canvas();

// View bounds

private final Rect mBounds = new Rect();

// Check whether need to redraw shadow

private boolean mInvalidateShadow = true;

// Detect if shadow is visible

private boolean mIsShadowed;

// Shadow variables

private int mShadowColor;

private int mShadowAlpha;

private float mShadowRadius;

private float mShadowDistance;

private float mShadowAngle;

private float mShadowDx;

private float mShadowDy;

public ShadowLayout(final Context context) {

this(context, null);

}

public ShadowLayout(final Context context, final AttributeSet attrs) {

this(context, attrs, 0);

}

public ShadowLayout(final Context context, final AttributeSet attrs, final int defStyleAttr) {

super(context, attrs, defStyleAttr);

setWillNotDraw(false);

setLayerType(LAYER_TYPE_HARDWARE, mPaint);

// Retrieve attributes from xml

final TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.ShadowLayout);

try {

setIsShadowed(typedArray.getBoolean(R.styleable.ShadowLayout_sl_shadowed, true));

setShadowRadius(

typedArray.getDimension(

R.styleable.ShadowLayout_sl_shadow_radius, DEFAULT_SHADOW_RADIUS

)

);

setShadowDistance(

typedArray.getDimension(

R.styleable.ShadowLayout_sl_shadow_distance, DEFAULT_SHADOW_DISTANCE

)

);

setShadowAngle(

typedArray.getInteger(

R.styleable.ShadowLayout_sl_shadow_angle, (int) DEFAULT_SHADOW_ANGLE

)

);

setShadowColor(

typedArray.getColor(

R.styleable.ShadowLayout_sl_shadow_color, DEFAULT_SHADOW_COLOR

)

);

} finally {

typedArray.recycle();

}

}

@Override

protected void onDetachedFromWindow() {

super.onDetachedFromWindow();

// Clear shadow bitmap

if (mBitmap != null) {

mBitmap.recycle();

mBitmap = null;

}

}

public boolean isShadowed() {

return mIsShadowed;

}

public void setIsShadowed(final boolean isShadowed) {

mIsShadowed = isShadowed;

postInvalidate();

}

public float getShadowDistance() {

return mShadowDistance;

}

public void setShadowDistance(final float shadowDistance) {

mShadowDistance = shadowDistance;

resetShadow();

}

public float getShadowAngle() {

return mShadowAngle;

}

@SuppressLint("SupportAnnotationUsage")

@FloatRange

public void setShadowAngle(@FloatRange(from = MIN_ANGLE, to = MAX_ANGLE) final float shadowAngle) {

mShadowAngle = Math.max(MIN_ANGLE, Math.min(shadowAngle, MAX_ANGLE));

resetShadow();

}

public float getShadowRadius() {

return mShadowRadius;

}

public void setShadowRadius(final float shadowRadius) {

mShadowRadius = Math.max(MIN_RADIUS, shadowRadius);

if (isInEditMode()) return;

// Set blur filter to paint

mPaint.setMaskFilter(new BlurMaskFilter(mShadowRadius, BlurMaskFilter.Blur.NORMAL));

resetShadow();

}

public int getShadowColor() {

return mShadowColor;

}

public void setShadowColor(final int shadowColor) {

mShadowColor = shadowColor;

mShadowAlpha = Color.alpha(shadowColor);

resetShadow();

}

public float getShadowDx() {

return mShadowDx;

}

public float getShadowDy() {

return mShadowDy;

}

// Reset shadow layer

private void resetShadow() {

// Detect shadow axis offset

mShadowDx = (float) ((mShadowDistance) * Math.cos(mShadowAngle / 180.0F * Math.PI));

mShadowDy = (float) ((mShadowDistance) * Math.sin(mShadowAngle / 180.0F * Math.PI));

// Set padding for shadow bitmap

final int padding = (int) (mShadowDistance + mShadowRadius);

setPadding(padding, padding, padding, padding);

requestLayout();

}

private int adjustShadowAlpha(final boolean adjust) {

return Color.argb(

adjust ? MAX_ALPHA : mShadowAlpha,

Color.red(mShadowColor),

Color.green(mShadowColor),

Color.blue(mShadowColor)

);

}

@Override

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

super.onMeasure(widthMeasureSpec, heightMeasureSpec);

// Set ShadowLayout bounds

mBounds.set(

0, 0, MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.getSize(heightMeasureSpec)

);

}

@Override

public void requestLayout() {

// Redraw shadow

mInvalidateShadow = true;

super.requestLayout();

}

@Override

protected void dispatchDraw(final Canvas canvas) {

// If is not shadowed, skip

if (mIsShadowed) {

// If need to redraw shadow

if (mInvalidateShadow) {

// If bounds is zero

if (mBounds.width() != 0 && mBounds.height() != 0) {

// Reset bitmap to bounds

mBitmap = Bitmap.createBitmap(

mBounds.width(), mBounds.height(), Bitmap.Config.ARGB_8888

);

// Canvas reset

mCanvas.setBitmap(mBitmap);

// We just redraw

mInvalidateShadow = false;

// Main feature of this lib. We create the local copy of all content, so now

// we can draw bitmap as a bottom layer of natural canvas.

// We draw shadow like blur effect on bitmap, cause of setShadowLayer() method of

// paint does`t draw shadow, it draw another copy of bitmap

super.dispatchDraw(mCanvas);

// Get the alpha bounds of bitmap

final Bitmap extractedAlpha = mBitmap.extractAlpha();

// Clear past content content to draw shadow

mCanvas.drawColor(0, PorterDuff.Mode.CLEAR);

// Draw extracted alpha bounds of our local canvas

mPaint.setColor(adjustShadowAlpha(false));

mCanvas.drawBitmap(extractedAlpha, mShadowDx, mShadowDy, mPaint);

// Recycle and clear extracted alpha

extractedAlpha.recycle();

} else {

// Create placeholder bitmap when size is zero and wait until new size coming up

mBitmap = Bitmap.createBitmap(1, 1, Bitmap.Config.RGB_565);

}

}

// Reset alpha to draw child with full alpha

mPaint.setColor(adjustShadowAlpha(true));

// Draw shadow bitmap

if (mCanvas != null && mBitmap != null && !mBitmap.isRecycled())

canvas.drawBitmap(mBitmap, 0.0F, 0.0F, mPaint);

}

// Draw child`s

super.dispatchDraw(canvas);

}

}

在xml中使用Tag,如下所示:

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_alignParentBottom="true"

android:layout_centerHorizontal="true"

android:layout_gravity="center_horizontal"

app:sl_shadow_color="#9e000000"

app:sl_shadow_radius="4dp">

UPDATE

将以下代码放在资源>>值的attrs.xml中

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值