±à¼ÍƼö: |
±¾ÎÄÊ×ÏȽéÉÜÁËFlutterÖй¹½¨UI½çÃæ×î³£ÓõĻù´¡×é¼þ£¨ÈÝÆ÷£¬ÐУ¬ÁУ¬¾ø¶Ô¶¨Î»²¼¾Ö£¬Îı¾£¬Í¼Æ¬ºÍͼ±ê£©Ó÷¨¡£½Ó×Å£¬½éÉÜÁËÒ»¸ö½Ï¸´ÔÓµÄUIʵսÀý×Ó¡£Ï£ÍûÄܶÔÄúÓÐËù°ïÖú¡£
±¾ÎÄÀ´×ÔÓÚsegmentfault£¬ÓÉ»ðÁú¹ûÈí¼þAlice±à¼¡¢ÍƼö¡£ |
|

1. ǰÑÔ
Flutter×÷ΪʱÏÂ×îÁ÷Ðеļ¼ÊõÖ®Ò»£¬Æ¾½èÆä³öÉ«µÄÐÔÄÜÒÔ¼°Ä¨Æ½¶à¶ËµÄ²îÒìÓÅÊÆ£¬ÔçÒÑÒýÆð´óÅú¼¼Êõ°®ºÃÕߵĹØ×¢£¬ÉõÖÁһЩÏÐÓ㣬ÃÀÍÅ£¬ÌÚѶµÈ´ó¹«Ë¾¾ùÒÑ¿ªÊ¼Ê¹Óá£ËäȻĿǰÆäÉú̬»¹Ã»ÓÐÍêÈ«³ÉÊ죬µ«Éí¿¿±³ºóµÄGoogle¼Ó³Ö£¬Æä·¢Õ¹ËÙ¶ÈÒѾ×ã¹»¾ªÈË£¬¿ÉÒÔÔ¤¼û½«À´¶ÔFlutter¿ª·¢ÈËÔ±µÄÐèÇóÒ²»áËæÖ®Ôö³¤¡£
ÎÞÂÛÊÇΪÁËÏÖÔڵļ¼Êõ³¢ÏÊ»¹Êǽ«À´µÄ³±Á÷Ç÷ÊÆ£¬¶¼9102ÄêÁË£¬×÷Ϊһ¸öǰ¶Ë¿ª·¢Õߣ¬ËƺõûÓÐÀíÓɲ»È¥³¢ÊÔËü¡£ÕýÊÇ´ø×ÅÕâÑùµÄÐÄÀí£¬±ÊÕßÒ²¿ªÊ¼Ñ§Ï°Flutter£¬Í¬Ê±½¨ÁËÒ»¸öÓÃÓÚÁ·Ï°µÄ²Ö¿â£¬ºóÐøËùÓдúÂë¶¼»áÍйÜÔÚÉÏÃæ£¬»¶Óstar£¬Ò»Æðѧϰ¡£ÕâÊÇÎÒдµÄFlutterϵÁÐÎÄÕ£º
ÓÃFlutter¹¹½¨Æ¯ÁÁµÄUI½çÃæ - »ù´¡×é¼þƪ
Flutter¹ö¶¯ÐÍÈÝÆ÷×é¼þ - ListViewƪ
FlutterÍø¸ñÐͲ¼¾Ö - GridViewƪ
ÔÚFlutterÖÐʹÓÃ×Ô¶¨ÒåIcon
½ñÌì·ÖÏíµÄÊÇFlutterÖÐ×î³£Óõ½µÄһЩ»ù´¡×é¼þ£¬ËüÃÇÊǹ¹³ÉUI½çÃæµÄ»ù´¡ÔªËØ£ºÈÝÆ÷£¬ÐУ¬ÁУ¬¾ø¶Ô¶¨Î»²¼¾Ö£¬Îı¾£¬Í¼Æ¬ºÍͼ±êµÈ¡£
2. »ù´¡×é¼þ
2.1 Container(ÈÝÆ÷×é¼þ)

