BoxDecoration cung cấp nhiều cách khác nhau để vẽ một box.
Box có border (viền), body (thân) và có thể tạo shadow cho box (boxShadow).
Hình dạng của box có thể là hình tròn hoặc hình chữ nhật. Nếu nó là một hình chữ nhật, thì borderRadius property kiểm soát độ tròn của các góc.
Body box được sơn nhiều lớp. Ở lớp dưới cùng nhất màu sẽ lấp đầy box. Phía trên là gradient, cũng được lấp đầy bởi màu. Cuối cùng là hình ảnh, việc căn chỉnh chính xác được kiểm soát bởi DecorationImage class.
Hãy bắt đầu với một container trống và áp dụng red color property trong boxDecoration class.
Note: Bạn không thể áp dụng color property cho container nếu bạn đang sử dụng decoration property. Đối số màu sắc chỉ là cách viết tắt của “decoration: new BoxDecoration(color:color)”.
new Center(
child: new Container(
decoration: new BoxDecoration(
color: Colors.purple,
),
child: new FlutterLogo(
size: 200.0,
)
),
);
Gradient Property:
Nếu bạn sử dụng thuộc tính Gradient thì thuộc tính color không có hiệu lực.
Gradient có thể được vẽ dưới hình ảnh.
Giá trị của gradient property có thể là LinearGradient Class hoặc RadialGradient Class.
Hãy bắt đầu với LinearGradient Class.
LinearGradient Class có 5 property chính
- begin (Offset tại đó bắt đầu gradient)
- end (Offset tại đó kết thúc gradient)
- colors (Danh sách các màu)
- stops (Danh sách các giá trị từ 0.0 đến 1.0 biểu thị các phân số dọc theo gradient)
- tileMode (Cách gradient này sẽ xếp mặt phẳng trong vùng trước khi bắt đầu và sau khi kết thúc)
Center(
child: new Container(
decoration: new BoxDecoration(
color: Colors.purple,
gradient: new LinearGradient(
colors: [Colors.red, Colors.cyan],
),
),
child: new FlutterLogo(
size: 200.0,
)
),
);
Nếu chúng ta không thêm begin property và start property theo mặc định, gradient bắt đầu từ đầu đến cuối (từ trái sang phải)
Hãy thêm bắt đầu và kết thúc. Bạn sẽ sử dụng Alignment Class cho cả hai property.
Center(
child: new Container(
decoration: new BoxDecoration(
color: Colors.purple,
gradient: new LinearGradient(
colors: [Colors.red, Colors.cyan],
begin: Alignment.centerRight,
end: Alignment.centerLeft
),
),
child: new FlutterLogo(
size: 200.0,
)
),
);
Hãy nhớ rằng nó là một Linear Gradient. Vì vậy, nếu bắt đầu là bottomRight và kết thúc là bottomLeft, gradient sẽ đi từ Phải sang Trái cùng kết quả là:
begin: Alignment.centerRight & end: Alignment.centerLeft
begin: Alignment.topRight & end: Alignment.topLeft
Ngoài ra, bạn có thể sử dụng Alignment class với tọa độ X và Y.
new Center(
child: new Container(
decoration: new BoxDecoration(
color: Colors.purple,
gradient: new LinearGradient(
colors: [Colors.red, Colors.cyan],
begin: Alignment.centerRight,
end: new Alignment(-1.0, -1.0)
),
),
child: new FlutterLogo(
size: 200.0,
)
),
);
TileMode property
Làm thế nào gradient này sẽ xếp mặt phẳng vượt ra ngoài khu vực trước khi bắt đầu và sau khi kết thúc.
Các giá trị của TileMode là:
- TileMode.clamp
- TileMode.mirror
- TileMode.repeated
TileMode.clamp là TileMode mặc định
new Center(
child: new Container(
decoration: new BoxDecoration(
color: Colors.purple,
gradient: new LinearGradient(
colors: [Colors.red, Colors.cyan],
begin: Alignment.centerRight,
end: new Alignment(0.8, 0.0),
tileMode: TileMode.clamp
),
),
child: new FlutterLogo(
size: 200.0,
)
),
);
TileMode.mirror
new Center(
child: new Container(
decoration: new BoxDecoration(
color: Colors.purple,
gradient: new LinearGradient(
colors: [Colors.red, Colors.cyan],
begin: Alignment.centerRight,
end: new Alignment(0.8, 0.0),
tileMode: TileMode.mirror
),
),
child: new FlutterLogo(
size: 200.0,
)
),
);
new Center(
child: new Container(
decoration: new BoxDecoration(
color: Colors.purple,
gradient: new LinearGradient(
colors: [Colors.red, Colors.cyan],
begin: Alignment.centerRight,
end: new Alignment(0.8, 0.0),
tileMode: TileMode.repeated
),
),
child: new FlutterLogo(
size: 200.0,
)
),
);
Stops
Là một danh sách các giá trị từ 0.0 đến 1.0 biểu thị các phân số dọc theo gradient.
Nếu non-null, danh sách này phải có cùng độ dài với màu sắc.
Nếu giá trị đầu tiên không phải là 0.0, thì điểm dừng ở vị trí 0.0 và màu bằng màu đầu tiên trong các màu được chỉ định.
Nếu giá trị cuối cùng không phải là 1.0, thì điểm dừng ở vị trí 1.0 và màu bằng màu cuối cùng trong các màu được chỉ định.
Các giá trị trong danh sách điểm dừng phải theo thứ tự tăng dần. Nếu một giá trị trong danh sách dừng nhỏ hơn một giá trị trước đó trong danh sách, thì giá trị của nó được giả định bằng giá trị trước đó.
Nếu các điểm dừng là null, thì một tập hợp các điểm dừng được phân bố đồng đều được ngụ ý, với điểm dừng đầu tiên là 0.0 và điểm dừng cuối cùng là 1.0.
new Center(
child: new Container(
decoration: new BoxDecoration(
color: Colors.purple,
gradient: new LinearGradient(
colors: [Colors.red, Colors.cyan, Colors.purple, Colors.lightGreenAccent],
begin: Alignment.centerRight,
end: Alignment.centerLeft,
tileMode: TileMode.clamp,
stops: [0.3, 0.5, 0.6, 0.7]
),
),
child: new FlutterLogo(
size: 200.0,
)
),
);
RadialGradient
RadialGradient Class có 5 property chính
- center (Tâm của gradient, như một offset vào hình vuông (-1.0, -1.0) x (1.0, 1.0) mô tả gradient sẽ được map vào paint box)
- radius (Bán kính của gradient, như một phần nhỏ của cạnh ngắn nhất của paint box)
- colors (Danh sách các màu) Giống như LinearGradient
- stops (Danh sách các giá trị từ 0,0 đến 1,0 biểu thị các phân số dọc theo gradient) Giống như LinearGradient
- tileMode (Cách gradient này sẽ xếp mặt phẳng vượt ra ngoài trong vùng trước khi bắt đầu và sau khi kết thúc) Giống như LinearGradient
new Center(
child: new Container(
decoration: new BoxDecoration(
color: Colors.purple,
gradient: new RadialGradient(
colors: [Colors.red, Colors.cyan, Colors.purple, Colors.lightGreenAccent],
center: Alignment(-0.7, -0.6),
radius: 0.2,
tileMode: TileMode.clamp,
stops: [0.3, 0.5, 0.6, 0.7]
),
),
child: new FlutterLogo(
size: 200.0,
)
),
);
Center propery lấy một giá trị của Alignment Class giống như LinearGradient và giá trị của bán kính là từ 0.0 đến 1.0
Nếu một radial gradient được vẽ trên một box rộng 200.0, thì bán kính 0.5 bằng 100.0
Image Property
Một hình ảnh để vẽ phía trên backgroundcolor
hoặcgradient
. Giá trị của image property là DecorationImage Class.
DecorationImage Class có các property sau:
- image
- alignment (để biết thêm chi tiết, hãy kiểm tra container Cheat Sheet)
- centerSlice
- colorFilter
- fit
- matchTextDirection
- repeat
Hình ảnh
Hình ảnh có thể được vẽ vào decoration. Thông thường, đây sẽ là AssetImage (đối với hình ảnh local) hoặc NetworkImage (đối với hình ảnh lấy từ network).
new Center(
child: new Container(
decoration: new BoxDecoration(
color: Colors.purple,
gradient: new RadialGradient(
colors: [Colors.red, Colors.cyan, Colors.purple, Colors.lightGreenAccent],
center: Alignment(0.0, 0.0),
radius: 0.5,
tileMode: TileMode.clamp,
stops: [0.3, 0.5, 0.9, 1.0]
),
image: new DecorationImage(
image: new NetworkImage("http://jlouage.com/images/author.jpg")
)
),
child: new FlutterLogo(
size: 200.0,
)
),
);
Bạn có thể thấy rằng hình ảnh được vẽ phía trên color và gradient.
centerSlice Property
centerSlice cũng giống như 9 patch png trong Android Studio. Là một kỹ thuật được sử dụng để chia tỷ lệ hình ảnh theo cách mà 4 góc không được thêm vào chia tỷ lệ, nhưng bốn cạnh được chia tỷ lệ theo một trục và phần giữa được chia tỷ lệ theo cả hai trục.
Giá trị của centerSlice property là Rect Class. Chúng ta cần tạo một hình chữ nhật từ các cạnh bên trái và trên cùng, chiều rộng và chiều cao của nó. Hãy bắt đầu để biết kích thước bức hình của chúng ta.
Width = 320 & the Height = 190
Class chúng ta cần sử dụng là
Rect.fromLTWH(double left, double top, double width, double height)
CenterSlice của chúng ta là hình chữ nhật màu xanh lá cây ở giữa hình. Để tạo nó, chúng ta cần biết chiều rộng của hình chữ nhật màu cam và đặt nó cho giá trị bên trái và chiều cao của hình chữ nhật màu tím và đặt nó cho giá trị trên cùng
Rect.fromLTWH(50.0, 50.0, double width, double height)
Vì vậy, chúng ta đã yêu cầu Rect class di chuyển 50 từ bên trái và 50 từ trên cùng của hình ảnh và bắt đầu vẽ hình chữ nhật từ điểm màu vàng được đánh dấu trên hình trên.
Trong hình trên, chúng ta có chiều rộng của hình chữ nhật là 220 và chiều cao là 90 vì vậy giá trị final class phải là
Rect.fromLTWH(50.0, 50.0, 220.0, 90.0)
Final code là
new Center(
child: new Container(
decoration: new BoxDecoration(
image: new DecorationImage(
image: new AssetImage('assets/images/9_patch_scaled_320x190.png'),
centerSlice: new Rect.fromLTWH(50.0, 50.0, 220.0, 90.0),
fit: BoxFit.fill,
)
),
child: new Container(
//color: Colors.yellow,
width: 110.0,
height: 110.0,
)
),
);
Bạn có thể thấy rằng bốn hình vuông màu đỏ không được chia tỷ lệ. Để cho child của container có chiều rộng và chiều cao nhiều hơn.
new Center(
child: new Container(
decoration: new BoxDecoration(
image: new DecorationImage(
image: new AssetImage('assets/images/9_patch_scaled_320x190.png'),
centerSlice: new Rect.fromLTWH(50.0, 50.0, 220.0, 90.0),
fit: BoxFit.fill,
)
),
child: new Container(
//color: Colors.yellow,
width: 350.0,
height: 450.0,
)
),
);
ColorFilter Property
Một bộ lọc màu để áp dụng cho hình ảnh trước khi sơn nó. Giá trị của property này là ColorFilter Class và method là mode.
ColorFilter.mode() lấy hai tham số, tham số đầu tiên là bộ lọc màu và tham số thứ hai là blend mode. Chúng ta sẽ sử dụng hình ảnh dưới đây và áp dụng ColorFilter khác trên nó
Chúng ta sẽ sử dụng Colors.red.withOpacity(0.5) với nhiều chế độ hòa trộn (multiple blend mode). Dưới đây chúng ta đang sử dụng BlendMode.src. Thao tác này sẽ làm mất hình ảnh đích (cuối?) (destination image), chỉ vẽ hình ảnh nguồn (ban đầu?) (source image).
new Center(
child: new Container(
width: double.infinity,
height: double.infinity,
color: Colors.white,
child: new Container(
decoration: new BoxDecoration(
image: new DecorationImage(
image: new AssetImage('assets/images/JL-Logo-empty.png'),
colorFilter: new ColorFilter.mode(Colors.red.withOpacity(0.5), BlendMode.src),
)
),
),
),
);
Bây giờ sẽ sử dụng BlendMode.clear. Thao tác này sẽ làm mất cả hình ảnh nguồn và hình ảnh đích, không để lại gì.
BlendMode.color
Lấy màu sắc và độ bão hòa (saturation) của hình ảnh nguồn và độ sáng của hình ảnh đích.
Tác dụng là để tô màu hình ảnh đích với hình ảnh nguồn.
Độ mờ của output image được tính theo cách tương tự như đối với srcOver.
Các vùng hoàn toàn trong suốt trong hình ảnh nguồn sẽ lấy màu sắc và độ bão hòa của chúng từ đích.
BlendMode.colorBurn
Chia nghịch đảo của đích cho nguồn và nghịch đảo kết quả.
Đảo ngược các component có nghĩa là channel bão hòa hoàn toàn (màu trắng đục) được coi là giá trị 0.0 và các giá trị thường được coi là 0.0 (màu đen, trong suốt) được coi là 1.0.
BlendMode.colorDodge
Chia đích cho nghịch đảo của nguồn.
Đảo ngược các component có nghĩa là channel bão hòa hoàn toàn (màu trắng đục) được coi là giá trị 0.0 và các giá trị thường được coi là 0.0 (màu đen, trong suốt) được coi là 1.0.
BlendMode.darken
Kết hợp hình ảnh nguồn và hình ảnh đích bằng cách chọn giá trị thấp nhất từ mỗi color channel.
Độ mờ của output image được tính theo cách tương tự như đối với srcOver.
BlendMode.difference
Trừ giá trị nhỏ hơn từ giá trị lớn hơn cho mỗi channel.
Kết hợp màu đen không có tác dụng; kết hợp màu trắng sẽ đảo ngược màu sắc của hình ảnh khác.
Độ mờ của output image được tính theo cách tương tự như đối với srcOver.
Hiệu quả tương tự như loại trừ (exclusion) nhưng khắc nghiệt hơn.
BlendMode.dst
Bỏ hình ảnh nguồn, chỉ vẽ hình ảnh đích.
Về mặt khái niệm, hình ảnh nguồn bị loại bỏ, không ảnh hưởng đến đích.
Điều này tương ứng với “Destination” Porter-Duff operator.
BlendMode.dstATop
Kết hợp hình ảnh đích trên hình ảnh nguồn, nhưng chỉ nơi nó chồng lên nguồn.
Điều này tương ứng với “Destination atop Source” Porter-Duff operator.
Về cơ bản, đây là dstOver operator, nhưng với opacity channel của output được đặt thành của hình ảnh nguồn thay vì là sự kết hợp của cả hai opacity channel của hình ảnh.
Đối với một variant có nguồn ở trên cùng thay vì đích, hãy xem srcATop.
BlendMode.dstIn
Hiển thị hình ảnh đích, nhưng chỉ nơi hai hình ảnh chồng lên nhau. Hình ảnh nguồn không được hiển thị, nó chỉ được coi như một mặt nạ. Các color channel của nguồn bị bỏ qua, chỉ có độ mờ có ảnh hưởng.
Để hiển thị hình ảnh nguồn thay vào đó, hãy xem xét srcIn.
Để đảo ngược ngữ nghĩa của mặt nạ (semantic of the mask) (chỉ hiển thị nguồn nơi đích hiện diện), hãy xem xét dstOut.
Điều này tương ứng với “Destination in Source” Porter-Duff operator.
BlendMode.dstOut
Hiển thị hình ảnh đích nhưng chỉ hiển thị ở nơi hai hình ảnh không chồng lên nhau. Hình ảnh nguồn không được hiển thị, nó chỉ được coi như một mặt nạ. Các color channel của nguồn bị bỏ qua, chỉ có độ mờ có ảnh hưởng.
Để hiển thị hình ảnh nguồn thay vào đó, hãy xem xét srcOut.
Để đảo ngược ngữ nghĩa của mặt nạ (chỉ hiển thị đích nơi nguồn hiện diện, thay vì nơi nó vắng mặt), hãy xem xét dstIn.
Điều này tương ứng với “Destination out Source” Porter-Duff operator.
BlendMode.dstOver
Kết hợp hình ảnh nguồn dưới hình ảnh đích.
Điều này ngược lại với srcOver.
Điều này tương ứng với “Destination over Source” Porter-Duff operator.
BlendMode.exclusion
Lấy tổng của hai ảnh trừ gấp đôi tích của hai ảnh.
Kết hợp màu đen không có tác dụng; kết hợp màu trắng sẽ đảo ngược màu sắc của hình ảnh khác.
Độ mờ của output image được tính theo cách tương tự như đối với srcOver.
Hiệu ứng tương tự như difference nhưng nhẹ nhàng hơn.
BlendMode.hardLight
Nhân các component của ảnh nguồn và ảnh đích sau khi đã điều chỉnh chúng.
Cụ thể, nếu giá trị nguồn nhỏ hơn, thì nhân nó với giá trị đích, trong khi giá trị đích nhỏ hơn, nó nhân nghịch đảo của giá trị đích với nghịch đảo của giá trị nguồn, sau đó đảo ngược kết quả.
Đảo ngược các component có nghĩa là channel bão hòa hoàn toàn (màu trắng đục) được coi là giá trị 0.0 và các giá trị thường được coi là 0.0 (màu đen, trong suốt) được coi là 1.0.
BlendMode.hue
Lấy màu sắc của hình ảnh nguồn, độ bão hòa và độ sáng của hình ảnh đích.
Tác dụng là để tô màu hình ảnh đích với hình ảnh nguồn.
Độ mờ của output image được tính theo cách tương tự như đối với srcOver.
Các vùng hoàn toàn trong suốt trong hình ảnh nguồn sẽ lấy màu sắc của chúng từ đích.
BlendMode.lighten
Kết hợp hình ảnh nguồn và hình ảnh đích bằng cách chọn giá trị cao nhất từ mỗi color channel.
Độ mờ của output image được tính theo cách tương tự như đối với srcOver.
BlendMode.luminosity
Lấy độ sáng của hình ảnh nguồn, màu sắc và độ bão hòa của hình ảnh đích.
Độ mờ của output image được tính theo cách tương tự như đối với srcOver.
Các vùng hoàn toàn trong suốt trong hình ảnh nguồn sẽ lấy độ sáng của chúng từ đích.
BlendMode.modulate
Nhân các color component của ảnh nguồn và ảnh đích.
Điều này chỉ có thể dẫn đến các màu giống nhau hoặc tối hơn (nhân với màu trắng, 1.0, kết quả là không thay đổi; nhân với màu đen, 0.0, kết quả là màu đen).
Khi kết hợp hai hình ảnh mờ, điều này có tác dụng tương tự như chồng chéo hai hình ảnh trong suốt trên máy chiếu.
Đối với một biến thể cũng nhân alpha channel, hãy xem xét việc nhân.
BlendMode.multiply
Nhân các component của hình ảnh nguồn và hình ảnh đích, bao gồm cả alpha channel.
Điều này có thể dẫn đến các màu giống nhau hoặc tối hơn (nhân với màu trắng, 1.0, kết quả là không thay đổi; nhân với màu đen, 0.0, kết quả là màu đen).
Vì alpha channel cũng được nhân lên, pixel hoàn toàn trong suốt (độ mờ 0.0) trong một hình ảnh dẫn đến pixel hoàn toàn trong suốt ở output. Điều này tương tự như dstIn, nhưng với các màu kết hợp.
Đối với một variant nhân các màu nhưng không nhân alpha channel, hãy xem xét điều chỉnh.
BlendMode.overlay
Nhân các component của ảnh nguồn và ảnh đích sau khi đã điều chỉnh chúng để có lợi cho đích.
Cụ thể, nếu giá trị đích nhỏ hơn, điều này nhân nó với giá trị nguồn, trong khi giá trị nguồn nhỏ hơn, nó nhân nghịch đảo của giá trị nguồn với nghịch đảo của giá trị đích, sau đó đảo ngược kết quả.
Đảo ngược các component có nghĩa là channel bão hòa hoàn toàn (màu trắng đục) được coi là giá trị 0.0 và các giá trị thường được coi là 0.0 (màu đen, trong suốt) được coi là 1.0.
BlendMode.plus
Tính tổng các component của ảnh nguồn và ảnh đích.
Độ trong suốt ở một pixel của một trong các hình ảnh làm giảm sự đóng góp của hình ảnh đó vào output pixel tương ứng, như thể màu của pixel đó trong hình ảnh đó tối hơn.
Điều này tương ứng với “Source plus Destination” Porter-Duff operator.
BlendMode.saturation
Lấy độ bão hòa của hình ảnh nguồn và màu sắc và độ sáng của hình ảnh đích.
Độ mờ của output image được tính theo cách tương tự như đối với srcOver.
Các vùng hoàn toàn trong suốt trong hình ảnh nguồn sẽ lấy độ bão hòa của chúng từ đích.
BlendMode.screen
Nhân nghịch đảo của các component của hình ảnh nguồn và ảnh đích, và nghịch đảo kết quả.
Đảo ngược các component có nghĩa là channel bão hòa hoàn toàn (màu trắng đục) được coi là giá trị 0.0 và các giá trị thường được coi là 0.0 (màu đen, trong suốt) được coi là 1.0.
Điều này về cơ bản giống như chế độ hòa trộn điều chế (modulate blend mode), nhưng với các giá trị của màu sắc được đảo ngược trước phép nhân và kết quả được đảo ngược lại trước khi hiển thị.
Điều này có thể dẫn đến các màu giống nhau hoặc nhạt hơn (nhân với màu đen, 1.0, kết quả là không thay đổi; nhân với màu trắng, 0.0, cho kết quả là màu trắng). Tương tự, trong alpha channel, nó chỉ có thể dẫn đến màu sắc mờ hơn.
Điều này có tác dụng tương tự như hai máy chiếu hiển thị hình ảnh của chúng trên cùng một màn hình đồng thời.
BlendMode.softLight
Sử dụng colorDodge cho các giá trị nguồn dưới 0.5 và colorBurn cho các giá trị nguồn trên 0.5.
Điều này dẫn đến một hiệu ứng tương tự nhưng nhẹ nhàng hơn so với overlay.
BlendMode.srcATop
Kết hợp hình ảnh nguồn trên hình ảnh đích, nhưng chỉ ở nơi nó chồng lên điểm đích.
Điều này tương ứng với “Source atop Destination” Porter-Duff operator.
Về cơ bản, đây là srcOver operator, nhưng với opacity channel của output được đặt thành của hình ảnh đích thay vì là sự kết hợp của cả hai opacity channel của hình ảnh.
Đối với một variant có đích ở trên cùng thay vì nguồn, hãy xem dstATop.
BlendMode.srcIn
Hiển thị hình ảnh nguồn, nhưng chỉ nơi hai hình ảnh chồng lên nhau (overlap). Hình ảnh đích không được hiển thị, nó chỉ được coi như một mặt nạ. Các color channel của điểm đích bị bỏ qua, chỉ có độ mờ có ảnh hưởng.
Để hiển thị hình ảnh đích thay thế, hãy xem xét dstIn.
Để đảo ngược ngữ nghĩa của mặt nạ (chỉ hiển thị nguồn nơi đích vắng mặt, thay vì nơi nó hiện diện), hãy xem xét srcOut.
Điều này tương ứng với “Source in Destination” Porter-Duff operator.
BlendMode.srcOut
Hiển thị hình ảnh nguồn, nhưng chỉ hiển thị ở nơi hai hình ảnh không chồng lên nhau. Hình ảnh đích không được hiển thị, nó chỉ được coi như một mặt nạ. Các color channel của điểm đích bị bỏ qua, chỉ có độ mờ có ảnh hưởng.
Để hiển thị hình ảnh đích thay thế, hãy xem xét dstOut.
Để đảo ngược semantic của mặt nạ (chỉ hiển thị nguồn nơi đích hiện diện), hãy xem xét srcIn.
Điều này tương ứng với “Source out Destination” Porter-Duff operator.
BlendMode.srcOver
Kết hợp hình ảnh nguồn với hình ảnh đích.
Đây là giá trị mặc định. Nó đại diện cho trường hợp trực quan nhất, trong đó các shape được vẽ trên đầu những gì bên dưới, với các khu vực trong suốt hiển thị lớp đích.
Điều này tương ứng với “Source over Destination” Porter-Duff operator, còn được gọi là Thuật toán của Họa sĩ (Painter’s Algorithm).
BlendMode.xor
Áp dụng bitwise xor
operator cho ảnh nguồn và ảnh đích. Điều này để lại sự rõ rệt ở nơi chúng sẽ chồng lên nhau.
Điều này tương ứng với “Source xor Destination” Porter-Duff operator.
fit Property
Cách hình ảnh được hiển thị trên box. Giá trị của fit property là BoxFit enum.
- contain
- cover
- fill
- fitHeight
- fitWidth
- none
- scaleDown
Center(
child: new Container(
width: double.infinity,
height: double.infinity,
color: Colors.white,
child: new Container(
decoration: new BoxDecoration(
image: new DecorationImage(
image: new NetworkImage('http://jlouage.com/images/author.jpg'),
fit: BoxFit.contain
)
),
),
),
);
contain
Càng lớn càng tốt trong khi vẫn chứa source hoàn toàn trong target box.
cover
Càng nhỏ càng tốt trong khi vẫn bao phủ toàn bộ target box.
fill
Fill vào target box bằng cách bóp méo aspect ratio của source.
fitHeight
Đảm bảo toàn bộ chiều cao của source được hiển thị, bất kể điều này có nghĩa là source tràn target box theo chiều ngang.
fitWidth
Đảm bảo toàn bộ chiều rộng của source được hiển thị, bất kể điều này có nghĩa là source overflows target box theo chiều dọc.
none
Căn chỉnh source bên trong target box (theo mặc định, căn giữa) và loại bỏ bất kỳ phần nào của source nằm bên ngoài box.
Source image không được thay đổi kích thước.
scaleDown
Căn chỉnh source trong target box (theo mặc định, căn giữa) và nếu cần, hãy thu nhỏ source để đảm bảo rằng source vừa với box.
Điều này giống nhưcontain
nếu điều đó sẽ thu nhỏ hình ảnh, nếu không thì nó giống nhưnone
.
repeat Property
Làm thế nào để tô bất kỳ phần nào của box mà sẽ không bị cover bởi hình ảnh. Giá trị của repeat propery là ImageRepeat enum.
- noRepeat
- repeat
- repeatX
- repeatY
noRepeat
Để các phần không được cover của box trong suốt.
Center(
child: new Container(
width: double.infinity,
height: double.infinity,
color: Colors.white,
child: new Container(
decoration: new BoxDecoration(
image: new DecorationImage(
image: new AssetImage('assets/images/JL-Logo-150.png'),
repeat: ImageRepeat.noRepeat
)
),
),
),
);
repeat
Lặp lại hình ảnh theo cả hai hướng x và y cho đến khi box được lấp đầy.
Center(
child: new Container(
width: double.infinity,
height: double.infinity,
color: Colors.white,
child: new Container(
decoration: new BoxDecoration(
image: new DecorationImage(
image: new AssetImage('assets/images/JL-Logo-150.png'),
repeat: ImageRepeat.repeat
)
),
),
),
);
repeatX
Lặp lại hình ảnh theo hướng x cho đến khi box được lấp đầy theo chiều ngang.
Center(
child: new Container(
width: double.infinity,
height: double.infinity,
color: Colors.white,
child: new Container(
decoration: new BoxDecoration(
image: new DecorationImage(
image: new AssetImage('assets/images/JL-Logo-150.png'),
repeat: ImageRepeat.repeatX
)
),
),
),
);
repeatY
Lặp lại hình ảnh theo hướng y cho đến khi box được lấp đầy theo chiều dọc.
Center(
child: new Container(
width: double.infinity,
height: double.infinity,
color: Colors.white,
child: new Container(
decoration: new BoxDecoration(
image: new DecorationImage(
image: new AssetImage('assets/images/JL-Logo-150.png'),
repeat: ImageRepeat.repeatY
)
),
),
),
);
matchTextDirection Property
Liệu có vẽ hình ảnh theo hướng của TextDirectionTextDirection
hay không. Giá trị là true hoặc false;
Nếu điều này là true, thì trong TextDirection.ltr context, hình ảnh sẽ được vẽ với điểm gốc của nó ở phía trên bên trái (hướng vẽ "bình thường" cho hình ảnh); và trong TextDirection.rtl context, hình ảnh sẽ được vẽ với hệ số tỷ lệ -1 theo hướng ngang sao cho điểm gốc ở trên cùng bên phải.
Border Property
Đường viền để vẽ phía trên màucolor
,gradient
hoặcimage
.
Border Property coi như giá trị Border Class, Border.all Class & BorderDirectional Class.
Border & BorderDirectional nếu bạn muốn đặt đường viền cho một mặt cụ thể.
Border.all nếu bạn đặt đường viền cho tất cả các bên.
Trước tiên hãy sử dụng Border.all - Nó có 3 tham số,
- color: màu của đường viền
- width: chiều rộng của đường viền
- style: kiểu viền, có 2 kiểu.
BorderStyle.solid và BorderStyle.none
new Center(
child: new Container(
width: 200.0,
height: 200.0,
color: Colors.white,
child: new Container(
decoration: new BoxDecoration(
border: new Border.all(
color: Colors.green,
width: 5.0,
style: BorderStyle.solid
),
image: new DecorationImage(
image: new AssetImage('assets/images/JL-Logo-150.png'),
)
),
),
),
);
Bây giờ chúng ta sẽ sử dụng Border Class thay vì Border.all. Border Class lấy 4 tham số trên, dưới, trái và phải. Giá trị của mọi tham số phải là BorderSide Class.
new Center(
child: new Container(
width: 200.0,
height: 200.0,
color: Colors.white,
child: new Container(
decoration: new BoxDecoration(
border: new Border(
top: new BorderSide(
color: Colors.green,
width: 5.0,
style: BorderStyle.solid
),
),
image: new DecorationImage(
image: new AssetImage('assets/images/JL-Logo-150.png'),
)
),
),
),
);
Bây giờ, hãy sử dụng BorderDirectional.
BorderDirectional giống như Border Class có 4 tham số, nhưng thay vì trái và phải, nó sẽ bắt đầu và kết thúc.
new Center(
child: new Container(
width: 200.0,
height: 200.0,
color: Colors.white,
child: new Container(
decoration: new BoxDecoration(
border: new BorderDirectional(
top: new BorderSide(
color: Colors.green,
width: 5.0,
style: BorderStyle.solid
),
start: new BorderSide(
color: Colors.green,
width: 5.0,
style: BorderStyle.solid
),
),
image: new DecorationImage(
image: new AssetImage('assets/images/JL-Logo-150.png'),
)
),
),
),
);
borderRadius Property
Bạn sử dụng borderRadius nếu bạn muốn làm cho góc của box được bo tròn,
Note: borderRadius chỉ áp dụng cho các box có hình chữ nhật.
Giá trị của borderRadius là BorderRadius.all, BorderRadius.only, BorderRadius.circular, BorderRadius.horizontal, BorderRadius.vertical.
Ngoài ra bạn có thể sử dụng thay cho BorderRadius, BorderRadiusDirectional với các method tương tự ở trên. Nhưng trong các tham số thay vì trái và phải, bạn sẽ sử dụng bắt đầu và kết thúc.
BorderRadius.all Tạo bán kính đường viền trong đó tất cả các bán kính đều làradius
.
new Center(
child: new Container(
width: 200.0,
height: 200.0,
color: Colors.white,
child: new Container(
decoration: new BoxDecoration(
border: new Border.all(
color: Colors.green,
width: 5.0,
style: BorderStyle.solid
),
borderRadius: new BorderRadius.all(new Radius.circular(20.0)),
image: new DecorationImage(
image: new AssetImage('assets/images/JL-Logo-150.png'),
)
),
),
),
);
BorderRadius.circular Tạo bán kính đường viền trong đó tất cả các bán kính đều là Radius.circular (bán kính).
new Center(
child: new Container(
width: 200.0,
height: 200.0,
color: Colors.white,
child: new Container(
decoration: new BoxDecoration(
border: new Border.all(
color: Colors.green,
width: 5.0,
style: BorderStyle.solid
),
borderRadius: new BorderRadius.circular(20.0),
image: new DecorationImage(
image: new AssetImage('assets/images/JL-Logo-150.png'),
)
),
),
),
);
Kết quả tương tự như BorderRadius.all nhưng bạn có thể nhập giá trị trực tiếp dưới dạng gấp đôi. không cần thêm Radius Class.
BorderRadius.horizontal Tạo bán kính đường viền đối xứng theo chiều ngang trong đó các cạnh bên trái và bên phải của hình chữ nhật có cùng bán kính.
new Center(
child: new Container(
width: 200.0,
height: 200.0,
color: Colors.white,
child: new Container(
decoration: new BoxDecoration(
border: new Border.all(
color: Colors.green,
width: 5.0,
style: BorderStyle.solid
),
borderRadius: new BorderRadius.horizontal(
left: new Radius.circular(20.0),
//right: new Radius.circular(20.0),
),
image: new DecorationImage(
image: new AssetImage('assets/images/JL-Logo-150.png'),
)
),
),
),
);
BorderRadius.vertical Tạo bán kính đường viền đối xứng theo chiều dọc trong đó các cạnh trên và dưới của hình chữ nhật có cùng bán kính.
new Center(
child: new Container(
width: 200.0,
height: 200.0,
color: Colors.white,
child: new Container(
decoration: new BoxDecoration(
border: new Border.all(
color: Colors.green,
width: 5.0,
style: BorderStyle.solid
),
borderRadius: new BorderRadius.vertical(
top: new Radius.circular(20.0),
//bottom: new Radius.circular(20.0),
),
image: new DecorationImage(
image: new AssetImage('assets/images/JL-Logo-150.png'),
)
),
),
),
);
BorderRadius.only Tạo bán kính đường viền chỉ với các giá trị khác 0 đã cho. Các góc khác sẽ là góc vuông.
new Center(
child: new Container(
width: 200.0,
height: 200.0,
color: Colors.white,
child: new Container(
decoration: new BoxDecoration(
border: new Border.all(
color: Colors.green,
width: 5.0,
style: BorderStyle.solid
),
borderRadius: new BorderRadius.only(
topLeft: new Radius.circular(20.0),
//topRight: new Radius.circular(20.0),
//bottomRight: new Radius.circular(20.0),
bottomLeft: new Radius.circular(20.0),
),
image: new DecorationImage(
image: new AssetImage('assets/images/JL-Logo-150.png'),
)
),
),
),
);
Ngoài ra, bạn có thể sử dụng thay thế cho Radius.circular Class, Radius.elliptical.
Radius.elliptical lấy 2 tham số x & y.
new Center(
child: new Container(
width: 200.0,
height: 200.0,
color: Colors.white,
child: new Container(
decoration: new BoxDecoration(
border: new Border.all(
color: Colors.green,
width: 5.0,
style: BorderStyle.solid
),
borderRadius: new BorderRadius.only(
topLeft: new Radius.elliptical(40.0, 10.0),
//topRight: new Radius.circular(20.0),
//bottomRight: new Radius.circular(20.0),
bottomLeft: new Radius.circular(20.0),
),
image: new DecorationImage(
image: new AssetImage('assets/images/JL-Logo-150.png'),
)
),
),
),
);
boxShadow Property
Danh sách các shadow cast bởi box này phía sau box. Bóng đổ theo hình dạng của box.
Giá trị của boxShadow là một danh sách của BoxShadow class. Bạn có thể sử dụng multipleBoxShadow trong danh sách.
BoxShadow class có 4 tham số
- color: Màu của bóng
- offset: Độ dịch chuyển của bóng khỏi box.
- blurRadius: Độ lệch chuẩn của Gaussian đối với hình dạng của box.
- spreadRadius: Số lượng box phải được thổi phồng trước khi áp dụng hiệu ứng làm mờ.
Ví dụ đầu tiên, chúng ta sử dụng màu sắc và offset.
Giá trị của tham số offset là một Offset class và lấy 2 tham số kép x và y.
new Center(
child: new Container(
width: 200.0,
height: 200.0,
color: Colors.white,
child: new Container(
decoration: new BoxDecoration(
color: Colors.white,
border: new Border.all(
color: Colors.green,
width: 5.0,
style: BorderStyle.solid
),
borderRadius: new BorderRadius.only(
topLeft: new Radius.elliptical(40.0, 10.0),
bottomLeft: new Radius.circular(20.0),
),
boxShadow: [
new BoxShadow(
color: Colors.red,
offset: new Offset(20.0, 10.0),
)
],
image: new DecorationImage(
image: new AssetImage('assets/images/JL-Logo-150.png'),
)
),
),
),
);
Chúng ta đã chuyển shadow 20 trên trục X và 10 trên trục Y. Shadow là thể rắn.
Hãy thêm một BlurRadius vào nó để làm cho nó như một cái bóng thực sự.
new Center(
child: new Container(
width: 200.0,
height: 200.0,
color: Colors.white,
child: new Container(
decoration: new BoxDecoration(
color: Colors.white,
border: new Border.all(
color: Colors.green,
width: 5.0,
style: BorderStyle.solid
),
borderRadius: new BorderRadius.only(
topLeft: new Radius.elliptical(40.0, 10.0),
bottomLeft: new Radius.circular(20.0),
),
boxShadow: [
new BoxShadow(
color: Colors.red,
offset: new Offset(20.0, 10.0),
blurRadius: 20.0,
)
],
image: new DecorationImage(
image: new AssetImage('assets/images/JL-Logo-150.png'),
)
),
),
),
);
Bây giờ chúng ta sẽ thêm nhiều spread hơn cho shadow. Chúng ta sử dụng spreadRadius.
new Center(
child: new Container(
width: 200.0,
height: 200.0,
color: Colors.white,
child: new Container(
decoration: new BoxDecoration(
color: Colors.white,
border: new Border.all(
color: Colors.green,
width: 5.0,
style: BorderStyle.solid
),
borderRadius: new BorderRadius.only(
topLeft: new Radius.elliptical(40.0, 10.0),
bottomLeft: new Radius.circular(20.0),
),
boxShadow: [
new BoxShadow(
color: Colors.red,
offset: new Offset(20.0, 10.0),
blurRadius: 20.0,
spreadRadius: 40.0
)
],
image: new DecorationImage(
image: new AssetImage('assets/images/JL-Logo-150.png'),
)
),
),
),
);
Bây giờ, hãy sử dụng nhiều BoxShadow.
new Center(
child: new Container(
width: 200.0,
height: 200.0,
child: new Container(
decoration: new BoxDecoration(
color: Colors.white,
border: new Border.all(
color: Colors.green,
width: 5.0,
style: BorderStyle.solid
),
boxShadow: [
new BoxShadow(
color: Colors.red,
offset: new Offset(20.0, 10.0),
blurRadius: 20.0,
spreadRadius: 40.0
),
new BoxShadow(
color: Colors.yellow,
offset: new Offset(20.0, 10.0),
blurRadius: 20.0,
spreadRadius: 20.0
),
new BoxShadow(
color: Colors.green,
offset: new Offset(10.0, 5.0),
blurRadius: 20.0,
spreadRadius: 5.0
)
],
image: new DecorationImage(
image: new AssetImage('assets/images/JL-Logo-150.png'),
)
),
),
),
);
shape Property
Shape để fill màu background, gradient và hình ảnh vào và để đúc dưới dạng boxShadow.
Giá trị của shape property là BoxShape enum
- BoxShape.rectangle
- BoxShape.circle
Note: Nếu đây là BoxShape.circle thì borderRadius bị bỏ qua.
new Center(
child: new Container(
width: 200.0,
height: 200.0,
child: new Container(
decoration: new BoxDecoration(
color: Colors.white,
border: new Border.all(
color: Colors.green,
width: 5.0,
style: BorderStyle.solid
),
boxShadow: [
new BoxShadow(
color: Colors.red,
offset: new Offset(20.0, 10.0),
blurRadius: 20.0,
spreadRadius: 40.0
)
],
shape: BoxShape.circle,
image: new DecorationImage(
image: new AssetImage('assets/images/JL-Logo-150.png'),
)
),
),
),
);
Mong rằng bạn sẽ thích bài viết này.
Bài viết được lược dịch từ Julien Louage.
Chau Le
Cực thích đồ ngọt như sữa, kem. Thích phiêu lưu mạo hiểm nhưng vì Covid mà vô tình trở thành người chia sẻ nội dung lập trình :))
follow me :
Bài viết liên quan
Tự học Dart: Các Dart Operators (toán tử) bạn cần biết
Sep 02, 2023 • 18 min read
Flutter cơ bản: Điều cần biết khi lập trình ứng dụng đầu tiên
Aug 23, 2023 • 13 min read
Dart là gì? Giới thiệu cơ bản về ngôn ngữ lập trình Dart
Aug 21, 2023 • 11 min read
Flutter là gì? Vì sao nên học công cụ lập trình Flutter?
Aug 19, 2023 • 11 min read
Flutter cơ bản: Widget Tree, Element Tree & Render Tree
Aug 19, 2023 • 10 min read
So sánh StatelessWidget và StatefulWidget
Jul 17, 2022 • 12 min read