Displayobject has a render event that will be triggered before the displaylist is re-painted. This gives us the chance to perform the last operation before the re-painting.
Each time displayobject is required to trigger render, it must be called once.
Stage. invalidate ();
The following is a small example to illustrate the specific usage.
Suppose we want to write a list component. This component has the additem () method used to add list items and remvoeitem ()
Methods are used to delete list items. Of course, additemat (), removeitemat () and other methods may also exist. After these methods are called
Rearrange rows.
First, we implement a list class to display list items.
In the list class, there are additem () and removeitem ()
These two methods are provided to external calls for adding and deleting list items. In addition to adding/deleting list items, you must call a method to sort list items again, layoutcontents ().
The key is that the more layoutcontents () calls, the fewer the number of calls, the higher the efficiency of course. If it is a conventional practice, it is similar to this:
Code
Public
Function additem (item: displayobject ):
Void
{
Addchild (item );
Layoutcontents ();
}
After adding items, rearrange the list
The source code of the List class is as follows:
Code
Package
{
Import
Flash. display. displayobject;
Import
Flash. display. Sprite;
Import
Flash. Events. event;
Public
Class
List
Extends
Sprite
{
Public
Function additem (item: displayobject ):
Void
{
Addchild (item );
Layoutcontents ();
}
Public
Function removeitem (item: displayobject ):
Void
{
If
(Contains (item ))
{
Removechild (item );
Layoutcontents ();
}
}
//
Arrange internal projects by any sort algorithm
Protected
Function layoutcontents ():
Void
{
Trace (
"
Do Layout
"
);
Var y: Number
=
0
;
VaR num:
Int
=
Numchildren;
For
(Var I:
Int
=
0
; I
<
Num; I
++
)
{
VaR child: displayobject
=
Getchildat (I );
Child. x
=
0
;
Child. Y
=
Y;
Y
+ =
Child. Height
+
2
;
}
}
}
}
This program seems to be okay, but there is a problem with efficiency.
If additem is called only once, no problem. What if it is called 10 times?
The layoutcontents () of the first nine times are not necessary. Only the tenth time is really needed, and the efficiency of the program is reduced.
Let's give it a try.
First, a simple listitem is required.
Code
Package
{
Import
Flash. display. shape;
Public
Class
Listitem
Extends
Shape
{
Public
Function listitem ()
{
Super
();
Graphics. beginfill (
0xff6600
);
Graphics. drawrect (
0
,
0
,
30
,
16
);
Graphics. endfill ();
}
}
}
Then test
Code
Package
{
Import
Flash. display. Sprite;
Public
Class
Listtest
Extends
Sprite
{
Public
Function listtest ()
{
VaR list: List
=
New
List ();
Addchild (list );
List. additem (
New
Listitem ());
List. additem (
New
Listitem ());
List. additem (
New
Listitem ());
}
}
}
We can see that the output of do layout three times indicates that layoutcontents has been executed three times, and the first two times are redundant.
Now, the solution is to use the render event.
Because the render event is triggered before the display list is updated within the current frame, the list items are sorted after the render event is triggered, you can ensure that the arrangement method is called once after any addition or deletion operation, thus improving the efficiency.
To do this, you only need to make some changes to the List class. First, you must listen to the render event. We can only listen to the render event of the stage object, in this way, you can create an independent repaintmanger to manage the repainting of all components (refer to the repaintmanager class of aswing ).
After the render event is triggered, make the necessary adjustments. To trigger the render event, you must first call stage. invalidate ()
Therefore, you must execute this method once each time you add or delete a list project, that is:
Code:
Code
Public
Function additem (item: displayobject): voide
{
//
Stage. invalidate ()
}
Because it is a listener stage render event, after the delete operation is added, a tag is required to indicate that the list has been changed and needs to be rearranged after the render event. If the tag is
False, so even if the render is triggered, it is not arranged because the render event of the stage may be caused by the re-painting of other child in the stage.
Stage render is triggered.
The following is the list Code after modification.
Code
Package
{
Import
Flash. display. displayobject;
Import
Flash. display. Sprite;
Import
Flash. Events. event;
Public
Class
List
Extends
Sprite
{
Private
VaR changed: Boolean;
Public
Function list ()
{
Super
();
Addeventlistener (event. added_to_stage, _ addtostage );
}
Public
Function additem (item: displayobject ):
Void
{
Addchild (item );
Requirelayout ();
}
Public
Function removeitem (item: displayobject ):
Void
{
If
(Contains (item ))
{
Removechild (item );
Requirelayout ();
}
}
Private
Function requirelayout ():
Void
{
Changed
=
True
;
If
(Stage
! =
Null
)
Stage. invalidate ();
}
//
Arrange internal projects by any sort algorithm
Protected
Function layoutcontents ():
Void
{
Trace (
"
Do Layout
"
);
Var y: Number
=
0
;
VaR num:
Int
=
Numchildren;
For
(Var I:
Int
=
0
; I
<
Num; I
++
)
{
VaR child: displayobject
=
Getchildat (I );
Child. x
=
0
;
Child. Y
=
Y;
Y
+ =
Child. Height
+
2
;
}
}
Private
Function _ addtostage (E: Event ):
Void
{
Stage. addeventlistener (event. Render, _ render );
If
(Changed)
Stage. invalidate ();
}
Private
Function _ render (E: Event ):
Void
{
If
(Changed)
{
Layoutcontents ();
Changed
=
False
;
}
}
}
}
When we run listtest again, do layout
Output only once.
That's the content. Of course, you may say that it doesn't need to be so complicated to do this. As long as the layoutcontents method is exposed, the caller needs to call layoutcontents () after all the operations are called ().
In
In this example, yes, but when the situation is complex, the user must call the update method for each operation. This is not a good solution. Imagine if
Flash Player does not process displayobject display for us. Instead, after addchild/removechild, we need to call
Using the underlying method of Flash Player to display what we need is obviously not good.