ÈÝÆ÷×é¼þ
Container×é¼þÊÇ×î³£ÓõIJ¼¾Ö×é¼þÖ®Ò»£¬¿ÉÒÔÈÏΪËüÊÇweb¿ª·¢ÖеÄdiv£¬rn¿ª·¢ÖеÄView¡£ÆäÍùÍù¿ÉÒÔÓÃÀ´¿ØÖÆ´óС¡¢±³¾°ÑÕÉ«¡¢±ß¿ò¡¢ÒõÓ°¡¢ÄÚÍâ±ß¾àºÍÄÚÈÝÅÅÁз½Ê½µÈ¡£ÎÒÃÇÏÈÀ´¿´ÏÂÆä¹¹Ô캯Êý£º
Container({
Key key,
double width,
double height,
this.margin,
this.padding,
Color color,
this.alignment,
BoxConstraints constraints,
Decoration decoration,
this.foregroundDecoration,
this.transform,
this.child,
}) |
2.1.1 width£¬height£¬margin£¬padding
ÕâЩÊôÐԵĺ¬ÒåºÍÎÒÃÇÒѾÊìÖªµÄ²¢Ã»ÓÐÇø±ð¡£Î¨Ò»ÐèҪעÒâµÄÊÇ£¬marginºÍpaddingµÄ¸³Öµ²»ÊÇÒ»¸ö¼òµ¥µÄÊý×Ö£¬ÒòΪÆäÓÐleft,
top, right, bottomËĸö·½ÏòµÄÖµÐèÒªÉèÖá£FlutterÌṩÁËEdgeInsetsÕâ¸öÀ࣬°ïÖúÎÒÃÇ·½±ãµØÉú³ÉËĸö·½ÏòµÄÖµ¡£Í¨³£Çé¿öÏ£¬ÎÒÃÇ¿ÉÄÜ»áÓõ½EdgeInsetsµÄ4ÖÖ¹¹Ôì·½·¨£º
EdgeInsets.all(value): ÓÃÓÚÉèÖÃ4¸ö·½ÏòÒ»ÑùµÄÖµ£»
EdgeInsets.only(left: val1, top: val2, right: val3,
bottom: val4): ¿ÉÒÔµ¥¶ÀÉèÖÃij¸ö·½ÏòµÄÖµ£»
EdgeInsets.symmetric(horizontal: val1, vertical: val2):
ÓÃÓÚÉèÖÃˮƽ/´¹Ö±·½ÏòÉϵÄÖµ£»
EdgeInsets.fromLTRB(left, top, right, bottom): °´ÕÕ×óÉÏÓÒϵÄ˳ÐòÉèÖÃ4¸ö·½ÏòµÄÖµ¡£
2.1.2 color
¸ÃÊôÐԵĺ¬ÒåÊDZ³¾°ÑÕÉ«£¬µÈͬÓÚweb/rnÖеÄbackgroundColor¡£ÐèҪעÒâµÄÊÇFlutterÖÐÓÐÒ»¸öרÃűíʾÑÕÉ«µÄColorÀ࣬¶ø·ÇÎÒÃdz£ÓõÄ×Ö·û´®¡£²»¹ýÎÒÃÇ¿ÉÒԷdz£ÇáËɵؽøÐÐת»»£¬¾Ù¸öÀõ×Ó£º
ÔÚweb/rnÖÐÎÒÃÇ»áÓÃ'#FF0000'»ò'red'À´±íʾºìÉ«£¬¶øÔÚFlutterÖУ¬ÎÒÃÇ¿ÉÒÔÓÃColor(0xFFFF0000)»òColors.redÀ´±íʾ¡£
2.1.3 alignment
¸ÃÊôÐÔÊÇÓÃÀ´¾ö¶¨Container×é¼þµÄ×Ó×é¼þ½«ÒÔºÎÖÖ·½Ê½½øÐÐÅÅÁУ¨PS£ºÔÙÒ²²»ÓÃΪÔõô¾ÓÖвÙÐÄÁË£©¡£Æä¿Éѡֵͨ³£»áÓõ½£º
Alignment.topLeft: ×óÉÏ
Alignment.topCenter: ÉÏÖÐ
Alignment.topRight: ÓÒÉÏ
Alignment.centerLeft: ×óÖÐ
Alignment.center: ¾ÓÖÐ
Alignment.centerRight: ÓÒÖÐ
Alignment.bottomLeft: ×óÏÂ
Alignment.bottomCenter: ÏÂÖÐ
Alignment.bottomRight: ÓÒÏÂ
2.1.4 constraints
ÔÚweb/rnÖÐÎÒÃÇͨ³£»áÓÃminWidth/maxWidth/minHeight/maxHeightµÈÊôÐÔÀ´ÏÞÖÆÈÝÆ÷µÄ¿í¸ß¡£ÔÚFlutterÖУ¬ÄãÐèҪʹÓÃBoxConstraints£¨ºÐÔ¼Êø£©À´ÊµÏָù¦ÄÜ¡£
// ÈÝÆ÷µÄ´óС½«±»ÏÞÖÆÔÚ[100*100
~ 200*200]ÄÚ
BoxConstraints(
minWidth: 100,
maxWidth: 200,
minHeight: 100,
maxHeight: 200,
) |
2.1.5 decoration
¸ÃÊôÐԷdz£Ç¿´ó£¬×ÖÃæÒâ˼ÊÇ×°ÊΣ¬ÒòΪͨ¹ýËüÄã¿ÉÒÔÉèÖñ߿ò£¬ÒõÓ°£¬½¥±ä£¬Ô²½ÇµÈ³£ÓÃÊôÐÔ¡£BoxDecoration¼Ì³Ð×ÔDecorationÀ࣬Òò´ËÎÒÃÇͨ³£»áÉú³ÉÒ»¸öBoxDecorationʵÀýÀ´ÉèÖÃÕâЩÊôÐÔ¡£
1) ±ß¿ò
¿ÉÒÔÓÃBorder.all¹¹Ô캯ÊýÖ±½ÓÉú³É4Ìõ±ß¿ò£¬Ò²¿ÉÒÔÓÃBorder¹¹Ô캯Êýµ¥¶ÀÉèÖò»Í¬·½ÏòÉϵı߿ò¡£²»¹ýÁîÈ˾ªÑȵÄÊǹٷ½ÌṩµÄ±ß¿ò¾¹È»²»Ö§³ÖÐéÏߣ¨issueÔÚÕâÀ¡£
// ͬʱÉèÖÃ4Ìõ±ß¿ò£º1px´ÖϸµÄºÚɫʵÏ߱߿ò
BoxDecoration(
border: Border.all(color: Colors.black, width:
1, style: BorderStyle.solid)
)
// ÉèÖõ¥±ß¿ò£ºÉϱ߿òΪ1px´ÖϸµÄºÚɫʵÏ߱߿ò£¬ Óұ߿òΪ1px´ÖϸµÄºìɫʵÏ߱߿ò
BoxDecoration(
border: Border(
top: BorderSide(color: Colors.black, width:
1, style: BorderStyle.solid),
right: BorderSide(color: Colors.red, width:
1, style: BorderStyle.solid),
),
) |
2) ÒõÓ°
ÒõÓ°ÊôÐÔºÍwebÖеÄboxShadow¼¸ºõûÓÐÇø±ð£¬¿ÉÒÔÖ¸¶¨x£¬y£¬blur£¬spread£¬colorµÈÊôÐÔ¡£
BoxDecoration(
boxShadow: [
BoxShadow(
offset: Offset(0, 0),
blurRadius: 6,
spreadRadius: 10,
color: Color.fromARGB(20, 0, 0, 0),
),
],
) |
3) ½¥±ä
Èç¹ûÄã²»ÏëÈÝÆ÷µÄ±³¾°ÑÕÉ«Êǵ¥µ÷µÄ£¬¿ÉÒÔ³¢ÊÔÓÃgradientÊôÐÔ¡£Flutterͬʱ֧³ÖÏßÐÔ½¥±äºÍ¾¶Ïò½¥±ä£º
// ´Ó×óµ½ÓÒ£¬ºìÉ«µ½À¶É«µÄÏßÐÔ½¥±ä
BoxDecoration(
gradient: LinearGradient(
begin: Alignment.centerLeft,
end: Alignment.centerRight,
colors: [Colors.red, Colors.blue],
),
)
// ´ÓÖÐÐÄÏòËÄÖÜÀ©É¢£¬ºìÉ«µ½À¶É«µÄ¾¶Ïò½¥±ä
BoxDecoration(
gradient: RadialGradient(
center: Alignment.center,
colors: [Colors.red, Colors.blue],
),
) |
4) Ô²½Ç
ͨ³£Çé¿öÏ£¬Äã¿ÉÄÜ»áÓõ½BorderRadius.circular¹¹Ô캯ÊýÀ´Í¬Ê±ÉèÖÃ4¸ö½ÇµÄÔ²½Ç£¬»òÊÇBorderRadius.only¹¹Ô캯ÊýÀ´µ¥¶ÀÉèÖÃij¼¸¸ö½ÇµÄÔ²½Ç£º
// ͬʱÉèÖÃ4¸ö½ÇµÄÔ²½ÇΪ5
BoxDecoration(
borderRadius: BorderRadius.circular(5),
)
// ÉèÖõ¥Ô²½Ç£º×óÉϽǵÄÔ²½ÇΪ5£¬ÓÒÉϽǵÄÔ²½ÇΪ10
BoxDecoration(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(5),
topRight: Radius.circular(10),
),
) |
2.1.6 transform
transformÊôÐÔºÍÎÒÃÇÔÚweb/rnÖо³£Óõ½µÄ»ù±¾Ò²Ã»Óвî±ð£¬Ö÷Òª°üÀ¨£ºÆ½ÒÆ£¬Ëõ·Å¡¢ÐýתºÍÇãб¡£ÔÚFlutterÖУ¬·â×°Á˾ØÕó±ä»»ÀàMatrix4°ïÖúÎÒÃǽøÐб任£º
translationValues(x, y, z): Æ½ÒÆx, y, z£»
rotationX(radians): xÖáÐýתradians»¡¶È£»
rotationY(radians): yÖáÐýתradians»¡¶È£»
rotationZ(radians): zÖáÐýתradians»¡¶È£»
skew(alpha, beta): xÖáÇãбalpha¶È£¬yÖáÇãбbeta¶È£»
skewX(alpha): xÖáÇãбalpha¶È£»
skewY(beta): yÖáÇãбbeta¶È£»
2.1.7 С½á
Container×é¼þµÄÊôÐԺܷḻ£¬ËäÈ»ÓÐЩÓ÷¨ÉϺÍweb/rnÓÐЩÐí²îÒ죬µ«»ù±¾ÉÏ´óͬСÒ죬ËùÒÔ¹ý¶ÉÆðÀ´Ò²²»»áÓÐʲôÕϰ¡£ÁíÍ⣬ÓÉÓÚContainer×é¼þÊǵ¥×Ó½Úµã×é¼þ£¬Ò²¾ÍÊÇÖ»ÔÊÐí×Ó½ÚµãÓÐÒ»¸ö¡£ËùÒÔÔÚ²¼¾ÖÉÏ£¬ºÜ¶àʱºòÎÒÃÇ»áÓÃRowºÍColumn×é¼þ½øÐÐÐÐ/Áв¼¾Ö¡£
2.2 Row/Column(ÐÐ/ÁÐ×é¼þ)
ÐÐ/ÁÐ×é¼þ

