Define your own ViewGroup and your own ViewGroup

Source: Internet
Author: User

Define your own ViewGroup and your own ViewGroup

Respect originality: Http://blog.csdn.net/yuanzeyao/article/details/40264433

I haven't written any articles for a long time. Now I can summarize some knowledge over the weekend to help me better understand it. Today I will learn how to implement custom ViewGroup.

Commonly used layout, FrameLayout, and RelativeLayout layout in Android... These la s are inherited from ViewGroup. With these la S, we can almost develop all interfaces in Android. However, for some common and complex la s, we will spend a lot of time on repetitive work. Can we imitate these basic la S and implement our own la s based on our own needs, what can I do if I need it in the future? Of course.


Layout similar to playing cards


In the landlords game, we often encounter a layout similar to this. I will call this layout cascade layout. This layout can be made using RelativeLayout and margin, however, it is not very convenient. Today we will explain this requirement in the context of custom ViewGroup.

Before learning about custom la S, you 'd better first understand how Android la s seem to have been painted. I suggest you read about them: they are all articles on the official website.
1. http://developer.android.com/guide/topics/ui/how-android-draws.html
2. http://developer.android.com/reference/android/view/ViewGroup.html
3. http://developer.android.com/reference/android/view/ViewGroup.LayoutParams.html


Through the above articles, we need to understand the knowledge:
1. The layout is composed of two processes: the measurement process and the layout process. The measurement process is completed using the measure (int, int) method. After the traversal is completed, the size of all views is determined, and the layout method is used to complete the layout process. The size of the View determines where the View is placed, however, the measure and layout methods in the source code are of the final type, so we cannot rewrite them. The final method is defined to avoid developers' damage to the layout painting process, however, the measurement and layout details can be implemented by rewriting onMeasure and onLayout.


2. ViewGroup
As I mentioned earlier, all la s in Android are inherited from ViewGroup, and ViewGroup is a View container. We can place the View of the task in it, we can define it through onMeasure and onLayout. onMeasure is called in measure, while onLayout is called in layout.


3. ViewGroup. LayoutParams


This class is mainly used by View to tell its parent container how to display it, such as width, height, and center. The two most important parameters in ViewGroup. LayoutParams are width and height. If you want to use the margin attribute, you must use the ViewGroup. MarginLayoutParams class, which inherits from ViewGroup. LayoutParams. Added support for the margin attribute. If you want to add more attributes, you can define a LayoutParams class to add the desired attributes. In fact, the layout such as LinearLayout is inherited from the ViewGroup. marginLayoutParams and add the required attributes.




Implement your own layout CascadeLayout. java


