Äú¿ÉÒÔ¾èÖú£¬Ö§³ÖÎÒÃǵĹ«ÒæÊÂÒµ¡£

1Ôª 10Ôª 50Ôª





ÈÏÖ¤Â룺  ÑéÖ¤Âë,¿´²»Çå³þ?Çëµã»÷Ë¢ÐÂÑéÖ¤Âë ±ØÌî



  ÇóÖª ÎÄÕ ÎÄ¿â Lib ÊÓÆµ iPerson ¿Î³Ì ÈÏÖ¤ ×Éѯ ¹¤¾ß ½²×ù Model Center   Code  
»áÔ±   
   
 
     
   
 ¶©ÔÄ
  ¾èÖú
FlutterÑùʽºÍ²¼¾Ö¿Ø¼þ¼òÎö
 
  1990  次浏览      27
2019-8-12
 
±à¼­ÍƼö:
±¾ÎÄÀ´×ÔÓÚsegmentfault£¬Ö÷ÒªÏêϸ½éÉÜÁËFlutterµÄ¸÷¸ö¿Ø¼þµÄʹÓü°´úÂëʵÀý£¬Ï£Íû¶ÔÄúÄÜÓÐËù°ïÖú¡£

¿ªÊ¼

¸ãǰ¶ËµÄͬѧ¿ÉÄܶ¼Ï°¹ßÁËCSS¾Ö²¿µÄ˼ά£¬¹ýÈ¥Ò²³öÏÖ¹ýһЩ¸ú²¼¾Ö»òÕßÑùʽÏà¹ØµÄ±êÇ©£¬ÀýÈ磺big, center, font, s, strike, tt, u£»µ«ÊÇĿǰҲ±»CSSËù´úÌæ£¬ÒѾ­²»ÍƼöʹÓᣵ«ÊÇÔÚFlutterÀïÃæ£¬ÊÇûÓÐCSSÕâÑùÒ»¸ö¸ÅÄîµÄ£¬²¼¾ÖºÍÑùʽ¶¼¿ÉÄÜ»áÊÇÒ»¸ö×é¼þ»òÕßÊÇ×é¼þÀïÃæµÄÊôÐÔËù¶¨ÒåºÍʵÏֵ쬶ÔÓÚϰ¹ßдÑùʽµÄǰ¶Ëͬѧ¿ÉÄÜÐèÒªÊÊӦһϡ£

¸öÈË˼¿¼

ÏÖÔÚ¿ÉÄÜÒªÏëһϣ¬FlutterΪɶûÓÐÏñä¯ÀÀÆ÷Ò»Ñù³éÀë³öCSS£¿

ÎÒÃÇÖªµÀÔÚä¯ÀÀÆ÷ÀïÃæJS£¬CSS£¬HTML¸÷˾ÆäÖ°£ºÐÐΪ£¬±íÏֺͽṹ£¬ÒѾ­ÉîÈëÈËÐÄ£¬Ò²±»ºÜ¶àÈËËùÍÆ³ç¡£µ«ÊÇFlutterºÃÏñ·´ÆäµÀ¶øÐÐÖ®£¬ÑùʽôÛºÏÔڽṹÀïÃæ£¬ÕâÑù¾¿¾¹ÓÐɶÒâ˼Ä᣿

Ê×ÏÈÓ¦¸ÃÊÇÒ»¸öÐÔÄܵĿ¼ÂÇ£¬ä¯ÀÀÆ÷½âÎöCSSÆäʵҲÊÇÒ»¸öÐÔÄÜÏûºÄµã£¬Ã»ÓÐCSS½âÎö×ÔȻҲ¿ÉÒÔ¼Ó¿ìÒ³ÃæµÄÏÔʾ¡£

Æä´ÎÔÙÌÖÂÛÒ»ÏÂCSS£¬CSSȷʵ·Ç³£ÊʺÏÃèÊöÑùʽºÍ²¼¾Ö£¬µ«ÊÇÒ²ÓкÜÃ÷ÏÔµÄȱµã£º×÷ÓÃÓòÈ«¾ÖÐÔ£¬´úÂëÈßÓ࣬´úÂëÄÑÒÔÖØÓã¬ÄÑÒÔÄ£¿é»¯µÈ£»ÎÒÃÇÐÞÐÞ²¹²¹£¬ÓÖ´´ÔìÁËless£¬sassµÈ¹¤¾ß°ïÖúÎÒÃÇÈ¥½â¾öÎÊÌ⣬µ«ÊÇ×ÔÉíµÄȱÏÝÒÀÈ»»á´æÔÚ£¬ÉõÖÁÓеã×êÅ£½Ç¼â£¬ÒòΪ´æÔÚÁËCSS£¬ËùÒÔÖ»ÄܸĽøCSS¡£