RowºÍColumn×é¼þÆäʵºÍweb/rnÖеÄFlex²¼¾Ö£¨µ¯ÐÔºÐ×Ó£©ÌرðÏàËÆ£¬»òÕßÎÒÃÇ¿ÉÒÔ¾ÍÕâôÀí½â¡£Ê¹ÓÃFlex²¼¾ÖµÄͬѧ¶ÔÖ÷ÖáºÍ´ÎÖáµÄ¸ÅÄî¿Ï¶¨¶¼ÒѾʮ·ÖÊìϤ£¬Row×é¼þµÄÖ÷Öá¾ÍÊǺáÏò£¬Column×é¼þµÄÖ÷Öá¾ÍÊÇ×ÝÏò¡£ÇÒËüÃǵĹ¹Ô캯ÊýÊ®·ÖÏàËÆ£¨ÒÑÊ¡ÂÔ²»³£ÓÃÊôÐÔ£©£º
Row({
Key key,
MainAxisAlignment mainAxisAlignment = MainAxisAlignment.start,
CrossAxisAlignment crossAxisAlignment = CrossAxisAlignment.center,
MainAxisSize mainAxisSize = MainAxisSize.max,
List<Widget> children = const <Widget>[],
})
Column({
Key key,
MainAxisAlignment mainAxisAlignment = MainAxisAlignment.start,
CrossAxisAlignment crossAxisAlignment = CrossAxisAlignment.center,
MainAxisSize mainAxisSize = MainAxisSize.max,
List<Widget> children = const <Widget>[],
}) |
2.2.1 mainAxisAlignment
¸ÃÊôÐԵĺ¬ÒåÊÇÖ÷ÖáÅÅÁз½Ê½£¬¸ù¾ÝÉÏÊö¹¹Ô캯Êý¿ÉÒÔÖªµÀRowºÍColumn×é¼þÔÚÖ÷Öá·½ÏòÉÏĬÈ϶¼ÊÇ´Óstart¿ªÊ¼£¬Ò²¾ÍÊÇ˵Row×é¼þĬÈÏ´Ó×óµ½ÓÒ¿ªÊ¼ÅÅÁÐ×Ó×é¼þ£¬Column×é¼þĬÈÏ´ÓÉϵ½Ï¿ªÊ¼ÅÅÁÐ×Ó×é¼þ¡£
µ±È»£¬Ä㻹¿ÉÒÔʹÓÃÆäËûµÄ¿Éѡֵ£º
MainAxisAlignment.start
MainAxisAlignment.end
MainAxisAlignment.center
MainAxisAlignment.spaceBetween
MainAxisAlignment.spaceAround
MainAxisAlignment.spaceEvenly
2.2.2 crossAxisAlignment
¸ÃÊôÐԵĺ¬ÒåÊÇ´ÎÖáÅÅÁз½Ê½£¬¸ù¾ÝÉÏÊö¹¹Ô캯Êý¿ÉÒÔÖªµÀRowºÍColumn×é¼þÔÚ´ÎÖá·½ÏòÉÏĬÈ϶¼ÊǾÓÖС£
ÕâÀïÓÐÒ»µãÐèÒªÌØ±ð×¢Ò⣺ÓÉÓÚColumn×é¼þ´ÎÖá·½ÏòÉÏ£¨¼´Ë®Æ½£©Ä¬ÈÏÊǾÓÖÐ¶ÔÆë£¬ËùÒÔˮƽ·½ÏòÉϲ»»á³ÅÂúÆä¸¸ÈÝÆ÷£¬´ËʱÐèÒªÖ¸¶¨CrossAxisAlignment.stretch²Å¿ÉÒÔ¡£
ÁíÍ⣬crossAxisAlignmentÆäËûµÄ¿ÉѡֵÓУº
crossAxisAlignment.start
crossAxisAlignment.end
crossAxisAlignment.center
crossAxisAlignment.stretch
crossAxisAlignment.baseline
2.2.3 mainAxisSize
×ÖÃæÒâ˼ÉÏÀ´Ëµ£¬¸ÃÊôÐÔÖ¸µÄÊÇÔÚÖ÷ÖáÉϵijߴ硣Æäʵ¾ÍÊÇÖ¸ÔÚÖ÷Öá·½ÏòÉÏ£¬Êǰü¹üÆäÄÚÈÝ£¬»¹ÊdzÅÂúÆä¸¸ÈÝÆ÷¡£ËüµÄ¿ÉѡֵÓÐMainAxisSize.minºÍMainAxisSize.max¡£ÓÉÓÚÆäĬÈÏÖµ¶¼ÊÇMainAxisSize.max£¬ËùÒÔÖ÷Öá·½ÏòÉÏĬÈÏ´óС¶¼ÊǾ¡¿ÉÄܳÅÂú¸¸ÈÝÆ÷µÄ¡£
2.2.4 С½á
ÓÉÓÚRow/Column×é¼þºÍÎÒÃÇÊìϤµÄFlex²¼¾Ö·Ç³£ÏàËÆ£¬ËùÒÔÉÏÊÖÆðÀ´·Ç³£ÈÝÒ×£¬¼¸ºõÁãѧϰ³É±¾¡£
2.3 Stack/Positoned(¾ø¶Ô¶¨Î»²¼¾Ö×é¼þ)

