ShadowLayout and shadowlayout

Source: Internet
Author: User

ShadowLayout and shadowlayout
Effect


The second and third images have a shadow effect. Do you think the stereoscopic effect is strong and the image is floating on the screen. This effect can also be achieved using the CardView control in the extended package provided by Google, and this article will bring you to achieve this effect.

Principle

After careful observation, we can find that there are shadow and no shadow effects. In fact, the difference is that the shadow effect is drawn under the image, the image size remains unchanged. So what we need to do is to draw a shadow for the Child View. How do I draw the shadow part? Here is a difficult point for achieving the entire effect. The shadow part is actually a bitmap image, and the next job is to generate a bitmap image with this effect, and determine the position of the bitmap image.

Implementation

1. Generation of bitmap images with shadow effects
The simplest way is to ask the artist to make one and we will convert it. 9. This is a method. Another method is to use code to generate such a bitmap. To achieve this effect, we need to use an attribute in the Paint brush.

public MaskFilter setMaskFilter(MaskFilter maskfilter) {//...}

This MaskFilter has a subclass BlurMaskFilter to achieve this effect. Generally, it is called the glass effect. The implementation of this class requires two parameters

public BlurMaskFilter(float radius, Blur style) {        //...    }

Radius: the distance of the gradient effect.

Style: mode. Four middle modes are available.

    public enum Blur {        /**         * Blur inside and outside the original border.         */        NORMAL(0),        /**         * Draw solid inside the border, blur outside.         */        SOLID(1),        /**         * Draw nothing inside the border, blur outside.         */        OUTER(2),        /**         * Blur inside the border, draw nothing outside.         */        INNER(3);        Blur(int value) {            native_int = value;        }        final int native_int;    }

What exactly are these models? Let's take a look at the figure below.

In the form

    public void drawRect(RectF rect, Paint paint) {        ;    }

It should be clear that this figure is annotated with the above several modes.
Note that when we draw a rectangle, if this blur effect is not set, the size of the drawing is the size of the rectangle. If the blur effect is drawn, then the image size needs to be added with the radius when the BlurMaskFilter is instantiated, that is, the gradient distance.
The code for creating a bitmap is as follows:

// Set the style mPaint of the paint brush. setStyle (Paint. style. FILL); // set the blur effect of the paint brush mPaint. setMaskFilter (new BlurMaskFilter (BLUR_WIDTH, BlurMaskFilter. blur. NORMAL); // set the paint brush color mPaint. setColor (Color. BLACK); // create a bitmap image mShadowBitmap = Bitmap. createBitmap (mOriginRect. width (), mOriginRect. height (), Bitmap. config. ARGB_8888); // bind it to the Canvas canvas Canvas = new canvas (mShadowBitmap); // Let the Canvas pan. Why translate it here? You can see the canvas after reading the previous picture. translate (BLUR_WIDTH, BLUR_WIDTH); // draw the shadow canvas. drawRoundRect (mDesRecF, mRadius, mRadius, mPaint );

2. determine the position of the bitmap image
The bitmap is drawn on

protected void dispatchDraw(Canvas canvas) {//...}

Note that bitmap must be drawn first in each region.

super.dispatchDraw(canvas);

Why? It's easy to understand, because super. dispatchDraw (canvas) is a distributed rendering mechanism. The painting of all child classes of Layout must be distributed through it. If a child class is drawn first, the bitmap shadow part is displayed on the Child class, will overwrite the subclass.
The Code is as follows:

@ Override protected void dispatchDraw (Canvas canvas) {int N = getChildCount (); for (int I = 0; I <N; I ++) {View view = getChildAt (I); if (view. getVisibility () = GONE | view. getVisibility () = INVISIBLE | view. getAlpha () = 0) {continue;} int left = view. getLeft (); int top = view. getTop ();/* Save the canvas position */canvas. save ();/* Pan the canvas */canvas. translate (left + (1-mDepth) * 80, top + (1-mDepth) * 80);/* set the transparency of the Shadow paint brush */mAlphaPaint. setAlpha (int) (125 + 100 * (mDepth);/* obtain the shadow width */mDesRecF. right = view. getWidth ();/* obtain the shadow height */mDesRecF. bottom = view. getHeight ();/* draw shadow */canvas. drawBitmap (mShadowBitmap, mOriginRect, mDesRecF, mAlphaPaint);/* restore paint brush */canvas. restore ();} super. dispatchDraw (canvas );}

By now, the Layout of the entire effect is completed, and the code is very concise. If there are no more than 100 lines of code, simply paste them all.

/*** Created by moon. zhong on 2015/3/25. */public class ShadowLayout extends RelativeLayout {private float mDepth = 0.5f; private Bitmap mShadowBitmap; private Paint mPaint = new Paint (Paint. ANTI_ALIAS_FLAG); private final int BLUR_WIDTH = 5; private final Rect mOriginRect = new Rect (150, 150 + 2 * BLUR_WIDTH, + 2 * BLUR_WIDTH ); private RectF mDesRecF = new RectF (0,0, 150,150); private int mRadius = 6; private Paint mAlphaPaint; public ShadowLayout (Context context) {super (context); initView (context );} public ShadowLayout (Context context, AttributeSet attrs) {super (context, attrs); initView (context) ;}public ShadowLayout (Context context, AttributeSet attrs, int defStyleAttr) {super (context, int, attrs, defStyleAttr); initView (context);} private void initView (Context context) {setWillNotDraw (false); // set the style mPaint of the paint brush. setStyle (Paint. style. FILL); // set the blur effect of the paint brush mPaint. setMaskFilter (new BlurMaskFilter (BLUR_WIDTH, BlurMaskFilter. blur. NORMAL); // set the paint brush color mPaint. setColor (Color. BLACK); // create a bitmap image mShadowBitmap = Bitmap. createBitmap (mOriginRect. width (), mOriginRect. height (), Bitmap. config. ARGB_8888); // bind it to the Canvas canvas Canvas = new canvas (mShadowBitmap); // Let the Canvas pan. Why translate it here? You can see the canvas after reading the previous picture. translate (BLUR_WIDTH, BLUR_WIDTH); // draw the shadow canvas. drawRoundRect (mDesRecF, mRadius, mRadius, mPaint); mAlphaPaint = new Paint (Paint. ANTI_ALIAS_FLAG);} public void setDepth (float depth) {mDepth = depth; invalidate () ;}@ Override protected void dispatchDraw (Canvas canvas) {int N = getChildCount (); for (int I = 0; I <N; I ++) {View view = getChildAt (I); if (view. getVisibility () = GONE | view. getVisibility () = INVISIBLE | view. getAlpha () = 0) {continue;} int left = view. getLeft (); int top = view. getTop ();/* Save the canvas position */canvas. save ();/* Pan the canvas */canvas. translate (left + (1-mDepth) * 80, top + (1-mDepth) * 80);/* set the transparency of the Shadow paint brush */mAlphaPaint. setAlpha (int) (125 + 100 * (mDepth);/* obtain the shadow width */mDesRecF. right = view. getWidth ();/* obtain the shadow height */mDesRecF. bottom = view. getHeight ();/* draw shadow */canvas. drawBitmap (mShadowBitmap, mOriginRect, mDesRecF, mAlphaPaint);/* restore paint brush */canvas. restore ();} super. dispatchDraw (canvas );}}

Let's take a look at the dynamic

Summary

The overall implementation is not particularly difficult. The most important thing is

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

When creating a bitmap, bitmap must be twice the size of BLUR_WIDTH, that is

private final Rect mOriginRect = new Rect(0,0,150+ 2*BLUR_WIDTH,150+2*BLUR_WIDTH) ;

I have already explained why.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.