/*** Custom Layout for playing card effect * com. myviewgroup. cascadeLayout * @ author yuanzeyao <br/> * create at October 19, 2014 4:15:42 */public class CascadeLayout extends ViewGroup {/*** horizontal offset distance */private int horizontal_space; /*** vertical offset distance */private int vertical_space; public CascadeLayout (Context context) {super (context);} public CascadeLayout (Context context Context, AttributeSet attrs, int defStyle) {super (context, attrs, defStyle); initAttribute (context, attrs);} public CascadeLayout (Context context, AttributeSet attrs) {super (context, attrs); initAttribute (context, attrs);}/*** assign values to horizontal_space and vertical_space Based on the attributes in the xml file * @ param context * @ param attrs */private void initAttribute (Context context, AttributeSet attrs) {TypedArray a = context. obtainStyledAttributes (attrs, R. styleable. cascadeLayout); horizontal_space =. getDimensionPixelSize (R. styleable. cascadeLayout_horizontal_space, this. getResources (). getDimensionPixelSize (R. dimen. cascade_horizontal_spacing); vertical_space =. getDimensionPixelSize (R. styleable. cascadeLayout_vertical_space, this. getResources (). getDimensionPixelSize (R. dimen. cascade_vertical_spacing);. recycle ();}/*** onMeasure is called in measure. The parameters are the width and height of CascadeLayout */@ Override protected void onMeasure (int widthMeasureSpec, int heightMeasureSpec) {// use measureChildren to measure all the children. You can also use the for loop and get out of it. Get a measurechild function to measure measureChildren (widthMeasureSpec, heightMeasureSpec ); // assign the width and height to the measureWidth and measureHeight variables setMeasuredDimension (widthMeasureSpec, heightMeasureSpec) of CascadeLayout );} /*** add how to arrange the logic of each View in this function */@ Override protected void onLayout (boolean changed, int l, int t, int r, int B) {for (int I = 0; I <getChildCount (); I ++) {// traverse the child node View child = getChildAt (I) in sequence ); // MarginLayoutParams mlp = (MarginLayoutParams) child. getLayoutParams (); LayoutParams lp = child. getLayoutParams (); // calculate the distance between the left and top: int left = horizontal_space * I; int top = vertical_space * I; child. layout (left, top, left + child. getMeasuredWidth (), top + child. getMeasuredHeight () ;}}/*** rewrite the LayoutParams Generation Method */@ Override protected LayoutParams generateLayoutParams (LayoutParams p) {// return super. generateLayoutParams (p); // return new ViewGroup. marginLayoutParams (p. width, p. height); return new ViewGroup. layoutParams (p. width, p. height) ;}@ Override public LayoutParams generateLayoutParams (AttributeSet attrs) {// return super. generateLayoutParams (attrs); // return new ViewGroup. marginLayoutParams (this. getContext (), attrs); return new ViewGroup. layoutParams (this. getContext (), attrs );}}

In CascadeLayout, we define two attributes, horizontal_space and vertical_space, which are used to record the vertical distance and horizontal distance before each sub-View in the layout. They are all initialized in the constructor. Since attributes are added, the attrs. xml file is defined in res/values.

<?xml version="1.0" encoding="utf-8"?><resources>    <declare-styleable name="CascadeLayout">        <attr name="horizontal_space" format="dimension"></attr>        <attr name="vertical_space" format="dimension"></attr>    </declare-styleable></resources>

Use CascadeLayout in the layout File


<com.myviewgroup.CascadeLayout    xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:cascade ="http://schemas.android.com/apk/res/com.myviewgroup"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    cascade:horizontal_space="40dip"    cascade:vertical_space="40dip"       >       <View         android:layout_width="200dip"        android:layout_height="200dip"        android:background="@color/view1"        />         <View         android:layout_width="200dip"        android:layout_height="200dip"        android:background="@color/view2"        />           <View         android:layout_width="200dip"        android:layout_height="200dip"        android:background="@color/view3"        /></com.myviewgroup.CascadeLayout>

The running effect is as follows:



Custom LayoutParams in CascadeLayout, we use ViewGroup. layoutParams class, but this class only has the width and height attributes. If we want to add other attributes, we need to define our own LayoutParams class.
Next we will customize our own LayoutParams class. This class inherits ViewGroup. MarginLayoutParams, so my custom LayoutPrams has the margin attribute.


The following LayoutParams class is defined in CascadeLayout:


Public static class LayoutParams extends ViewGroup. marginLayoutParams {/*** defines the vertical offset distance, which can overwrite the vertical_space attribute */private int layout_vertical_spacing in CascadeLayout; public LayoutParams (Context c, AttributeSet attrs) {super (c, attrs); TypedArray a = c. obtainStyledAttributes (attrs, R. styleable. cascadeLayout_LayoutParams); try {layout_vertical_spacing =. getDimensionPixelSize (R. styleable. cascadeLayout_LayoutParams_layout_vertical_spacing,-1);} finally {. recycle () ;}} public LayoutParams (int width, int height) {super (width, height );}}
This LayoutParams supports the layout_vertical_spaceing attribute.
Well, let's write it here first. If you have any questions, please leave a message...



Custom ViewGroup

In the onMeasure method of ViewGroup, call measure (MeasureSpec. UNSPECIFIED, MeasureSpec. UNSPECIFIED) method, and then call TextView's getMeasuredHeight () to get the TextView height. Call TextView's getMeasuredWidth () to get the TextView width.
 
Custom viewgroup

After you click the blank space, onInterceptTouchEvent returns false when the event is down, and then submits the event to the sub-view for processing. Because there is no sub-view in the blank space, the event is returned to the onTouchEvent callback of the viewgroup, however, I returned false at the down event of the onTouchEvent of viewgroup, so the subsequent move and up events are submitted to the parent view of this viewgroup for processing, and viewgroup itself cannot receive the event. This problem occurs. The solution is to return true at the down event of onTouchEvent in viewgroup. Haha, I answered myself.
 

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.