¾ø¶Ô¶¨Î»²¼¾Ö×é¼þ
¾ø¶Ô¶¨Î»²¼¾ÖÔÚweb/rn¿ª·¢ÖÐÒ²ÊÇʹÓÃÆµÂʽϸߵÄÒ»ÖÖ²¼¾Ö·½Ê½£¬FlutterÒ²ÌṩÁËÏàÓ¦µÄ×é¼þʵÏÖ£¬ÐèÒª½«StackºÍPositioned×é¼þ´îÅäÔÚÒ»ÆðʹÓᣱÈÈçÏ·½µÄÕâ¸öÀý×Ó¾ÍÊÇ´´½¨ÁËÒ»¸ö»ÆÉ«µÄºÐ×Ó£¬²¢ÇÒÔÚÆäËĸö½ÇÂä·ÅÖÃÁË4¸öºìÉ«µÄСÕý·½ÐΡ£Stack×é¼þ¾ÍÊǾø¶Ô¶¨Î»µÄÈÝÆ÷£¬Positioned×é¼þͨ¹ýleft£¬top
£¬right£¬bottomËĸö·½ÏòÉϵÄÊôÐÔÖµÀ´¾ö¶¨ÆäÔÚ¸¸ÈÝÆ÷ÖеÄλÖá£
Container(
height: 100,
color: Colors.yellow,
child: Stack(
children: <Widget>[
Positioned(
left: 10,
top: 10,
child: Container(width: 10, height: 10, color:
Colors.red),
),
Positioned(
right: 10,
top: 10,
child: Container(width: 10, height: 10, color:
Colors.red),
),
Positioned(
left: 10,
bottom: 10,
child: Container(width: 10, height: 10, color:
Colors.red),
),
Positioned(
right: 10,
bottom: 10,
child: Container(width: 10, height: 10, color:
Colors.red),
),
],
),
) |
2.4 Text(Îı¾×é¼þ)