¶øÔÚFlutter£¬Ã»ÓÐÁËCSS£¬ÒÔÉϵÄÎÊÌâ×ÔÈ»µ´È»Î޴棬ÄÇôÃèÊöÑùʽ»á²»»á±äµÃºÜÂé·³£¿´óµÀÐÐÖ®£¬ÎÒÃǵÄǰ±²ÃÇÔç¾ÍÔÚ´úÂëÉÏ×ܽá³öºÜ¶àÉè¼ÆÄ£Ê½»òÕß¼¼ÊõÈ¥½â¾ö´úÂëÖØÓ㬴úÂëÈßÓ࣬ģ¿é»¯µÄÎÊÌ⣬ΪʲôÎÒÃDz»È¥ÓÃÒѾ­´æÔںܾöøÇÒÐÐÖ®ÓÐЧµÄ¼¼ÊõÈ¥½â¾öÎÊÌâÄá¡£×ÔÈ»°ÑÑùʽôۺϽø½á¹¹»áÔö¼ÓÐÅÏ¢Á¿£¬¶ÔÎÒÃÇÔĶÁ´úÂë¿ÉÄÜ»áÊÇÒ»¸öССµÄÌôÕ½£¬µ«ÊÇÓ¦¸ÃÒ²»áºÜ¿ìÊÊÓ¦ÏÂÀ´µÄ£¬ÎÒÏàÐÅ¡£

ÎÒÃǺܶàʱºò¶¼ÔÚ´´ÔìÐµĹ¤¾ßµÄ½â¾öÎÊÌ⣬ÆäʵҲÓпÉÄÜ´´Ôì³öеÄÎÊÌ⣬ÓÐʱºò»Ø¹é¸ù±¾£¬²»Ò»¶¨ÊÇÒ»¼þ»µÊ¡£

¸÷ÖÖ¸÷ÑùµÄ¿Ø¼þ

Directionality

Ö÷Òª¿ØÖÆÎÄ×Ö·½Ïò

Widget build(BuildContext context) {
return new Container(
color: Colors.white,
child: new Text('ÎÒÊÇÒ»¶ÎÎı¾')
);
}

¼ÓÈë¿Ø¼þºó

Widget build(BuildContext context) {
return new Container(
color: Colors.white,
child: new Directionality(
textDirection: TextDirection.rtl,
child: new Text('ÎÒÊÇÒ»¶ÎÎı¾')
)
);
}

DefaultTextStyle

¸úÎı¾Ïà¹ØµÄ»¹ÓÐÒ»¸öDefaultTextStyle¿Ø¼þ£¬ÌṩÁ˸ü¶àµÄ¿ØÖÆÑ¡ÏtextAlign£¬softWrap£¬styleºÍmaxLinesµÈ£¬¶¼ÊÇ¿ØÖÆÕûÌ壺»»ÐУ¬ÎÄ×Ö¾ÓÖкͶàÐÐÊ¡ÂԵȣ¬Ïà¶ÔstyleÌṩ¶¼ÊÇÎÄ×Ö×ÔÉíÑùʽÏà¹Ø£º×ÖÖØ£¬×ÖÌå´óСµÈ

const TextStyle({
this.inherit: true,
this.color,
this.fontSize,
this.fontWeight,
this.fontStyle,
this.letterSpacing,
this.wordSpacing,
this.textBaseline,
this.height,
this.decoration,
this.decorationColor,
this.decorationStyle,
this.debugLabel,
String fontFamily,
String package,
})

ÑÝʾһÏÂЧ¹û£º

Widget build(BuildContext context) {
return new Container(
color: Colors.white,
child: new Directionality(
textDirection: TextDirection.ltr,
child: new DefaultTextStyle(
style: new TextStyle(
fontSize: 14.0,
color: Colors.blue,
decoration: TextDecoration.underline
),
maxLines: 2,
softWrap: true,
overflow: TextOverflow.ellipsis,
child: new Text('ÎÒÊÇÒ»¶Î³¬³¤µÄÎı¾À²À²À²À²À²À²À²À²À²À²À²À²À²À²À²À²'
'À²À²À²À²À²À²À²À²À²À²À²À²À²À²À²À²À²À²À²À²À²À²À²À²À²À²À²À²À²À²À²À²À²'
'À²À²À²À²À²À²À²À²À²À²À²À²À²À²À²À²À²À²À²À²À²À²À²À²À²À²À²À²À²À²À²À²À²À²'
'À²À²À²À²À²À²À²À²À²À²À²À²À²À²À²À²À²À²')
)
)
);
}

ÆäʵText¿Ø¼þ¾ÍÒѾ­´øÉÏÕâЩÊôÐÔ£º

const Text(this.data, {
Key key,
this.style,
this.textAlign,
this.textDirection,
this.softWrap,
this.overflow,
this.textScaleFactor,
this.maxLines,
})

ΪʲôÓÖÒª¶ÀÁ¢³öÕâЩ¿Ø¼þרÃŹÜÀíÄØ£¬ÎÒÃÇÖªµÀCSSÊôÐÔÀïÃæÓÐЩÊôÐÔʱ¼Ì³Ð¸¸ÔªËصģ¬ÀýÈ磺×ÖÌå´óС£¬ÑÕÉ«µÈ£»ÕâÑùµÄ»°£¬ÎÒÃǺÜÈÝÒ×ͳһһ¸öÄ£¿éÀïÃæµÄÑùʽ£¬²¢²»ÐèҪÿ¸öÔªËØ¶¼ÒªÈ¥ÉèÖÃÒ»±é£¬ÕâÀïµÄÕâЩ¿Ø¼þÒ²ÊÇÆðµ½ÕâÑùµÄ¹¦ÄÜ£¬Æäʵ³ýÁËЩ×ÖÌåÑùʽ»¹ÓÐºÜ¶àµØ·½»áÓÐÕâÖּ̳йØÏµ£¬ÀýÈ磺Ö÷ÌâÑÕÉ«£¬ÓïÑÔÎÄ×ֵȵȡ£ËùÒÔºóÃæText¿Ø¼þºÜÈÝÒ״ӿؼþÊ÷ÉÏÕÒµ½ÕâЩ¸¸¿Ø¼þ£¬»ñÈ¡ËüÃÇÉèÖõÄÊôÐÔ£¬¾ÍÕâÑù¾Í¿ÉÒ԰Ѹ¸¿Ø¼þµÄÑùʽ¼Ì³ÐÏÂÀ´¡£

