The General Fillet Label control is implemented using XML to set shape. But suppose we want to make a more powerful universal fillet control that doesn't require the user to care about the rounded corners, just set the background to be able.
How should it be done? This will need to set the background into a picture, and then the picture processed into rounded corners, and then set to the background. Basic ideas such as the following code:
Bitmap Bitmap = ((bitmapdrawable) Getbackground ()). Getbitmap (); Bitmapshader Bitmapshader = new Bitmapshader (bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP); Matrix matrix = new Matrix (); Bitmapshader.setlocalmatrix (matrix);//Set zoom float scale = Math.max (getwidth () * 1.0f/bmp.get Width (), getheight () * 1.0f/bmp.getheight ()); Mbitmappaint.setshader (Bitmapshader); Canvas canvas = new canvas (bitmap), if (Mradius > 0) {canvas.drawroundrect (Mdrawablerect, Mradius, Mradius, Mbitmapp aint);} else {canvas.drawrect (mdrawablerect, mbitmappaint);} SetBackground (New bitmapdrawable (bitmap));
The above code takes out the background image and draws a fillet with the shader (assuming that the background color is color, you need to do a colordrawable conversion bitmap). This will force the textview of a rounded background to be implemented. You can also use Xfermode to do a lot of online articles. Do not repeat it.
Now that's the question, suppose my background is shapdrawable (xml:shape) or statelistdrawable (selector)? There is no way, shapedrawable can also do their own definition, but statelistdrawable open can define their own interface very little, completely no way.
Also, suppose we need to set drawableleft or Drawableright. will also cover up the background. The fillet is gone.
It is also assumed that fillets are also set for these compound drawable. And the radius of the fillet cannot be the same as the radius of the main space. Otherwise it will be different because of the wide height. The rounded corners of the drawing will also be different.
This method is too complex.
Give!
Is there any simple way to do it? We can use Xfermode to make a fuss about the basemap of the artboard.
Here's how the control is implemented for Android (which is expected to be almost identical to other OS).
All the things we see on the display. is actually a piece of memory, placed in a memory buffer called framebuffer. This buffer is in pixels, with a certain color rule, which gives us a variety of things to see on the screen. Android uses a system called surface to manage this piece of framebuffer, the so-called control, in fact, according to certain rules, tell Surface system How to draw my area. This will give us a concrete picture of what we want to see. About the details, too many things, and then slowly say.
Continue to the question of implementing the fillet control.
All the controls in Android give us a way to call OnDraw (), which is the canvas. Canvas is what the canvas means, what we draw on this piece of cloth. Is the appearance of the space.
This method is called in View.draw () to tell the system how to draw the control. For example, TextView inside the OnDraw is basically some writing. Set the color, font of operation, ImageView is to use drawable to draw canvas operation.
Android offers a variety of ways to make it easier for us to manipulate this canvas. If we want to achieve rounded corners, can we do something about this canvas? We can xfermode to draw an oval bitmap on top of the original, and then just keep the part that they intersect. Remove the disjoint part, and the rounded corner control is done? With regard to Xfermode, there is a classic diagram of deep moving images that illustrate how to use:
What we want to do, for example, is:
The code that generates the masking diagram is as follows:
Private Bitmap Generatemaskbitmap () { Bitmap Bitmap = Bitmap.createbitmap (GetWidth (), GetHeight (), Bitmap.Config.ARGB_8888); Canvas Bitmapcanvas = new canvas (bitmap); RECTF r = new RECTF (0, 0, getwidth (), getheight ()); Rect rect = new Rect (0, 0, getwidth (), getheight ()); Paint Bitmappaint = new paint (); Bitmappaint.setalpha (0); Bitmappaint.setcolor (color.transparent); Bitmapcanvas.drawrect (rect, bitmappaint); Bitmappaint.reset (); Bitmappaint.setstyle (Paint.Style.FILL); Bitmappaint.setantialias (true); Bitmappaint.setcolor (color.white); Bitmapcanvas.drawroundrect (R, Mradius, Mradius, bitmappaint); return bitmap;}
OnDraw code such as the following:
@Overrideprotected void OnDraw (canvas canvas) { super.ondraw (canvas); if (Mradius > 0) { Bitmap Bitmap = Generatemaskbitmap (); Paint Bitmappaint = new paint (); Bitmappaint.setxfermode (New Porterduffxfermode (PorterDuff.Mode.DST_IN)); Canvas.drawbitmap (Bitmap, 0f, 0f, bitmappaint); Bitmap.recycle (); }}
but this is not ok ah. With this control, this is the case:
<com.example.widget.tagtextview android:layout_width= "wrap_content" android:layout_height= "Wrap_ Content " android:background=" #ff0000 " android:text=" Oh Good " app:border_radius=" 5DP " />
Why is that? The fillet is there, but it is black around. Feel the code is no problem, then went to the internet search. Xfermode has some limitations when hardware acceleration is turned on (http://developer.android.com/guide/topics/graphics/hardware-accel.html#unsupported) , this problem is expected to be one of the limitations. As a result, hardware acceleration is turned off in this widget, and after another build, the discovery remains unchanged. I'm a little dizzy, for it's not the other color. It is black, and my maskbitmap is set white.
The explanation can only be one: My background does not set the alpha value, and no matter what the transparency, the deleted color becomes the color-free State. Let me set a background color with transparency try:
<com.example.widget.tagtextview android:layout_width= "wrap_content" android:layout_height= "Wrap_ Content " android:background=" #feff0000 " android:text=" Oh Good " app:border_radius=" 5DP " />
Yes, I can. In this way, no matter what the control does, it must be rounded around the drawing.
Summarize Although this is a mandatory fillet, it is very limited. Assuming that the canvas itself does not have a transparent channel, the rounded corners that are cleared will turn black.
I have tried to draw a transparent color in advance of the control, but still no use. The detailed reason is not yet known. Before I could go into it. Let's say a buddy knows. It's better to share the reason. Recommendation: the recommendation for such a requirement is to create a factory to generate some well-defined tag controls. This is more in line with the Android specification. You can also manage the various tag controls very well.
Code Link: http://download.csdn.net/detail/yutao52shi/8972539
An alternative implementation of the Android fillet tag control