Text×é¼þÒ²ÊÇÈÕ³£¿ª·¢ÖÐ×î³£ÓõĻù´¡×é¼þÖ®Ò»£¬ÎÒÃÇͨ³£ÓÃËüÀ´Õ¹Ê¾Îı¾ÐÅÏ¢¡£À´¿´ÏÂÆä¹¹Ô캯Êý£¨ÒÑÊ¡ÂÔ²»³£ÓÃÊôÐÔ£©£º
const Text(
this.data, {
Key key,
this.style,
this.textAlign,
this.softWrap,
this.overflow,
this.maxLines,
}) |
data: ÏÔʾµÄÎı¾ÐÅÏ¢£»
style: Îı¾Ñùʽ£¬FlutterÌṩÁËÒ»¸öTextStyleÀ࣬×î³£ÓõÄfontSize
£¬fontWeight £¬color£¬backgroundColorºÍshadowsµÈÊôÐÔ¶¼ÊÇͨ¹ýËüÉèÖõģ»
textAlign: ÎÄ×Ö¶ÔÆë·½Ê½£¬³£ÓÿÉѡֵÓÐTextAlignµÄleft£¬right£¬centerºÍjustify£»
softWrap: ÎÄ×ÖÊÇ·ñ»»ÐУ»
overflow: µ±ÎÄ×ÖÒç³öµÄʱºò£¬ÒÔºÎÖÖ·½Ê½´¦Àí£¨Ä¬ÈÏÖ±½Ó½Ø¶Ï£©¡£¿ÉѡֵÓÐTextOverflowµÄclip£¬fade£¬ellipsisºÍvisible£»
maxLines: µ±ÎÄ×Ö³¬¹ý×î´óÐÐÊý»¹Ã»ÏÔʾÍêµÄʱºò£¬¾Í»á¸ù¾ÝoverflowÊôÐÔ¾ö¶¨ÈçºÎ½Ø¶Ï´¦Àí¡£
FlutterµÄText×é¼þ×ã¹»Áé»î£¬ÌṩÁ˸÷ÖÖÊôÐÔÈÃÎÒÃǶ¨ÖÆ£¬²»¹ýÒ»°ãÇé¿öÏ£¬ÎÒÃǸü¶àµØÖ»ÐèÏ·½¼¸ÐдúÂë¾Í×ã¹»ÁË£º
Text(
'ÕâÊDzâÊÔÎı¾',
style: TextStyle(
fontSize: 13,
fontWeight: FontWeight.bold,
color: Color(0xFF999999),
),
) |
³ýÁËÉÏÊöµÄÓ¦Óó¡¾°Í⣬ÓÐʱÎÒÃÇ»¹»áÓöµ½¸»Îı¾µÄÐèÇ󣨼´Ò»¶ÎÎı¾ÖУ¬¿ÉÄÜÐèÒª²»Í¬µÄ×ÖÌåÑùʽ£©¡£±ÈÈçÔÚһЩUIÉè¼ÆÖо³£»áÓöµ½±íʾ¼Û¸ñµÄʱºò£¬£¤·ûºÅ±È½ð¶îµÄ×ÖºÅСµã¡£¶ÔÓÚ´ËÀàÐèÇó£¬ÎÒÃÇ¿ÉÒÔÓÃFlutterÌṩµÄText.rich¹¹Ô캯ÊýÀ´´´½¨ÏàÓ¦µÄÎı¾×é¼þ£º
Text.rich(TextSpan(
children: [
TextSpan(
'£¤',
style: TextStyle(
fontSize: 12,
color: Color(0xFFFF7528),
),
),
TextSpan(
'258',
style: TextStyle(
fontSize: 15,
color: Color(0xFFFF7528),
),
),
]
)) |
2.5 Image(ͼƬ×é¼þ)