Ôõô×öµ½µÄÄØ£¬ÎÞÂÛDirectionality»¹ÊÇDefaultTextStyle¶¼ÊÇInheritedWidgetµÄ×ÓÀ࣬InheritedWidgetʵÏÖÁËÒ»¸ö·¢²¼/¶©ÔĵÄģʽ£¬µ±×ӿؼþµ÷ÓÃinheritFromWidgetOfExactType·½·¨»ñÈ¡¸¸¿Ø¼þʱ£¬Í¬Ê±Ò²°Ñ×Ô¼º¼ÓÈëµ½InheritedWidgetµÄ¶©ÔÄÕßÁбíÀïÃæ£¬ËùÒÔµ±InheritedWidgetÊôÐԸıäµÄʱºò£¬¾Í»áµ÷Æð×Ó×é¼þdidChangeDependencies·½·¨È¥Í¨Öª×Ó×é¼þ¡£

CustomPaint

Õâ¸ö¿Ø¼þ¸Ð¾õ±ØÐëµÃ½éÉÜһϣ¬ÒòΪÔÚǰ¶ËÎÒÃÇÓÐÒ»¸öcanvasÔªËØ£¬¿ÉÒÔÌṩ¸øÎÒÃÇÖ±½ÓÈ¥»æÖÆÔªËØ£¬¸øÁËÎÒÃǺܴóµÄÁé»îÐÔ£¬ÄÇôFlutterÖжÔÓ¦µÄÓ¦¸Ã¾ÍÊÇÕâ¸ö¿Ø¼þÁË¡£

ÈçºÎʹÓãº

Ïȼ̳ÐCustomPainter

class CustomPainterSample extends CustomPainter {

double progress;

CustomPainterSample({this.progress: 0.0});

@override
void paint(Canvas canvas, Size size) {
Paint p = new Paint();
p.color = Colors.green;
p.isAntiAlias = true;
p.style = PaintingStyle.fill;
canvas.drawCircle(size.center(const Offset(0.0, 0.0)), size.width / 2 * progress, p);
}

@override
bool shouldRepaint(CustomPainter oldDelegate) {
return true;
}

}

ÕâÀïÎÒ»­ÁËÒ»¸öÂÌÉ«µÄÔ²£¬È»ºó°ÑÕâ¸öCustomPainterSample´«µ½CustomPaint¿Ø¼þ¡£

Widget build(BuildContext context) {
return new Container(
color: Colors.white,
child: new CustomPaint(
painter: new CustomPainterSample(progress: this.progress),
)
);
}

µ±È»ÁË£¬¼ÈÈ»¿ÉÒÔËæ±ã»­µã¶«Î÷£¬×öµã¶¯»­Ò²ÊÇÍ×Í׵ģ¬ºÃÔÙ¼Ó¸ö·Å´óµÄ¶¯»­£¬ÍêÕû´úÂ룺

class SquareFragmentState extends State<SquareFragment> with TickerProviderStateMixin {

double progress = 0.0;

@override
void initState() {
AnimationController ac = new AnimationController(
vsync: this,
duration: const Duration(milliseconds: 10000)
);
ac.addListener(() {
this.setState(() {
this.progress = ac.value;
});
});
ac.forward();
}

@override
Widget build(BuildContext context) {
return new Container(
color: Colors.white,
child: new CustomPaint(
painter: new CustomPainterSample(progress: this.progress),
)
);
}
}

ÕâÀïmixinÁËTickerProviderStateMixin£¬ÀïÃæÓÐÒ»¸öcreateTicker·½·¨£¬Ö÷ÒªÊǼàÌýÿһ֡Éú³ÉÈ»ºó»Øµ÷£¬Ö÷ÒªÊÇÓÉSchedulerBinding.instance.scheduleFrameCallback·½·¨ËùÇý¶¯µÄ¡£

ClipRRect

¼ôÇÐÔªËØµÄ±ß½ç£¬ÕâÀïÀàËÆCSSµÄborder-radiusÊôÐÔ£»

Widget build(BuildContext context) {
return new Container(
color: Colors.white,
child: new Align(
alignment: Alignment.center,
child: new ClipRRect(
borderRadius: const BorderRadius.all(const Radius.circular(30.0)),
child: new Container(
width: 180.0,
height: 180.0,
color: Colors.red,
),
),
),
);
}

Ч¹û£º

°ÑradiusÖµµ÷µ½90£¬±ä³ÉÁËÔ²ÐΣº

ÀàËÆµÄ¿ÉÒÔ¼ôÇÐÔªËØµÄ»¹ÓÐClipOval£¬ClipPath£¬ÕâÀï¾Í²»ÉîÈë½éÉÜÁË¡£

PhysicalModel

ÏÈ¿´Ð§¹û£º

Widget build(BuildContext context) {
return new Container(
color: Colors.white,
child: new Align(
alignment: Alignment.center,
child: new PhysicalModel(
color: Colors.black,
elevation: 6.0,
child: new Container(
width: 180.0,
height: 180.0,
color: Colors.red,
),
),
),
);
}

