Android custom ViewGroup implements rounded rectangle menu with arrow

In this article, we will create a rounded rectangle menu with arrows, which is about as long as the following:

It is required that the arrow on the top should aim at the menu anchor point, the menu item press the reverse color, and the menu background color and press color can be configured. The simplest way is to let UX paste a triangle picture up, but on second thought, it's too low, and different resolutions don't fit well. Just customize a ViewGroup! Customizing a ViewGroup is actually very simple. It is basically based on a certain routine.

1、 Defining an attrs.xml is to declare the configurable properties of your custom view, which can be configured freely when used in the future. Seven attributes are declared here: arrow width, arrow height, arrow horizontal offset, fillet radius, menu background color, shadow color and shadow thickness.

2、 Write a class that inherits ViewGroup and initialize these attributes in the constructor. Here, you need to use an obtainstyledattributes () method to obtain a typedarray object, and then you can obtain the corresponding attribute value according to the type. It should be noted that after the object is used up, it needs to explicitly call the recycle () method to release it.

3、 Override the onmeasure() method

The onmeasure () method, as its name suggests, is used to measure the width and height of your ViewGroup.

Let's first consider the height: • first, reserve the height for the arrow and fillet, and add these two items to maxheight • then measure all visible children. ViewGroup has provided the ready-made measurechild() method • next, add the height of the obtained child to maxheight, and of course, consider the margin configuration above and below • in addition, You also need to consider the padding up and down and the height of the shadow • finally, it takes effect through setmeasureddimension()

Consider the width: • first, measure all visible children through the measurechild() method • then compare the width of these children and the margin configuration on the left and right, and select the maximum value • next, add the padding on the left and right, and the shadow width • finally, it takes effect through the setmeasureddimension() setting

Does it look simple? Of course, there are two small problems: 1. When the height is reserved for the fillet, why only one radius is left instead of the upper and lower radii? In fact, this is considered from the display effect. If you leave a radius at the top and bottom, the menu border will be very thick and ugly. When you implement onlayout() later, you will find that when we layout the menu items, we will move up half a radius, so that the border looks much better. 2. Why can child's layout parameters be forcibly converted to marginlayoutparams? In fact, you need to override another method, generatelayoutparams (), to return the type of layout parameter you want. Generally, marginlayoutparams is used. Of course, you can also use other types or user-defined types.

4、 Override the onlayout () method. The onlayout () method, as the name suggests, is used to layout all child views in the ViewGroup. In fact, each view has a layout () method. All we need to do is pass the appropriate left / top / right / bottom coordinates into this method. Here we can see that when we layout the menu items, we raise half a radius, so topoffset only adds half a radius, and the coordinates on the right side only subtract half a radius.

5、 Rewrite the dispatchdraw () method. Here, because we write a ViewGroup container and do not need to draw, we need to rewrite its dispatchdraw () method. If you rewrite a specific view, you can also override its OnDraw () method. The drawing process is divided into three steps: 1. Drawing a rounded rectangle is relatively simple. It is completed by directly calling drawroundrect() of canvas. 2. drawing triangular arrows requires setting up a path according to the configured properties, and then calling Canvas's drawPath () to complete the rendering. 3. Draw the menu shadow. To put it bluntly, it means to change the color and draw a rounded rectangle with a slight offset. Of course, it also has a blur effect. To obtain the blur effect, you need to configure it through paint's setmaskfilter() and turn off the hardware acceleration of the layer, which is clearly stated in the API. In addition, you also need to set the overlap mode of the source image and the target image. Obviously, the shadow should be stacked behind the menu. According to the figure below, we need to select DST_ Over mode.

See the code for other details:

6、 Reference the custom ViewGroup in the layout XML. So far, the implementation of the custom ViewGroup has been completed. Let's use it in the project! There are two small differences between using custom ViewGroup and using system ViewGroup components: first, specify the complete package name, otherwise it will be reported that the component cannot be found during operation. 2、 When configuring custom attributes, you need to specify another namespace to avoid confusion with the default Android namespace. For example, a new app namespace is specified here to reference custom attributes.

7、 Referencing the layout XML in the code is no different from referencing the normal layout XML. Here, the layout XML is specified when creating the pop-up menu. See the example code for details. So far, even if a complete custom ViewGroup process has been completed, some complex custom components may be written later, but everything changes. The basic principles and steps are the same. This article is to offer some help to friends who need to customize the ViewGroup.

Source code download: http://xiazai.jb51.net/201607/yuanma/ArrowRectangleMenu (jb51.net).rar

The above is the whole content of this article. I hope it will be helpful to your study, and I hope you can support programming tips.

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>