ImageͼƬ×é¼þ×÷Ϊ·á¸»ÄÚÈݵĻù´¡×é¼þÖ®Ò»£¬ÈÕ³£¿ª·¢ÖеÄʹÓÃÆµÂÊÒ²·Ç³£¸ß¡£¿´ÏÂÆä¹¹Ô캯Êý£¨ÒÑÊ¡ÂÔ²»³£ÓÃÊôÐÔ£©£º
Image({
Key key,
@required this.image,
this.width,
this.height,
this.color,
this.fit,
this.repeat = ImageRepeat.noRepeat,
}) |
image: ͼƬԴ£¬×î³£Óõ½Ö÷ÒªÓÐÁ½ÖÖ£¨AssetImageºÍNetworkImage£©¡£Ê¹ÓÃAssetImage֮ǰ£¬ÐèÒªÔÚpubspec.yamlÎļþÖÐÉùÃ÷ºÃͼƬ×ÊÔ´£¬È»ºó²ÅÄÜʹÓã»¶øNextworkImageÖ¸¶¨Í¼Æ¬µÄÍøÂçµØÖ·¼´¿É£¬Ö÷ÒªÊÇÔÚ¼ÓÔØÒ»Ð©ÍøÂçͼƬʱ»áÓõ½£»
width: ͼƬ¿í¶È£»
height: ͼƬ¸ß¶È£»
color: ͼƬµÄ±³¾°ÑÕÉ«£¬µ±ÍøÂçͼƬδ¼ÓÔØÍê±Ï֮ǰ£¬»áÏÔʾ¸Ã±³¾°ÑÕÉ«£»
fit: µ±ÎÒÃÇÏ£ÍûͼƬ¸ù¾ÝÈÝÆ÷´óС½øÐÐÊÊÅä¶ø²»ÊÇÖ¸¶¨¹Ì¶¨µÄ¿í¸ßֵʱ£¬¿ÉÒÔͨ¹ý¸ÃÊôÐÔÀ´ÊµÏÖ¡£Æä¿ÉѡֵÓÐBoxFitµÄfill£¬contain£¬cover£¬fitWidth£¬fitHeight£¬noneºÍscaleDown£»
repeat: ¾ö¶¨µ±Í¼Æ¬Êµ¼Ê´óС²»×ãÖ¸¶¨´óСʱÊÇ·ñʹÓÃÖØ¸´Ð§¹û¡£
ÁíÍ⣬Flutter»¹ÌṩÁËImage.networkºÍImage.asset¹¹Ô캯Êý£¬ÆäʵÊÇÓï·¨ÌÇ¡£±ÈÈçÏ·½µÄÁ½¶Î´úÂë½á¹ûÊÇÍêȫһÑùµÄ£º
Image(
image: NetworkImage('https://ss1.bdstatic.com /70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=1402367109, 4157195964&fm=27&gp=0.jpg'),
width: 100,
height: 100,
)
Image.network(
'https://ss1.bdstatic.com/70cFuXSh_Q1Ynx GkpoWK1HF6hhy/it/u=1402367109,4157195964& fm=27&gp=0.jpg',
width: 100,
height: 100,
) |
2.6 Icon(ͼ±ê×é¼þ)

Iconͼ±ê×é¼þÏà±ÈÓÚͼƬÓÐ×Å·Å´ó²»»áÊ§ÕæµÄÓÅÊÆ£¬ÔÚÈÕ³£¿ª·¢ÖÐÒ²ÊǾ³£»á±»Óõ½¡£Flutter¸üÊÇÖ±½ÓÄÚÖÃÁËÒ»Ì×Material·ç¸ñµÄͼ±ê£¨Äã¿ÉÒÔÔÚÕâÀïÔ¤ÀÀËùÓеÄͼ±êÀàÐÍ£©¡£¿´Ï¹¹Ô캯Êý£º
const Icon(
this.icon, {
Key key,
this.size,
this.color,
}) |
icon: ͼ±êÀàÐÍ£»
size: ͼ±ê´óС£»
color: ͼ±êÑÕÉ«¡£
3. ²¼¾Öʵս
ͨ¹ýÉÏÒ»½ÚµÄ½éÉÜ£¬ÎÒÃǶÔContainer£¬Row£¬Column£¬Stack£¬Positioned£¬Text£¬ImageºÍIcon×é¼þÓÐÁ˳õ²½µÄÈÏʶ¡£½ÓÏÂÀ´£¬¾ÍÈÃÎÒÃÇͨ¹ýÒ»¸öʵ¼ÊµÄÀý×ÓÀ´¼ÓÉîÀí½âºÍ¼ÇÒä¡£