¿ÉÒÔ¿´µ½ºìÉ«·½¿éµ×ÏÂÓÐÒ»¸öÒõÓ°£¬ÈúìÉ«·½¿éÓÐÒ»ÖÖÐü¸¡µÄ¸Ð¾õ£¬ÓÐmaterial designµÄ·ç¸ñ¡£

Transform

ÀàËÆÓÚCSSµÄtransformÊôÐÔ£¬¿ÉÒÔÌá¹©ÑØ×ÅX,Y»òÕßZÖáÐýת£¬Î»ÒÆÀ­ÉìµÈЧ¹û¡£

Widget build(BuildContext context) {
return new Container(
color: Colors.white,
child: new Align(
alignment: Alignment.center,
child: new Transform(
transform: new Matrix4.rotationZ(PI / 2),
child: new Container(
color: Colors.black,
child: new Text('´¹Ö±ÎÄ×Ö', style: const TextStyle(color: Colors.red),)
)
),
),
);
}

µÃ×¢Òâһϣ¬Transform¿Ø¼þÖеÄtransformHitTestsÊôÐÔ£¬Èç¹ûÎÒÃÇÑØ×ÅXÖáÎ»ÒÆÒ»¸ö°´Å¥£¬Ò»°ãÀ´Ëµ£¬ÎÒÃÇÕÕÑù¿ÉÒÔÖ±½Óµã»÷Î»ÒÆÖ®ºóµÄ°´Å¥£¬ÒòΪtransformHitTestsΪtrueµÄʱºò£¬ÔÚhitTest»áÅжϵã»÷ÂäµãÊÇ·ñÔÚtransfromËù×öµÄ²Ù×÷£¨Ðýת£¬À­Éì»òÕßÎ»ÒÆµÈ£©ºóµÄÇøÓòÀïÃæ£¬µ«ÊÇÈç¹ûΪfalse£¬´Ëʱµã»÷°´Å¥Ô­À´µÄÇøÓòÈÔÈ»»á´¥·¢µã»÷ʼþ£¬µ«ÊÇÖ±½Óµã»÷¾Í²»ÐÐÁË¡£

FractionalTranslation

¿ÉÒÔÌá¹©Î»ÒÆ£¬µ«ÊDz¢Ã»ÓÐTranform¿Ø¼þÌṩÄÇô¶à±ä»»£¬½ö½öÊÇÉÏÏÂ×óÓÒµÄÎ»ÒÆ£¬¶øÇÒÎ»ÒÆµÄ»ù×¼ÊÇÒÔchildµÄ´óС½øÐеġ£

Widget build(BuildContext context) {
return new Container(
color: Colors.white,
alignment: Alignment.center,
child: new FractionalTranslation(
translation: const Offset(1.0, 0.0),
child: new Container(
width: 100.0,
height: 100.0,
color: Colors.red,
),
)
);
}

Ч¹û£º

ºìÉ«·½¿éÍùÓÒ±ßÒÆ¶¯ÁËÒ»¸öÉí룬¾Í¸úCSSÖÐtransfrom: translate(100%, 0)Ч¹ûÒ»ÑùµÄ¡£

RotatedBox

ÐýתºÐ×Ó£¬¿ÉÒÔʹÓÃquarterTurnsÊôÐÔ¿ØÖÆÐýת£¬Ã¿´ÎÐýתquarterTurns * 90¶È¡£

Widget build(BuildContext context) {
return new Container(
color: Colors.white,
alignment: Alignment.center,
child: new RotatedBox(
quarterTurns: -1,
child: new Container(
width: 100.0,
height: 100.0,
color: Colors.red,
child: new Text('ÎÒµ¹×ªÁË'),
),
)
);
}

Padding

ÔÚǰ¶Ëÿ¸öÔªËØ¶¼»ù±¾»áÓÐborder, margin, padding£¬µ«ÊÇÔÚFlutterÀïÃæ¿ÉÄܲ»µÃ²»Í²ÛÁ¬padding¶¼ÒªÓøö¿Ø¼þ£¬Î´ÃâÌ«¹ýÓÚÂé·³¡£¶ÔÓÚ´Ë¿ò¼ÜµÄ¿ª·¢ÕßÃÇÒ²ÓÐ×Ô¼ºÒ»Ì׿´·¨£¬ÔÚFlutterÀïÃæ×éºÏ¼òµ¥µÄ¿Ø¼þȥʵÏÖ¸´ÔӵĿؼþ£¬¶ø²»ÊÇͨ¹ý¼Ì³ÐȥʵÏÖ¿ÉÒÔ˵ÊÇFlutterµÄÖ÷ÒªÉè¼ÆË¼Ï룬ËùÒÔÄã»á·¢ÏÖ¾¡¹ÜContainer¿Ø¼þÌṩÁËpaddingµÄ²ÎÊý£¬µ«ÆäʵËüÒ²±³ºóÒ²ÊÇͨ¹ý´´½¨Padding¿Ø¼þÀ´ÊµÏÖЧ¹ûµÄ¡£

FittedBox

