±à¼ÍƼö: |
±¾ÎÄÀ´×ÔÓÚ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µÄˮƽÏßÉÏÅŲ¼£¬¾Í¿ÉÒÔ¿´µ½ÏÖÔÚÕûÆëµÄЧ¹û¡£
|