3.1 ×¼±¸¹¤×÷ - Êý¾ÝÀàÐÍ
¸ù¾ÝÉÏÊö¿¨Æ¬ÖеÄÄÚÈÝ£¬ÎÒÃÇ¿ÉÒÔ¶¨ÒåһЩ×ֶΡ£ÎªÁ˹淶¿ª·¢Á÷³Ì£¬ÎÒÃÇÏȸø¿¨Æ¬¶¨ÒåÒ»¸öÊý¾ÝÀàÐ͵ÄÀ࣬ÕâÑùÔÚºóÐøµÄ¿ª·¢¹ý³ÌÖÐÒ²ÄܸüºÃµØ¶ÔÊý¾Ý½øÐÐMockºÍ¹ÜÀí£º
/// ·¢²¼ÄÚÈÝ
final String publishContent;
/// »Ø¸´ÊýÁ¿
final int replies;
/// ϲ»¶ÊýÁ¿
final int likes;
/// ·ÖÏíÊýÁ¿
final int shares; const PetCardViewModel({
this.coverUrl,
this.userImgUrl,
this.userName,
this.description,
this.topic,
this.publishTime,
this.publishContent,
this.replies,
this.likes,
this.shares,
});
} |
3.2 ´î½¨¹Ç¼Ü£¬²¼¾Ö²ð·Ö

¸ù¾Ý¸øµÄÊÓ¾õͼ£¬ÎÒÃÇ¿ÉÒÔ½«ÕûÌå½øÐвð·Ö£¬Ò»¹²»®·Ö³É4¸ö²¿·Ö£ºCover£¬UserInfo£¬PublishContentºÍInteractionArea¡£Îª´Ë£¬ÎÒÃÇ¿ÉÒÔ´îÆð´úÂëµÄ»ù±¾¹Ç¼Ü£º
class PetCard
extends StatelessWidget {
final PetCardViewModel data;
const PetCard({
Key key,
this.data,
}) : super(key: key);
Widget renderCover() {
}
Widget renderUserInfo() {
}
Widget renderPublishContent() {
} Widget renderInteractionArea() {
} @override
Widget build(BuildContext context) {
return Container(
margin: EdgeInsets.all(16),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(8),
boxShadow: [
BoxShadow(
blurRadius: 6,
spreadRadius: 4,
color: Color.fromARGB(20, 0, 0, 0),
),
],
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
this.renderCover(),
this.renderUserInfo(),
this.renderPublishContent(),
this.renderInteractionArea(),
],
),
);
}
} |
3.3 ·âÃæÇøÓò
ΪÁ˸üºÃµÄ͹ÏÖͼƬµÄЧ¹û£¬ÕâÀï¼ÓÁËÒ»¸öÃɲ㣬ËùÒÔ´Ë´¦¸ÕºÃ¿ÉÒÔÓõÃÉÏStack/Positioned²¼¾ÖºÍLinearGradient½¥±ä£¬Dom½á¹¹ÈçÏ£º

Widget renderCover()
{
return Stack(
fit: StackFit.passthrough,
children: <Widget>[
ClipRRect(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(8),
topRight: Radius.circular(8),
),
child: Image.network(
data.coverUrl,
height: 200,
fit: BoxFit.fitWidth,
),
),
Positioned(
left: 0,
top: 100,
right: 0,
bottom: 0,
child: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [
Color.fromARGB(0, 0, 0, 0),
Color.fromARGB(80, 0, 0, 0),
],
),
),
),
),
],
);
} |
3.4 Óû§ÐÅÏ¢ÇøÓò
Óû§ÐÅÏ¢ÇøÓò¾Í·Ç³£ÊʺÏʹÓÃRowºÍColumn×é¼þÀ´½øÐв¼¾Ö£¬Dom½á¹¹ÈçÏ£º

Widget renderUserInfo()
{
return Container(
margin: EdgeInsets.only(top: 16),
padding: EdgeInsets.symmetric(horizontal: 16),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Row(
children: <Widget>[
CircleAvatar(
radius: 20,
backgroundColor: Color(0xFFCCCCCC),
backgroundImage: NetworkImage(data.userImgUrl),
),
Padding(padding: EdgeInsets.only(left: 8)),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
data.userName,
style: TextStyle(
fontSize: 15,
fontWeight: FontWeight.bold,
color: Color(0xFF333333),
),
),
Padding(padding: EdgeInsets.only(top: 2)),
Text(
data.description,
style: TextStyle(
fontSize: 12,
color: Color(0xFF999999),
),
),
],
),
],
),
Text(
data.publishTime,
style: TextStyle(
fontSize: 13,
color: Color(0xFF999999),
),
),
],
),
);
} |
3.5 ·¢²¼ÄÚÈÝÇøÓò
ͨ¹ýÕâ¿éÇøÓòµÄUIÁ·Ï°£¬ÎÒÃÇ¿ÉÒÔʵ¼ùContainer×é¼þÉèÖò»Í¬µÄborderRadius£¬ÒÔ¼°Text×é¼þÎı¾ÄÚÈݳ¬³öʱµÄ½Ø¶Ï´¦Àí£¬Dom½á¹¹ÈçÏ£º