ÔÚCSSÖÐÓÐbackground-positionºÍbackground-sizeÁ½¸öÊôÐÔ¿ØÖƱ³¾°Í¼ÈçºÎƽÆÌ£¬ÀýÈ磺Èç¹û±³¾°Í¼±ÈÔªËØ³ß´ç´ó»òÕßСµÄʱºò£¬ÊÇ·ñÒª½øÐÐÀ­É죬Èç¹ûÒªÀ­É죬ÊÇÀ­ÉìͼƬ¿í¶È»¹ÊÇÀ­ÉìͼƬ¸ß¶ÈÀ´ÊÊÓ¦µÈµÈ¡£

¶øFittedBoxËù×öµÄÊÂÇéÒ²ÊDz¶à£¬ËüÓÐÁ½¸öºÜÖØÒªµÄ²ÎÊý£ºaligment ºÍ fit¡£

fit¿Éȡֵ£º

BoxFit.fill

BoxFit.contain

BoxFit.cover

BoxFit.fitWidth

BoxFit.fitHeight

»ù±¾Õâ¸ö¸úCSSµÄbackground-sizeȡֵ¶¼Ò»ÑùµÄ¡£

¶øaligmentÔòÊÇ¿ØÖÆ£¬µ±×ÓÔªËØ´óСûÓÐÍêȫռÂú¸¸ÔªËصÄʱºò£¬ÈçºÎ¶¨Î»£¬ÊǾÓÖл¹ÊÇ¿¿×ó¿¿ÓÒ¡£

ËäÈ»ÄÃbackground-sizeÀ´×ö¶Ô±È£¬µ«ÊÇbackground-sizeÖ»ÊÇ¿ØÖƱ³¾°Í¼Æ¬£¬¶øFittedBox¼¸ºõ¿ÉÒÔ¶ÔÈκÎÔªËØÆð×÷Óã¬ÒòΪËüÊÇͨ¹ýTransform·Å´óËõС×ÓÔªËØÀ´´ïµ½¸Õ²ÅËù˵µÄЧ¹û¡£

Widget build(BuildContext context) {
return new Container(
color: Colors.white,
alignment: Alignment.center,
child: new Container(
width: 200.0,
height: 100.0,
color: Colors.black
child: new FittedBox(
fit: BoxFit.fitHeight,
alignment: Alignment.bottomRight,
child: new Container(
color: Colors.red,
width: 300.0,
height: 240.0,
alignment: Alignment.center,
child: new Text('AAA'),
),
)
)
);
}

Ч¹û£º

ÕâÀïºìºÐ×Ó´óСÊDZȺںÐ×Ó´óµÄ£¬µ«ÊÇfitΪBoxFit.fitHeight¾Í»áͨ¹ýÀ­Éì¸ß¶ÈÀ´ÊÊÓ¦ºÚºÐ×Ó£¬Èç¹û°ÑfitÊôÐԸijÉBoxFit.fitWidth£¬Ð§¹û¾ÍÊÇÕâÑùµÄ£º

¿ÉÒÔ¿´µ½×ÖÌåÊDZ»Ö±½ÓËõСÁË¡£

SizedBox & ConstrainedBox

Ϊʲô°ÑÁ½¸ö¿Ø¼þÒ»Æð½²ÄØ£¿ÒòΪËüÃǶ¼ÒÀÀµÁËÏàͬµÄRenderObject£ºRenderConstrainedBox£¬¶øRenderConstrainedBoxÖ»ÓÐÒ»¸ö²ÎÊý£ºadditionalConstraints¡£

¶øÕâ¸ö²ÎÊýÔÚperformLayoutÖУº

void performLayout() {
if (child != null) {
child.layout(_additionalConstraints .enforce(constraints), parentUsesSize: true);
size = child.size;
} else {
size = _additionalConstraints.enforce(constraints) .constrain(Size.zero);
}
}

¿É¼ûadditionalConstraintsÊÇÔÚÔ­»ù´¡constraintsÔö¼ÓÁË×Ô¼ºµÄÔ¼Êø£¬µ«ÊDz¢²»»á´òÆÆÔ­À´µÄÔ¼ÊøÌõ¼þ¡£

FractionallySizedBox

Ö÷ÒªÓÐÈý¸ö²ÎÊý£ºaligment, widthFactor ºÍ heightFactor¡£

aligment²ÎÊý¿ØÖÆchildµÄ¶¨Î»£»widthFactor ºÍ heightFactor ¿ØÖÆchildµÄÔ¼Êø£¬Èç¹ûwidthFactor»òÕßheightFactor²»Îªnull£¬»á²úÉúÒ»¸öеÄBoxConstraints£ºËüµÄminWidth ºÍ maxWidthΪԭBoxConstraint.maxWidth widthFactor£»minHeight ºÍ maxHeightΪԭBoxConstraint.maxHeight heightFactor¡£

´úÂ룺

BoxConstraints enforce(BoxConstraints constraints) {
return new BoxConstraints(
minWidth: minWidth.clamp(constraints.minWidth, constraints.maxWidth),
maxWidth: maxWidth.clamp(constraints.minWidth, constraints.maxWidth),
minHeight: minHeight.clamp(constraints.minHeight, constraints.maxHeight),
maxHeight: maxHeight.clamp(constraints.minHeight, constraints.maxHeight)
);
}

Ч¹û£º

¿ÉÒÔ¿´µ½µ±widthFactorºÍheigthFractorʱ£¬ºìÉ«ºÐ×Ó¿í¸ß¶¼ÎªÂÌÉ«µÄÒ»°ë¡£

LimitedBox

