如何简单实现内凹阴影标题栏效果
先上效果图(支持自定义扩展格数,背景和阴影颜色以及圆角大小)ps:暂不支持滑动动画效果,后期会加上。
实现原理(图解):
自定义了一个layout布局在布局内画框,位置要超出屏幕之外(为了达到效果,投机的一个办法哈哈哈哈),空出底部间隙是为了阴影的展示。
如图的层次结构,我就不解释了这么简单,应该都能看懂哈哈哈哈哈。源码下面附上。
使用的时候直接setmPosition()就ok了。
源码:
/** * 内凹阴影标题栏 * * @author Sago丶 * @date 2017/11/17 */ public class ShadowLinearLayout extends LinearLayout { private Paint mPaint, mPaint2; private RectF mRectF, mRectF2; private int mPosition = 2; private int mLyoutColumn;//平分几格 private int mRadius;//圆角 private int mShadowColor;//阴影颜色 private int mLayoutBackgroundColor;//布局背景颜色 public ShadowLinearLayout(Context context) { super(context); init(); } public ShadowLinearLayout(Context context, @Nullable AttributeSet attrs) { super(context, attrs); TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.ShadowLinearLayout); mLyoutColumn = typedArray.getInteger(R.styleable.ShadowLinearLayout_lyout_column, 4); mRadius = typedArray.getInteger(R.styleable.ShadowLinearLayout_shadow_radius, 20); mShadowColor = typedArray.getColor(R.styleable.ShadowLinearLayout_shadow_color, ContextCompat.getColor(MyApplication.getInstance(), R.color.red_FFF7DEDA)); mLayoutBackgroundColor = typedArray.getColor(R.styleable.ShadowLinearLayout_layout_background_color, ContextCompat.getColor(MyApplication.getInstance(), R.color.white_FFFFFF)); typedArray.recycle(); init(); } public ShadowLinearLayout(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); } @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) public ShadowLinearLayout(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); init(); } void init() { setPadding(0, 0, 0, 15); setBackgroundColor(Color.WHITE); mPaint = new Paint(); mPaint2 = new Paint(); //硬件加速 setLayerType(LAYER_TYPE_SOFTWARE, mPaint); setLayerType(LAYER_TYPE_SOFTWARE, mPaint2); mPaint.setColor(mLayoutBackgroundColor); mPaint2.setColor(mLayoutBackgroundColor); // 设定阴影(柔边, X 轴位移, Y 轴位移, 阴影颜色) mPaint.setShadowLayer(10, 5, 5, mShadowColor); mPaint2.setShadowLayer(10, -5, 5, mShadowColor); mPaint.setAntiAlias(true);//锯齿不显示 mPaint2.setAntiAlias(true);//锯齿不显示 mRectF = new RectF();//左边RectF对象 mRectF2 = new RectF();//右边RectF对象 } public void setmPosition(int mPosition) { this.mPosition = mPosition; invalidate(); } @Override protected void onDraw(Canvas canvas) { mRectF.top = 0 - mRadius; //上边 mRectF.left = 0 - mRadius;//左边 mRectF.bottom = this.getMeasuredHeight() - 15;//下边 mRectF.right = this.getMeasuredWidth() / mLyoutColumn * (mPosition - 1);//右边 mRectF2.top = 0 - mRadius; //上边 mRectF2.bottom = this.getMeasuredHeight() - 15; //下边 mRectF2.right = this.getMeasuredWidth() + 15;//右边 mRectF2.left = this.getMeasuredWidth() / mLyoutColumn * (mPosition);//左边 if (mPosition != 1) { //左边 canvas.drawRoundRect(mRectF, mRadius, mRadius, mPaint); //绘制圆角矩形 } if (mPosition != mLyoutColumn) { //右边 canvas.drawRoundRect(mRectF2, mRadius, mRadius, mPaint2); //绘制圆角矩形 } super.onDraw(canvas); } }
自定义样式代码:
<resources> <declare-styleable name="ShadowLinearLayout"> <attr name="lyout_column" format="integer" /> <attr name="shadow_radius" format="integer" /> <attr name="layout_background_color" format="color" /> <attr name="shadow_color" format="color" /> </declare-styleable> </resources>
好了,整体实现就是这样,很简单的原理希望对大家有帮助,各位大佬不喜勿喷,有不妥之处还请指点。