Flutter stack小部件 - SinglechildScrollview引起问题
我的stack widget( fancy_on_boarding )和/或基于剪裁模式在景观模式下脱离。有什么方法可以解决,以便小部件只是在景观中滚动而我没有溢出错误?下面的背景:
我尝试像在其他小部件中所做的那样添加单个杂货店,但是切断了很多东西,但不再刷新。请参阅此处:
library fancy_on_boarding;
import 'dart:async';
import 'dart:ui' as ui;
import 'package:fancy_on_boarding/src/fancy_page.dart';
import 'package:fancy_on_boarding/src/page_dragger.dart';
import 'package:fancy_on_boarding/src/page_model.dart';
import 'package:fancy_on_boarding/src/page_reveal.dart';
import 'package:fancy_on_boarding/src/pager_indicator.dart';
import 'package:flutter/material.dart';
class FancyOnBoarding extends StatefulWidget {
final List<PageModel> pageList;
final VoidCallback onDoneButtonPressed;
final VoidCallback onSkipButtonPressed;
final String doneButtonText;
final ShapeBorder doneButtonShape;
final TextStyle doneButtonTextStyle;
final Color doneButtonBackgroundColor;
final String skipButtonText;
final TextStyle skipButtonTextStyle;
final Color skipButtonColor;
final bool showSkipButton;
final double bottomMargin;
final Widget doneButton;
final Widget skipButton;
FancyOnBoarding({
@required this.pageList,
@required this.onDoneButtonPressed,
this.onSkipButtonPressed,
this.doneButtonText = "Done",
this.doneButtonShape,
this.doneButtonTextStyle,
this.doneButtonBackgroundColor,
this.skipButtonText = "Skip",
this.skipButtonTextStyle,
this.skipButtonColor,
this.showSkipButton = true,
this.bottomMargin = 8.0,
this.doneButton,
this.skipButton,
}) : assert(pageList.length != 0 && onDoneButtonPressed != null);
@override
_FancyOnBoardingState createState() => _FancyOnBoardingState();
}
class _FancyOnBoardingState extends State<FancyOnBoarding>
with TickerProviderStateMixin {
StreamController<SlideUpdate> slideUpdateStream;
AnimatedPageDragger animatedPageDragger;
List<PageModel> pageList;
int activeIndex = 0;
int nextPageIndex = 0;
SlideDirection slideDirection = SlideDirection.none;
double slidePercent = 0.0;
bool get isRTL => ui.window.locale.languageCode.toLowerCase() == "ar";
@override
void initState() {
super.initState();
this.pageList = widget.pageList;
this.slideUpdateStream = StreamController<SlideUpdate>();
_listenSlideUpdate();
}
@override
Widget build(BuildContext context) {
return SingleChildScrollView(
child: Stack(
overflow: Overflow.visible,
children: [
FancyPage(
model: pageList[activeIndex],
percentVisible: 1.0,
),
PageReveal(
revealPercent: slidePercent,
child: FancyPage(
model: pageList[nextPageIndex],
percentVisible: slidePercent,
),
),
Positioned(
bottom: widget.bottomMargin,
child: PagerIndicator(
isRtl: isRTL,
viewModel: PagerIndicatorViewModel(
pageList,
activeIndex,
slideDirection,
slidePercent,
),
),
),
PageDragger(
pageLength: pageList.length - 1,
currentIndex: activeIndex,
canDragLeftToRight: activeIndex > 0,
canDragRightToLeft: activeIndex < pageList.length - 1,
slideUpdateStream: this.slideUpdateStream,
),
Padding(
padding: EdgeInsets.only(top: 425.0),
child: Align(
alignment: Alignment.bottomCenter,
child: Opacity(
opacity: opacity,
child: widget.doneButton ??
FlatButton(
height: 45,
shape: widget.doneButtonShape ??
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30.0)),
color: widget.doneButtonBackgroundColor ??
const Color(0xffE7C24A), //0x88FFFFFF),
child: Text(
widget.doneButtonText,
style: widget.doneButtonTextStyle ??
const TextStyle(
fontFamily: 'Title',
color: Color(0xff012A4C), //Colors.white,
fontSize: 22.0,
),
),
onPressed:
opacity == 1.0 ? widget.onDoneButtonPressed : () {},
),
),
// ),
),
),
widget.showSkipButton
? Padding(
padding: EdgeInsets.only(top: 425.0),
child: Align(
alignment: Alignment.bottomCenter,
child: widget.skipButton ??
FlatButton(
height: 25,
shape: widget.doneButtonShape ??
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30.0)),
color: widget.skipButtonColor ??
const Color(0xffE7C24A), //0x88FFFFFF),
child: Text(
widget.skipButtonText,
style: widget.skipButtonTextStyle ??
const TextStyle(
fontFamily: 'Title',
color: Color(0xff012A4C), //0xffE7C24A
fontSize: 18.0,
),
),
onPressed: widget.onSkipButtonPressed,
),
))
: Offstage()
],
));
}
_listenSlideUpdate() {
slideUpdateStream.stream.listen((SlideUpdate event) {
setState(() {
if (event.updateType == UpdateType.dragging) {
slideDirection = event.direction;
slidePercent = event.slidePercent;
if (slideDirection == SlideDirection.leftToRight) {
nextPageIndex = activeIndex - 1;
} else if (slideDirection == SlideDirection.rightToLeft) {
nextPageIndex = activeIndex + 1;
} else {
nextPageIndex = activeIndex;
}
} else if (event.updateType == UpdateType.doneDragging) {
if (slidePercent > 0.5) {
animatedPageDragger = AnimatedPageDragger(
slideDirection: slideDirection,
transitionGoal: TransitionGoal.open,
slidePercent: slidePercent,
slideUpdateStream: slideUpdateStream,
vsync: this,
);
} else {
animatedPageDragger = AnimatedPageDragger(
slideDirection: slideDirection,
transitionGoal: TransitionGoal.close,
slidePercent: slidePercent,
slideUpdateStream: slideUpdateStream,
vsync: this,
);
nextPageIndex = activeIndex;
}
animatedPageDragger.run();
} else if (event.updateType == UpdateType.animating) {
slideDirection = event.direction;
slidePercent = event.slidePercent;
} else if (event.updateType == UpdateType.doneAnimating) {
activeIndex = nextPageIndex;
slideDirection = SlideDirection.none;
slidePercent = 0.0;
animatedPageDragger.dispose();
}
});
});
}
double get opacity {
if (pageList.length - 2 == activeIndex &&
slideDirection == SlideDirection.rightToLeft) return slidePercent;
if (pageList.length - 1 == activeIndex &&
slideDirection == SlideDirection.leftToRight) return 1 - slidePercent;
if (pageList.length - 1 == activeIndex) return 1.0;
return 0.0;
}
@override
void dispose() {
slideUpdateStream?.close();
super.dispose();
}
}
与此代码相比,外观和工作方式很好:
library fancy_on_boarding;
import 'dart:async';
import 'dart:ui' as ui;
import 'package:fancy_on_boarding/src/fancy_page.dart';
import 'package:fancy_on_boarding/src/page_dragger.dart';
import 'package:fancy_on_boarding/src/page_model.dart';
import 'package:fancy_on_boarding/src/page_reveal.dart';
import 'package:fancy_on_boarding/src/pager_indicator.dart';
import 'package:flutter/material.dart';
class FancyOnBoarding extends StatefulWidget {
final List<PageModel> pageList;
final VoidCallback onDoneButtonPressed;
final VoidCallback onSkipButtonPressed;
final String doneButtonText;
final ShapeBorder doneButtonShape;
final TextStyle doneButtonTextStyle;
final Color doneButtonBackgroundColor;
final String skipButtonText;
final TextStyle skipButtonTextStyle;
final Color skipButtonColor;
final bool showSkipButton;
final double bottomMargin;
final Widget doneButton;
final Widget skipButton;
FancyOnBoarding({
@required this.pageList,
@required this.onDoneButtonPressed,
this.onSkipButtonPressed,
this.doneButtonText = "Done",
this.doneButtonShape,
this.doneButtonTextStyle,
this.doneButtonBackgroundColor,
this.skipButtonText = "Skip",
this.skipButtonTextStyle,
this.skipButtonColor,
this.showSkipButton = true,
this.bottomMargin = 8.0,
this.doneButton,
this.skipButton,
}) : assert(pageList.length != 0 && onDoneButtonPressed != null);
@override
_FancyOnBoardingState createState() => _FancyOnBoardingState();
}
class _FancyOnBoardingState extends State<FancyOnBoarding>
with TickerProviderStateMixin {
StreamController<SlideUpdate> slideUpdateStream;
AnimatedPageDragger animatedPageDragger;
List<PageModel> pageList;
int activeIndex = 0;
int nextPageIndex = 0;
SlideDirection slideDirection = SlideDirection.none;
double slidePercent = 0.0;
bool get isRTL => ui.window.locale.languageCode.toLowerCase() == "ar";
@override
void initState() {
super.initState();
this.pageList = widget.pageList;
this.slideUpdateStream = StreamController<SlideUpdate>();
_listenSlideUpdate();
}
@override
Widget build(BuildContext context) {
return
Stack(
clipBehavior: Clip.hardEdge,
children: [
FancyPage(
model: pageList[activeIndex],
percentVisible: 1.0,
),
PageReveal(
revealPercent: slidePercent,
child: FancyPage(
model: pageList[nextPageIndex],
percentVisible: slidePercent,
),
),
Positioned(
bottom: widget.bottomMargin,
child: PagerIndicator(
isRtl: isRTL,
viewModel: PagerIndicatorViewModel(
pageList,
activeIndex,
slideDirection,
slidePercent,
),
),
),
PageDragger(
pageLength: pageList.length - 1,
currentIndex: activeIndex,
canDragLeftToRight: activeIndex > 0,
canDragRightToLeft: activeIndex < pageList.length - 1,
slideUpdateStream: this.slideUpdateStream,
),
Padding(
padding: EdgeInsets.only(top: 425.0),
child: Align(
alignment: Alignment.bottomCenter,
child: Opacity(
opacity: opacity,
child: widget.doneButton ??
FlatButton(
height: 45,
shape: widget.doneButtonShape ??
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30.0)),
color: widget.doneButtonBackgroundColor ??
const Color(0xffE7C24A), //0x88FFFFFF),
child: Text(
widget.doneButtonText,
style: widget.doneButtonTextStyle ??
const TextStyle(
fontFamily: 'Title',
color: Color(0xff012A4C),
fontSize: 22.0,
),
),
onPressed:
opacity == 1.0 ? widget.onDoneButtonPressed : () {},
),
),
),
),
widget.showSkipButton
? Padding(
padding: EdgeInsets.only(top: 425.0),
child: Align(
alignment: Alignment.bottomCenter,
child: widget.skipButton ??
FlatButton(
height: 25,
shape: widget.doneButtonShape ??
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30.0)),
color: widget.skipButtonColor ??
const Color(0xffE7C24A),
child: Text(
widget.skipButtonText,
style: widget.skipButtonTextStyle ??
const TextStyle(
fontFamily: 'Title',
color: Color(0xff012A4C),
fontSize: 18.0,
),
),
onPressed: widget.onSkipButtonPressed,
),
))
: Offstage()
],
);
}
_listenSlideUpdate() {
slideUpdateStream.stream.listen((SlideUpdate event) {
setState(() {
if (event.updateType == UpdateType.dragging) {
slideDirection = event.direction;
slidePercent = event.slidePercent;
if (slideDirection == SlideDirection.leftToRight) {
nextPageIndex = activeIndex - 1;
} else if (slideDirection == SlideDirection.rightToLeft) {
nextPageIndex = activeIndex + 1;
} else {
nextPageIndex = activeIndex;
}
} else if (event.updateType == UpdateType.doneDragging) {
if (slidePercent > 0.5) {
animatedPageDragger = AnimatedPageDragger(
slideDirection: slideDirection,
transitionGoal: TransitionGoal.open,
slidePercent: slidePercent,
slideUpdateStream: slideUpdateStream,
vsync: this,
);
} else {
animatedPageDragger = AnimatedPageDragger(
slideDirection: slideDirection,
transitionGoal: TransitionGoal.close,
slidePercent: slidePercent,
slideUpdateStream: slideUpdateStream,
vsync: this,
);
nextPageIndex = activeIndex;
}
animatedPageDragger.run();
} else if (event.updateType == UpdateType.animating) {
slideDirection = event.direction;
slidePercent = event.slidePercent;
} else if (event.updateType == UpdateType.doneAnimating) {
activeIndex = nextPageIndex;
slideDirection = SlideDirection.none;
slidePercent = 0.0;
animatedPageDragger.dispose();
}
});
});
}
double get opacity {
if (pageList.length - 2 == activeIndex &&
slideDirection == SlideDirection.rightToLeft) return slidePercent;
if (pageList.length - 1 == activeIndex &&
slideDirection == SlideDirection.leftToRight) return 1 - slidePercent;
if (pageList.length - 1 == activeIndex) return 1.0;
return 0.0;
}
@override
void dispose() {
slideUpdateStream?.close();
super.dispose();
}
}
我从另一个类中调用此小部件,如下所示:
return Scaffold(
body: FancyOnBoarding(
doneButton: TwinkleButton(
buttonWidth: 230,
buttonTitle: Text(
'CREATE',
style: TextStyle(
fontFamily: 'Title',
color: Color(0xff012A4C), //0xff012A4C
fontSize: 18,
),
),
buttonColor: Color(0xffE7C24A),
onclickButtonFunction: () async {
// go();
}),
skipButton: TwinkleButton(
// buttonHeight: 35,
buttonWidth: 230,
buttonTitle: Text(
'CREATE',
style: TextStyle(
fontFamily: 'Title',
color: Color(0xff012A4C), //0xff012A4C
fontSize: 18,
),
),
buttonColor: Color(0xffE7C24A),
onclickButtonFunction: () async {
go();
}),
pageList: pageList,
onDoneButtonPressed: () => go(),
onSkipButtonPressed: () => go(),
));
My stack widget (fancy_on_boarding) was overflowing and/or getting cut off in landscape mode based on the clipping behavior. Any way to resolve so that the widget just scrolls in landscape and I don't get an overflow error? Background below:
I tried to add a SingleChildScrollView as I've done in other widgets, but a lot was cut off and it no longer swipes. See here:
library fancy_on_boarding;
import 'dart:async';
import 'dart:ui' as ui;
import 'package:fancy_on_boarding/src/fancy_page.dart';
import 'package:fancy_on_boarding/src/page_dragger.dart';
import 'package:fancy_on_boarding/src/page_model.dart';
import 'package:fancy_on_boarding/src/page_reveal.dart';
import 'package:fancy_on_boarding/src/pager_indicator.dart';
import 'package:flutter/material.dart';
class FancyOnBoarding extends StatefulWidget {
final List<PageModel> pageList;
final VoidCallback onDoneButtonPressed;
final VoidCallback onSkipButtonPressed;
final String doneButtonText;
final ShapeBorder doneButtonShape;
final TextStyle doneButtonTextStyle;
final Color doneButtonBackgroundColor;
final String skipButtonText;
final TextStyle skipButtonTextStyle;
final Color skipButtonColor;
final bool showSkipButton;
final double bottomMargin;
final Widget doneButton;
final Widget skipButton;
FancyOnBoarding({
@required this.pageList,
@required this.onDoneButtonPressed,
this.onSkipButtonPressed,
this.doneButtonText = "Done",
this.doneButtonShape,
this.doneButtonTextStyle,
this.doneButtonBackgroundColor,
this.skipButtonText = "Skip",
this.skipButtonTextStyle,
this.skipButtonColor,
this.showSkipButton = true,
this.bottomMargin = 8.0,
this.doneButton,
this.skipButton,
}) : assert(pageList.length != 0 && onDoneButtonPressed != null);
@override
_FancyOnBoardingState createState() => _FancyOnBoardingState();
}
class _FancyOnBoardingState extends State<FancyOnBoarding>
with TickerProviderStateMixin {
StreamController<SlideUpdate> slideUpdateStream;
AnimatedPageDragger animatedPageDragger;
List<PageModel> pageList;
int activeIndex = 0;
int nextPageIndex = 0;
SlideDirection slideDirection = SlideDirection.none;
double slidePercent = 0.0;
bool get isRTL => ui.window.locale.languageCode.toLowerCase() == "ar";
@override
void initState() {
super.initState();
this.pageList = widget.pageList;
this.slideUpdateStream = StreamController<SlideUpdate>();
_listenSlideUpdate();
}
@override
Widget build(BuildContext context) {
return SingleChildScrollView(
child: Stack(
overflow: Overflow.visible,
children: [
FancyPage(
model: pageList[activeIndex],
percentVisible: 1.0,
),
PageReveal(
revealPercent: slidePercent,
child: FancyPage(
model: pageList[nextPageIndex],
percentVisible: slidePercent,
),
),
Positioned(
bottom: widget.bottomMargin,
child: PagerIndicator(
isRtl: isRTL,
viewModel: PagerIndicatorViewModel(
pageList,
activeIndex,
slideDirection,
slidePercent,
),
),
),
PageDragger(
pageLength: pageList.length - 1,
currentIndex: activeIndex,
canDragLeftToRight: activeIndex > 0,
canDragRightToLeft: activeIndex < pageList.length - 1,
slideUpdateStream: this.slideUpdateStream,
),
Padding(
padding: EdgeInsets.only(top: 425.0),
child: Align(
alignment: Alignment.bottomCenter,
child: Opacity(
opacity: opacity,
child: widget.doneButton ??
FlatButton(
height: 45,
shape: widget.doneButtonShape ??
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30.0)),
color: widget.doneButtonBackgroundColor ??
const Color(0xffE7C24A), //0x88FFFFFF),
child: Text(
widget.doneButtonText,
style: widget.doneButtonTextStyle ??
const TextStyle(
fontFamily: 'Title',
color: Color(0xff012A4C), //Colors.white,
fontSize: 22.0,
),
),
onPressed:
opacity == 1.0 ? widget.onDoneButtonPressed : () {},
),
),
// ),
),
),
widget.showSkipButton
? Padding(
padding: EdgeInsets.only(top: 425.0),
child: Align(
alignment: Alignment.bottomCenter,
child: widget.skipButton ??
FlatButton(
height: 25,
shape: widget.doneButtonShape ??
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30.0)),
color: widget.skipButtonColor ??
const Color(0xffE7C24A), //0x88FFFFFF),
child: Text(
widget.skipButtonText,
style: widget.skipButtonTextStyle ??
const TextStyle(
fontFamily: 'Title',
color: Color(0xff012A4C), //0xffE7C24A
fontSize: 18.0,
),
),
onPressed: widget.onSkipButtonPressed,
),
))
: Offstage()
],
));
}
_listenSlideUpdate() {
slideUpdateStream.stream.listen((SlideUpdate event) {
setState(() {
if (event.updateType == UpdateType.dragging) {
slideDirection = event.direction;
slidePercent = event.slidePercent;
if (slideDirection == SlideDirection.leftToRight) {
nextPageIndex = activeIndex - 1;
} else if (slideDirection == SlideDirection.rightToLeft) {
nextPageIndex = activeIndex + 1;
} else {
nextPageIndex = activeIndex;
}
} else if (event.updateType == UpdateType.doneDragging) {
if (slidePercent > 0.5) {
animatedPageDragger = AnimatedPageDragger(
slideDirection: slideDirection,
transitionGoal: TransitionGoal.open,
slidePercent: slidePercent,
slideUpdateStream: slideUpdateStream,
vsync: this,
);
} else {
animatedPageDragger = AnimatedPageDragger(
slideDirection: slideDirection,
transitionGoal: TransitionGoal.close,
slidePercent: slidePercent,
slideUpdateStream: slideUpdateStream,
vsync: this,
);
nextPageIndex = activeIndex;
}
animatedPageDragger.run();
} else if (event.updateType == UpdateType.animating) {
slideDirection = event.direction;
slidePercent = event.slidePercent;
} else if (event.updateType == UpdateType.doneAnimating) {
activeIndex = nextPageIndex;
slideDirection = SlideDirection.none;
slidePercent = 0.0;
animatedPageDragger.dispose();
}
});
});
}
double get opacity {
if (pageList.length - 2 == activeIndex &&
slideDirection == SlideDirection.rightToLeft) return slidePercent;
if (pageList.length - 1 == activeIndex &&
slideDirection == SlideDirection.leftToRight) return 1 - slidePercent;
if (pageList.length - 1 == activeIndex) return 1.0;
return 0.0;
}
@override
void dispose() {
slideUpdateStream?.close();
super.dispose();
}
}
Looks and works great in portrait mode with this code:
library fancy_on_boarding;
import 'dart:async';
import 'dart:ui' as ui;
import 'package:fancy_on_boarding/src/fancy_page.dart';
import 'package:fancy_on_boarding/src/page_dragger.dart';
import 'package:fancy_on_boarding/src/page_model.dart';
import 'package:fancy_on_boarding/src/page_reveal.dart';
import 'package:fancy_on_boarding/src/pager_indicator.dart';
import 'package:flutter/material.dart';
class FancyOnBoarding extends StatefulWidget {
final List<PageModel> pageList;
final VoidCallback onDoneButtonPressed;
final VoidCallback onSkipButtonPressed;
final String doneButtonText;
final ShapeBorder doneButtonShape;
final TextStyle doneButtonTextStyle;
final Color doneButtonBackgroundColor;
final String skipButtonText;
final TextStyle skipButtonTextStyle;
final Color skipButtonColor;
final bool showSkipButton;
final double bottomMargin;
final Widget doneButton;
final Widget skipButton;
FancyOnBoarding({
@required this.pageList,
@required this.onDoneButtonPressed,
this.onSkipButtonPressed,
this.doneButtonText = "Done",
this.doneButtonShape,
this.doneButtonTextStyle,
this.doneButtonBackgroundColor,
this.skipButtonText = "Skip",
this.skipButtonTextStyle,
this.skipButtonColor,
this.showSkipButton = true,
this.bottomMargin = 8.0,
this.doneButton,
this.skipButton,
}) : assert(pageList.length != 0 && onDoneButtonPressed != null);
@override
_FancyOnBoardingState createState() => _FancyOnBoardingState();
}
class _FancyOnBoardingState extends State<FancyOnBoarding>
with TickerProviderStateMixin {
StreamController<SlideUpdate> slideUpdateStream;
AnimatedPageDragger animatedPageDragger;
List<PageModel> pageList;
int activeIndex = 0;
int nextPageIndex = 0;
SlideDirection slideDirection = SlideDirection.none;
double slidePercent = 0.0;
bool get isRTL => ui.window.locale.languageCode.toLowerCase() == "ar";
@override
void initState() {
super.initState();
this.pageList = widget.pageList;
this.slideUpdateStream = StreamController<SlideUpdate>();
_listenSlideUpdate();
}
@override
Widget build(BuildContext context) {
return
Stack(
clipBehavior: Clip.hardEdge,
children: [
FancyPage(
model: pageList[activeIndex],
percentVisible: 1.0,
),
PageReveal(
revealPercent: slidePercent,
child: FancyPage(
model: pageList[nextPageIndex],
percentVisible: slidePercent,
),
),
Positioned(
bottom: widget.bottomMargin,
child: PagerIndicator(
isRtl: isRTL,
viewModel: PagerIndicatorViewModel(
pageList,
activeIndex,
slideDirection,
slidePercent,
),
),
),
PageDragger(
pageLength: pageList.length - 1,
currentIndex: activeIndex,
canDragLeftToRight: activeIndex > 0,
canDragRightToLeft: activeIndex < pageList.length - 1,
slideUpdateStream: this.slideUpdateStream,
),
Padding(
padding: EdgeInsets.only(top: 425.0),
child: Align(
alignment: Alignment.bottomCenter,
child: Opacity(
opacity: opacity,
child: widget.doneButton ??
FlatButton(
height: 45,
shape: widget.doneButtonShape ??
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30.0)),
color: widget.doneButtonBackgroundColor ??
const Color(0xffE7C24A), //0x88FFFFFF),
child: Text(
widget.doneButtonText,
style: widget.doneButtonTextStyle ??
const TextStyle(
fontFamily: 'Title',
color: Color(0xff012A4C),
fontSize: 22.0,
),
),
onPressed:
opacity == 1.0 ? widget.onDoneButtonPressed : () {},
),
),
),
),
widget.showSkipButton
? Padding(
padding: EdgeInsets.only(top: 425.0),
child: Align(
alignment: Alignment.bottomCenter,
child: widget.skipButton ??
FlatButton(
height: 25,
shape: widget.doneButtonShape ??
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30.0)),
color: widget.skipButtonColor ??
const Color(0xffE7C24A),
child: Text(
widget.skipButtonText,
style: widget.skipButtonTextStyle ??
const TextStyle(
fontFamily: 'Title',
color: Color(0xff012A4C),
fontSize: 18.0,
),
),
onPressed: widget.onSkipButtonPressed,
),
))
: Offstage()
],
);
}
_listenSlideUpdate() {
slideUpdateStream.stream.listen((SlideUpdate event) {
setState(() {
if (event.updateType == UpdateType.dragging) {
slideDirection = event.direction;
slidePercent = event.slidePercent;
if (slideDirection == SlideDirection.leftToRight) {
nextPageIndex = activeIndex - 1;
} else if (slideDirection == SlideDirection.rightToLeft) {
nextPageIndex = activeIndex + 1;
} else {
nextPageIndex = activeIndex;
}
} else if (event.updateType == UpdateType.doneDragging) {
if (slidePercent > 0.5) {
animatedPageDragger = AnimatedPageDragger(
slideDirection: slideDirection,
transitionGoal: TransitionGoal.open,
slidePercent: slidePercent,
slideUpdateStream: slideUpdateStream,
vsync: this,
);
} else {
animatedPageDragger = AnimatedPageDragger(
slideDirection: slideDirection,
transitionGoal: TransitionGoal.close,
slidePercent: slidePercent,
slideUpdateStream: slideUpdateStream,
vsync: this,
);
nextPageIndex = activeIndex;
}
animatedPageDragger.run();
} else if (event.updateType == UpdateType.animating) {
slideDirection = event.direction;
slidePercent = event.slidePercent;
} else if (event.updateType == UpdateType.doneAnimating) {
activeIndex = nextPageIndex;
slideDirection = SlideDirection.none;
slidePercent = 0.0;
animatedPageDragger.dispose();
}
});
});
}
double get opacity {
if (pageList.length - 2 == activeIndex &&
slideDirection == SlideDirection.rightToLeft) return slidePercent;
if (pageList.length - 1 == activeIndex &&
slideDirection == SlideDirection.leftToRight) return 1 - slidePercent;
if (pageList.length - 1 == activeIndex) return 1.0;
return 0.0;
}
@override
void dispose() {
slideUpdateStream?.close();
super.dispose();
}
}
I am calling this Widget from another class as shown below:
return Scaffold(
body: FancyOnBoarding(
doneButton: TwinkleButton(
buttonWidth: 230,
buttonTitle: Text(
'CREATE',
style: TextStyle(
fontFamily: 'Title',
color: Color(0xff012A4C), //0xff012A4C
fontSize: 18,
),
),
buttonColor: Color(0xffE7C24A),
onclickButtonFunction: () async {
// go();
}),
skipButton: TwinkleButton(
// buttonHeight: 35,
buttonWidth: 230,
buttonTitle: Text(
'CREATE',
style: TextStyle(
fontFamily: 'Title',
color: Color(0xff012A4C), //0xff012A4C
fontSize: 18,
),
),
buttonColor: Color(0xffE7C24A),
onclickButtonFunction: () async {
go();
}),
pageList: pageList,
onDoneButtonPressed: () => go(),
onSkipButtonPressed: () => go(),
));
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
代码太多,所以我可能已经忽略了它。但是您需要堆栈尺寸。如果需要,请用大小的盒子包裹堆栈,或在堆栈中放一个大小将包含所有其他孩子的烟盒。
编辑:
当然。我已经尝试并确认了。如您在下面的代码中所看到的,垂直滚动或
定位。bottom
仅在堆栈的高度界定时才有可能。类似地,水平滚动或定位。用堆栈左左可能具有限制宽度。如何
在堆栈的子女中 给堆栈有限的维度?包含所有这些孩子的矩形是堆栈的渲染尺寸。
如果要使用右侧,底部,左,右,右,右,以确定一个Clidren的位置,它们必须朝向滚动方向。确定,所有其他孩子都是作为孩子的参考,并确定了他们的大小/职位。
如果没有这样的大小和位置的孩子,则堆栈会引用其渲染树的盒子。而且,如果这些约束在滚动方向上没有绑定,则无法在该方向上输入一个值(如果滚动方向是轴。
在下面的示例中,它应该是两个
sizedbox
。否则,它不会滚动(即使我们删除bottom
值),否则我们会遇到错误。(由于水平顶部的约束是有界的高度和不可滚动的,因此它将使用屏幕尺寸。即使我输入了无限值,width值也会使用。)
There are too many codes, so I may have overlooked it. But you need the stack sizing. Wrap the Stack with a SizedBox if you want, or put a SizedBox inside the stack whose size will include all other children.
Editing:
Certainly. I've tried and confirmed. As you can see in the codes below, vertical scrolling or
Positioned.bottom
are only possible when the Stack has bounded height. Similarly horizontal scrolling or Positioned.left possible with Stack has bounded width.How to give bounded dimension to Stack?
Among the children of the Stack, those whose size and position are determined are placed. The rectangle containing all of these children is the render size of the Stack.
If the right , bottom, left, right parameters of Positioned are to be used in order to determine the position of one of the clidren, they must not be in the scrolling direction.However, if there is even one child whose size and position are certain, all other children are placed as a reference from the child and their sizes/positions are determined.
If there are no children of such size and position, the Stack references the BoxConstraints of its render tree. And if those constraints don't have a bound in the scroll direction, you can't enter a value in that direction (if scroll direction is Axis.vertical you can't give bottom to Positioned).
In the example below it should be one of both
SizedBox
. Otherwise it will not scroll (even if we remove thebottom
values) or we will get an error.(Since the constraints from the top on the horizontal are bounded height and non-scrollable, it will use the screenSize.width value even if I have entered an infinity value.)
您可以在类似的容器中包装 singlechildscrollview(...):
然后,给这个容器一个绑定的高度和宽度:
请注意,您必须给出堆栈如果树上还有其他孩子占用空间,则高度较小。在下面的图像中,当我翻转屏幕时,您可以看到行为。 :)

You can wrap SingleChildScrollView(...) in a Container like this:
Then, give this Container a bound height and width like this:
Note that you will have to give the stack a smaller height if there are other children in the tree taking up space. In the images below you can see the behavior when I flip the screen. :)


你尝试过吗?
&amp;请分享错误消息或任何屏幕截图。
谢谢。
Have you tried?
& please share the error message or any screenshot of it.
Thanks.