¿´Ãû³ÆÒ²ÖªµÀ¸ú¿ØÖƳߴçÓйØÁË£¬Õâ¸ö¿Ø¼þÖ÷ÒªÓÐÁ½¸ö²ÎÊý£ºmaxWidthºÍmaxHeight£¬µ±constraintsÊÇunboundedµÄʱºò£¬Ò²¾ÍÊÇmaxWidthºÍmaxHeight¶¼ÊÇinfiniteµÄʱºò£¬»áÓÃmaxWidthºÍmaxHeightÌæ»»Ô­À´µÄmaxWidthºÍmaxHeight£¬ËùÒÔÈç¹ûcontraintsÊÇboundedµÄʱºò²¢²»»áÆð×÷Óá£

¹Ø¼ü´úÂ룺

BoxConstraints _limitConstraints(BoxConstraints constraints) {
return new BoxConstraints(
minWidth: constraints.minWidth,
maxWidth: constraints.hasBoundedWidth ? constraints.maxWidth : constraints.constrainWidth(maxWidth),
minHeight: constraints.minHeight,
maxHeight: constraints.hasBoundedHeight ? constraints.maxHeight : constraints.constrainHeight(maxHeight)
);
}
@override
void performLayout() {
if (child != null) {
child.layout(_limitConstraints(constraints), parentUsesSize: true);
size = constraints.constrain(child.size);
} else {
size = _limitConstraints(constraints).constrain(Size.zero);
}
}

¶Ô±ÈConstrainedBox£¬Ã÷ÏÔʹÓ÷¶Î§¾ÍûÓÐÄÇô¹ãÁË¡£

OverflowBox

´ÓÇ°ÃæµÄ¼¸¸ö¿Ø¼þ£ºSizedBox£¬ConstrainedBoxºÍLimitedBox·ÖÎöÖªµÀ£¬ÎÒÃÇËÆºõûÓа취´òÆÆÓÉparent´«µÝÏÂÀ´µÄÔ¼ÊøÌõ¼þ£¬µ«ÊÇÎÒÃÇ×Ü»áÓÐһЩÇé¿öÊÇ×Ó×é¼þµÄ³ß´ç´óÓÚ¸¸×é¼þµÄÇé¿ö£¬ÄÇôÔõô½â¾öµÄÄ᣿À´£¬¾Í¿´ÕâÀïµÄOverflowBox¿Ø¼þ£¬Õâ¸ö¿Ø¼þÌṩÁ˼¸¸ö²ÎÊý£ºminWidth£¬minHeight£¬maxWidth£¬maxHeight ºÍ aligment£»ÏÈ¿´´úÂ룺

BoxConstraints _getInnerConstraints(BoxConstraints constraints) {
return new BoxConstraints(
minWidth: _minWidth ?? constraints.minWidth,
maxWidth: _maxWidth ?? constraints.maxWidth,
minHeight: _minHeight ?? constraints.minHeight,
maxHeight: _maxHeight ?? constraints.maxHeight
);
}

void performLayout() {
if (child != null) {
child.layout(_getInnerConstraints(constraints), parentUsesSize: true);
alignChild();
}
}

ÕâÀï¿ÉÒÔ¿´µ½Ö±½ÓʹÓÃÎÒÃÇ´«ÈëµÄ²ÎÊýÌæ»»ÁËÔ­±¾µÄminxWidth£¬maxWidthµÈ£¬ËùÒÔµ×ϵÄ×é¼þ¿ÉÒÔ¸ù¾ÝеÄÔ¼ÊøÌõ¼þÀ´²¼¾Ö¡£

×öÒ»ÏÂdemo:

Widget build(BuildContext context) {
return new Align(
alignment: Alignment.center,
child: new Container(
color: Colors.green,
alignment: Alignment.center,
width: 300.0,
height: 300.0,
child: new OverflowBox(
maxWidth: double.INFINITY,
maxHeight: double.INFINITY,
child: new Container(
height: 600.0,
width: 200.0,
color: Colors.red,
),
)
)
);
}

Ч¹û£º

Èç¹ûûÓÐOverflowBox¿Ø¼þ£¬ºìÉ«µÄºÐ×ÓÊDz»¿ÉÄܳ¬¹ýÂÌÉ«ºÐ×ӵģ»¶øaligment¿ÉÒÔ¿ØÖƺìÉ«ºÐ×ÓÔÚÂÌÉ«ºÐ×ÓÀïÃæµÄ¶¨Î»£¬ÏÖÔÚÊǾÓÖÐÏÔʾµÄ¡£

SizedOverflowBox

¸Õ²ÅOverflowBoxÊÇÒòΪÎÒÃÇÐÞ¸ÄÁËÔ¼ÊøÌõ¼þËùÒÔchild²¼¾Ö´óСȷʵ±»¸Ä±äÁË£¬ËùÒԻᷢÉúÒç³ö£¬¶øSizedOverflowBoxÕâ¸ö¿Ø¼þ²¢²»»á¸Ä±äÔ¼ÊøÌõ¼þ£¬µ«ÊÇËü»¹ÊÇ¿ÉÄܻᷢÉúÒç³ö£¬ÎªÊ²Ã´Ä᣿ÒòΪSizedOverflowBox¿ÉÒÔÈÿؼþ¿´ÉÏÈ¥¡°±äСһµã¡±£¬ÕâÔõÑù×öµ½µÄÄ᣿Õâ¸ö¿Ø¼þÓÐÒ»¸ö²ÎÊý£ºsize£¬Õâ¸ö²ÎÊý¾ÍÊÇÈÃÎÒÃǾö¶¨Õâ¸ö¿Ø¼þ¿´ÉÏÈ¥Ó¦¸Ã¶à´ó¡£

