Các bước để xây dựng một Flex component

Tổng quan

Nếu bạn đã từng xây dựng các ứng dụng nhiều Form như các ứng dụng về tài chính, ngân hàng, bảo hiểm … trên nền Flash thì bạn đã hiểu sự vất vả của các lập trình viên. Đơn giản là Flash sinh ra không để dành cho các ứng dụng đó. Đó là lý do vì sao Flex được ra đời với hàng tá các component như Combox, DataGird, Tree … và đặc biệt là khả năng binding dữ liệu. Tuy hỗ trợ nhiều nhưng không phải lúc nào các components của Flex có thể đáp ứng hết được yêu cầu của bạn. Chính vì vậy, bạn cần phải tạo ra các component của riêng mình.

Có 2 cách tiếp cận để tạo ra 1 component tùy biến. Thông thường, bạn tạo ra một component từ các component có sẵn của Flex – component tổ hợp. Ví dụ bạn tạo ra 1 form đăng ký từ 1 Panel, trong đó có các Combo, TextInput …. Cách thứ 2 là tạo ra một component bằng cách subclassing – kế thừa từ lớp UIComponent của Flex. Bài viết sau trình bày những bước cơ bản để xây dựng một component tùy biến (custom component) theo cách thứ 2 – kế thừa từ lớp UIComponent.

Cơ chế rendering của custom component

Công việc đầu tiên cần làm tất nhiên là tạo ra 1 lớp kế thừa từ mx.core.UIComponent. Lớp này có một số phương thức trong phạm vi protected mà bạn cần phải override khi xây dựng lớp Component của mình là commitProperties(), measure(), layoutChrome(), updateDisplayList(). Ngoài ra khi component của bạn có các sự thay đổi về kích thước, vị trí hay nội dung thì cũng cần phải xử lý một số event về kích thước, các thuộc tính cũng như cách render hay layout nội dung component. Tùy thuộc vào sự thay đổi mà  component cũng cần phải gọi các phương thức “invalidation – bất hợp lệ hóa” như invalidateSize(), invalidateProperties(), hoặc invalidateDisplayList(). Khi component của bạn thực hiện các phương thức trên, Flex sẽ tự động thực hiện các phương thức xử lý tương ứng như

invalidateProperties() gọi commitProperties();
invalidateSize() gọi measure();
invalidateDisplayList() gọi layoutChrome() và updateDisplayList();

Các phương thức commitProperties(), layoutChrome(),  measure()

commitProperties ()

Là phương pháp đầu tiên được gọi khi Flash Player sẵn sàng để bắt đầu vẽ một component Flex.

Nếu component có bất kỳ thay đổi nào trên các thuộc tính của nó, như chiều rộng, chiều cao, độ sâu, màu sắc …. thì commitProperties () là nơi bạn cần thực hiện các tính toán cần thiết dựa trên những đặc tính thay đổi. Nếu không có commitProperties (), bạn sẽ phải thực hiện việc tính toán một cách thủ công bất cứ khi nào bất cứ khi nào có sự thay đổi trên các thuộc tính.

layoutChrome ()

Được sử dụng để xác định biên giới (hay chính là khái niệm border) xung quanh component của bạn.

measure()

Cho phép bạn có thể tính được kích thước của các component. Phương thức này được sử dụng để tính toán kích thước tối thiểu và kích cỡ mặc định của các component.

updateDisplayList ()

Trong phương thức này bạn sẽ vẽ component lên màn hình. Để phương thức này được gọi, bạn phả gọi phương thức được thừa kế invalidateDisplayList () trước đó. Tuy nhiên đừng đặt các đoạn code vẽ bất cứ nơi nào khác hơn trong phương thức này, trừ khi bạn có ý định làm một cái gì đó đặc biệt như animation hoặc game.

Template nào cho một custom component ?

Đoạn mã dưới đây trình bầy một cách tóm lược cách viết một lớp Component kế thừa từ UIComponent với các phương thức trình bày ở trên.

package org.catapult.mycomponents{

    import mx.core.UIComponent;
    import flash.geom.Matrix;
    import flash.display.GradientType;
    import flash.display.SpreadMethod;
    import flash.display.InterpolationMethod;

    public class Chart extends UIComponent {
        private var _barWidth : Number = 20;
        private var _value : Number;

        public function get value() : Number {
            return _value;
        }

        public function set value(value: Number) : void {
            this._value = value;
            invalidateProperties();
            invalidateSize();
            invalidateDisplayList();
        }

        override protected function measure() : void {
            measuredHeight    = _value;
            measuredMinHeight = _value;
            measuredWidth     = _barWidth;
            measuredMinWidth  = _barWidth;
        }

        override protected function updateDisplayList( unscaledWidth:Number, unscaledHeight:Number):void {
            super.updateDisplayList(unscaledWidth, unscaledHeight);
            graphics.clear();
            graphics.beginFill(0xFFFF00);
            graphics.drawRect(0, 0, 20, _value);
	    graphics.endFill();
        }
    }
}

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s