Widget renderPublishContent()
{
return Container(
margin: EdgeInsets.only(top: 16),
padding: EdgeInsets.symmetric(horizontal: 16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Container(
margin: EdgeInsets.only(bottom: 14),
padding: EdgeInsets.symmetric(horizontal: 8, vertical:
2),
decoration: BoxDecoration(
color: Color(0xFFFFC600),
borderRadius: BorderRadius.only(
topRight: Radius.circular(8),
bottomLeft: Radius.circular(8),
bottomRight: Radius.circular(8),
),
),
child: Text(
'# ${data.topic}',
style: TextStyle(
fontSize: 12,
color: Colors.white,
),
),
),
Text(
data.publishContent,
maxLines: 2,
overflow: TextOverflow.ellipsis,
style: TextStyle(
fontSize: 15,
fontWeight: FontWeight.bold,
color: Color(0xFF333333),
),
),
],
),
);
} |
3.6 »¥¶¯ÇøÓò
ÔÚÕâ¸öÄ£¿é£¬ÎÒÃÇ»áÓõ½Iconͼ±ê×é¼þ£¬¿ÉÒÔ¿ØÖÆÆä´óСºÍÑÕÉ«µÈÊôÐÔ£¬Dom½á¹¹ÈçÏ£º

Widget renderInteractionArea()
{
return Container(
margin: EdgeInsets.symmetric(vertical: 16),
padding: EdgeInsets.symmetric(horizontal: 16),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Row(
children: <Widget>[
Icon(
Icons.message,
size: 16,
color: Color(0xFF999999),
),
Padding(padding: EdgeInsets.only(left: 6)),
Text(
data.replies.toString(),
style: TextStyle(
fontSize: 15,
color: Color(0xFF999999),
),
),
],
),
Row(
children: <Widget>[
Icon(
Icons.favorite,
size: 16,
color: Color(0xFFFFC600),
),
Padding(padding: EdgeInsets.only(left: 6)),
Text(
data.likes.toString(),
style: TextStyle(
fontSize: 15,
color: Color(0xFF999999),
),
),
],
),
Row(
children: <Widget>[
Icon(
Icons.share,
size: 16,
color: Color(0xFF999999),
),
Padding(padding: EdgeInsets.only(left: 6)),
Text(
data.shares.toString(),
style: TextStyle(
fontSize: 15,
color: Color(0xFF999999),
),
),
],
),
],
),
);
} |
3.7 С½á
ͨ¹ýÉÏÃæµÄÒ»¸öÀý×Ó£¬ÎÒÃdzɹ¦µØ°ÑÒ»¸ö¿´ÆðÀ´¸´ÔÓµÄUI½çÃæÒ»²½²½²ð½â£¬½«Ö®Ç°Ìáµ½µÄ×é¼þ¶¼ÓÃÁ˸ö±é£¬²¢ÇÒ×îÖյõ½Á˲»´íµÄЧ¹û¡£Æäʵ£¬ÈÕ³£¿ª·¢ÖÐ90%ÒÔÉϵÄÐèÇó¶¼Àë²»¿ªÉÏÊöÌáµ½µÄ»ù´¡×é¼þ¡£Òò´Ë£¬Ö»ÒªÉÔ¼ÓÁ·Ï°£¬ÊìϤÁËFlutterÖеĻù´¡×é¼þÓ÷¨£¬¾ÍÒѾËãÊÇÂõ³öÁËÒ»´ó²½Å¶~
ÕâÀﻹÓÐÒøÐп¨ºÍÅóÓÑȦµÄUIÁ·Ï°Àý×Ó£¬ÓÉÓÚÆª·ùÔÒò¾Í²»Ìù´úÂëÁË£¬¿ÉÒÔÈ¥github²Ö¿â¿´¡£
4. ×ܽá
±¾ÎÄÊ×ÏȽéÉÜÁËFlutterÖй¹½¨UI½çÃæ×î³£ÓõĻù´¡×é¼þ£¨ÈÝÆ÷£¬ÐУ¬ÁУ¬¾ø¶Ô¶¨Î»²¼¾Ö£¬Îı¾£¬Í¼Æ¬ºÍͼ±ê£©Ó÷¨¡£½Ó×Å£¬½éÉÜÁËÒ»¸ö½Ï¸´ÔÓµÄUIʵսÀý×Ó¡£Í¨¹ý¶ÔDom½á¹¹µÄ²ã²ã²ð½â£¬Ç°ÎÄÌáµ½¹ýµÄ×é¼þµÃµ½Ò»¸ö×ÛºÏÔËÓã¬Ò²ËãÊǹ®¹ÌÁËÇ°ÃæËùѧµÄ¸ÅÄî֪ʶ¡£
²»¹ý×îºó²»µÃ²»Í²ÛÒ»¾ä£ºFlutterµÄǶÌ×ÕæµÄºÜÄÑÊÜ¡£¡£¡£Èç¹û²»¶ÔUI²¼¾Ö½øÐÐÄ£¿é²ð·Ö£¬ÄǾø¶ÔÊÇØ¬ÃΰãµÄÌåÑé¡£¶øÇÒ²»Ïñweb/rn¿ª·¢Ñùʽ¿ÉÒÔµ¥¶À³éÀ룬FlutterÕâÖÖ½«Ñùʽµ±×öÊôÐԵĴ¦Àí·½Ê½£¬Ò»ÑÛ¿´È¥ÕæµÄºÜÄÑÀíÇådom½á¹¹£¬¶ÔÓÚнÓÊÖ´úÂëµÄ¿ª·¢ÈËÔ±¶øÑÔ£¬ÐèÒª·Ñµãʱ¼äÀí½â¡£¡£¡£
|