¹Ø¼ü´úÂëÔÚRenderSizedOverflowBoxÀàÖУº

@override
double computeMinIntrinsicWidth(double height) {
return _requestedSize.width;
}

@override
double computeMaxIntrinsicWidth(double height) {
return _requestedSize.width;
}

@override
double computeMinIntrinsicHeight(double width) {
return _requestedSize.height;
}

@override
double computeMaxIntrinsicHeight(double width) {
return _requestedSize.height;
}
void performLayout() {
size = constraints.constrain(_requestedSize);
if (child != null) {
child.layout(constraints);
alignChild();
}
}

ʾÀý´úÂ룺

Widget build(BuildContext context) {
return new Align(
alignment: Alignment.center,
child: new Container(
color: Colors.green,
alignment: Alignment.center,
width: 300.0,
height: 300.0,
child: new SizedOverflowBox(
size: new Size(200.0, 300.0),
child: new Container(
color: Colors.red
)
)
)
);
}

½ØÍ¼:

Offstage

ÔÚCSSÓÐÒ»¸öÊôÐÔvisibility£¬µ±ÉèÖÃΪhiddenʱ£¬ÔªËØÊÇ´æÔÚµ«ÊDz»»á»æÖƳöÀ´£»ÔÚFlutterÖÐOffstageÒ²¿ÉÒÔ×öµ½ÕâÖÖЧ¹û¡£

ÔÚRenderOffstageÀàÖУº

class RenderOffstage extends RenderProxyBox {
...
@override
void performLayout() {
if (offstage) {
child?.layout(constraints);
} else {
super.performLayout();
}
}

@override
bool hitTest(HitTestResult result, { Offset position }) {
return !offstage && super.hitTest(result, position: position);
}

@override
void paint(PaintingContext context, Offset offset) {
if (offstage)
return;
super.paint(context, offset);
}
...
}

¿É¼ûµ±offstageΪtrueʱ£¬²¼¾Ö»¹ÊÇ»á¼ÌÐø½øÐе쬵«ÊÇpaint·½·¨ÀïÃæ»áÖ±½Ó·µ»Ø£¬hitTest·½·¨Ò²»áÖ±½ÓÌø¹ý£¬Ò²¾ÍÊDz»ÄÜÏìÓ¦ÈκÎÊÖÊÆ¡£

AspectRatio

Õâ¸ö¿Ø¼þ¿ÉÒÔÓÃÀ´ÈÃ×ӿؼþ´óСά³ÖÔÚÒ»¸ö¹Ì¶¨¿í¸ß±È£¬ÀýÈ磺16£º9¡£

Ö±½Ó¿´²¼¾ÖËã·¨£º

Size _applyAspectRatio(BoxConstraints constraints) {
if (constraints.isTight)
return constraints.smallest;

double width = constraints.maxWidth;
double height;

// We default to picking the height based on the width, but if the width
// would be infinite, that's not sensible so we try to infer the height
// from the width.
if (width.isFinite) {
height = width / _aspectRatio;
} else {
height = constraints.maxHeight;
width = height * _aspectRatio;
}

// Similar to RenderImage, we iteratively attempt to fit within the given
// constraints while maintaining the given aspect ratio. The order of
// applying the constraints is also biased towards inferring the height
// from the width.

if (width > constraints.maxWidth) {
width = constraints.maxWidth;
height = width / _aspectRatio;
}

if (height > constraints.maxHeight) {
height = constraints.maxHeight;
width = height * _aspectRatio;
}

if (width < constraints.minWidth) {
width = constraints.minWidth;
height = width / _aspectRatio;
}

if (height < constraints.minHeight) {
height = constraints.minHeight;
width = height * _aspectRatio;
}

return constraints.constrain(new Size(width, height));
}

¼òµ¥·ÖÎöһϣº

Èç¹ûconstraintsÊÇtight£¬ÄÇôÕâ¸ö¿Ø¼þ²¢²»»áÆðɶ×÷Óã¬ËùÒÔÕâ¸ö¿Ø¼þÒ»°ãÐèÒªAlign¿Ø¼þ°ü¹üһϡ£

Èç¹û¿í¶È²»ÊÇInifinte£¬ËüÊ×ÏÈ»áÑ¡Ôñ×î´ó¿í¶È£¬·ñÔò¸ù¾ÝmaxHeightÀ´·´ÍÆ¿í¶È¡£

ÍòÒ»¸ß¶È³¬³öÔ¼ÊøÌõ¼þ£¬Ëü¾Í»á·´¹ýÀ´£¬Ñ¡Ôñ×î´óµÄ¸ß¶È·´ÍƳö¿í¶È£¬ÄÇôÍòÒ»¿í¶ÈСÓÚ×îС¿í¶È£¬ËüÓÖ»á¸ù¾Ý×îС¿í¶È¼ÆËã¸ß¶ÈµÈµÈ¡£

µ±È»×îºó»¹ÊÇ»á¸ù¾ÝÔ¼ÊøÌõ¼þÀ´¹æ·¶×îÖÕµÄSize£¬ËùÒÔ¿ÉÄܳöÀ´Ð§¹ûÊǸúÎÒÃÇÔ¤ÉèµÄ¿í¸ß±È²»Ò»Ö£¬µ«ÊÇÕâÖÖÇé¿öÓ¦¸ÃºÜÉÙ¡£

ʾÀý´úÂ룺

Widget build(BuildContext context) {
return new Align(
alignment: Alignment.center,
child: new Container(
color: Colors.green,
alignment: Alignment.center,
width: 300.0,
height: 300.0,
child: new AspectRatio(
aspectRatio: 2.0,
child: new Container(
color: Colors.red,
),
)
)
);
}

½ØÍ¼£º

IntrinsicWidth & IntrinsicHeight

Sizes its child's width to the child's maximum intrinsic width.

˵ʵÔÚÕâ¸ö¿Ø¼þ¿´Á˰ëÌìûÏë³öÓÃÓÚÄÄЩ³¡¾°£¬ËÑÁËһϴúÂ룬»ù±¾¶¼ÓÃÔÚһЩ¸¡´°ÉÏ¡£²¼¾Ö¹ý³ÌÊǵ÷ÓÃgetMaxIntrinsicWidth·½·¨µÝ¹éѯÎÊ×ӿؼþ×î´óµÄintrinsicWidth£¬ÒòΪÕâ¸ö·½·¨ÐèÒªµÝ¹éÏÂÈ¥£¬Èç¹ûÿ¸ö¿Ø¼þ¶¼µ÷ÓñȽϺÄÐÔÄÜ£¬µ±»ñÈ¡µ½intrinsicWidth£¬¾Í»áʹÓÃÕâ¸öÖµ×÷ÎªÔ¼ÊøÌõ¼þ£¨µ±È»Ò²Êܵ½Ô­Ê¼µÄÔ¼ÊøÌõ¼þÔ¼Êø£©£¬È»ºó´«µÝ¸øchild£¬ËùÒÔÕýÈçÉÏÃæµÄ»°Ëù˵£¬µ«ÊÇ»¹ÊÇÏë²»µ½ÄÄЩ³¡¾°»áÐèÒª¡£

Baseline

ÕýÈçͼÉÏ£¬»ùÏß¿ÉÒÔÓ°Ïì×ÅÎÄ×ÖˮƽÅŲ¼£»Èç¹ûÁ½¶ÎÎÄ×ֵĻùÏß²»Ò»Ñù£¬Á½¶ÎÎÄ×ֵĿÉÄÜ»á³öÏÖÒ»ÉÏһϣ¬²¢²»ÊÇÔÚͬһˮƽÏßÉÏÅŲ¼£¬¾ÍÏñÕâÑù£º

ÕâÊÇÁ½¸öText¿Ø¼þ£¬ÎÄ×Ö´óС·Ö±ðÊÇ12dpºÍ32dp£¬ËùÒÔËûÃǵĻùÏßλÖÃÊDz»Ò»ÑùµÄ£¬ËùÒÔÕâÑùµÄÅŲ¼²¢²»ÊÇÎÒÃÇÏëÒªµÄ£¬ËùÒÔÎÒÃÇ¿ÉÒÔʹÓÃBaseline¿Ø¼þÈÃËûÃǶ¼ÔÚÒ»ÑùµÄ»ùÏßÉÏ£¬Ð޸ĺó£º

Õâ²ÅÊÇÎÒÃdz£¼ûµÄ£¬´úÂëÈçÏ£º

Widget build(BuildContext context) {
return new Wrap(
children: <Widget>[
new Baseline(
baseline: 30.0,
baselineType: TextBaseline.alphabetic,
child:
new Text(
'AAAAA',
style: new TextStyle(
fontSize: 12.0,
textBaseline: TextBaseline.alphabetic,
),
)
),
new Baseline(
baseline: 30.0,
baselineType: TextBaseline.alphabetic,
child:
new Text(
'BBB',
style: new TextStyle(
fontSize: 32.0,
textBaseline: TextBaseline.alphabetic,
),
),
)
],
);

°Ñ»ùÏßµÄλÖö¼¶¨ÒåΪ30£¬Á½¶ÎÎÄ×Ö¶¼»áÔÚÀ´30µÄˮƽÏßÉÏÅŲ¼£¬¾Í¿ÉÒÔ¿´µ½ÏÖÔÚÕûÆëµÄЧ¹û¡£

 
   
1990 ´Îä¯ÀÀ       27
Ïà¹ØÎÄÕÂ

Éî¶È½âÎö£ºÇåÀíÀôúÂë
ÈçºÎ±àд³öÓµ±§±ä»¯µÄ´úÂë
ÖØ¹¹-ʹ´úÂë¸ü¼ò½àÓÅÃÀ
ÍŶÓÏîÄ¿¿ª·¢"±àÂë¹æ·¶"ϵÁÐÎÄÕÂ
Ïà¹ØÎĵµ

ÖØ¹¹-¸ÄÉÆ¼ÈÓдúÂëµÄÉè¼Æ
Èí¼þÖØ¹¹v2
´úÂëÕû½àÖ®µÀ
¸ßÖÊÁ¿±à³Ì¹æ·¶
Ïà¹Ø¿Î³Ì

»ùÓÚHTML5¿Í»§¶Ë¡¢Web¶ËµÄÓ¦Óÿª·¢
HTML 5+CSS ¿ª·¢
ǶÈëʽC¸ßÖÊÁ¿±à³Ì
C++¸ß¼¶±à³Ì