Related
I would like to obtain the effect of having the same Draggable for both child and feedback composed widgets. Look at _getDraggablePaperSheets().
But I get totally different text size for the feedback widget. Why is that?
code disclaimer: every PaperSheet has its rotation and color kept inside Controller and is based on questionNumber, so it should look the same.
class Phase3Screen extends StatelessWidget {
static const ROUTE = '/oneoften/phase3';
final QuestionsController controller = Get.put(QuestionsController());
#override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Container(
child: Stack(
children: [
DragTarget<int>(
builder: (
BuildContext context,
List<dynamic> accepted,
List<dynamic> rejected,
) {
return Container(
height: double.infinity,
width: double.infinity,
child: Align(
alignment: Alignment.bottomCenter,
child: Obx(() {
return Text('Question number: ${controller.getQuestionNumber}');
}),
),
);
},
onAccept: (int draggableData) {
debugPrint('draggable onAccept');
controller.nextQuestion();
},
onWillAccept: (item) {
debugPrint('draggable is on the target $item');
return true;
},
onLeave: (item) {
debugPrint('draggable has left the target $item');
},
),
Center(
child: Obx(
() {
return Stack(
children: _getDraggablePaperSheets(controller.getQuestionsStackSize),
);
},
),
),
],
),
),
),
);
}
List<Widget> _getDraggablePaperSheets(int currentQuestionsStackSize) {
List<Widget> sheets = [];
int i = 0;
logger.d("currentQuestionsStackSize = $currentQuestionsStackSize");
for (i = 1; i < currentQuestionsStackSize; i++) {
sheets.add(
Draggable(
maxSimultaneousDrags: 1,
data: i,
child: PaperSheet(questionNumber: i),
feedback: PaperSheet(questionNumber: i)
),
);
}
return sheets;
}
}
class PaperSheet extends GetView<QuestionsController> {
PaperSheet({
required this.questionNumber,
Key? key,
}) : super(key: key);
final questionNumber;
#override
Widget build(BuildContext context) {
return Container(
transform: Matrix4.rotationZ(controller.assignedRotationZ(questionNumber)),
child: ClipRRect(
borderRadius: BorderRadius.all(Radius.circular(8.0)),
child: Container(
width: 250,
height: 420,
color: controller.assignedBackgroundColor(questionNumber),
child: Column(children: [
Expanded(
child: Container(
padding: const EdgeInsets.all(12.0),
alignment: Alignment.center,
child: Obx(
() {
return Text(
'Question: ${controller.currentQuestionText}',
style: TextStyle(
color: controller.assignedTextColor(questionNumber),
),
);
},
),
),
),
Expanded(
child: Container(
padding: const EdgeInsets.all(12.0),
child: Obx(() {
return Center(
child: Text(
'Answer: ${controller.currentQuestionAnswer}',
style: TextStyle(
color: controller.assignedTextColor(questionNumber),
),
),
);
}),
),
),
]),
),
),
);
}
}
Try to wrap with Material widget
I have 2 pages, on one of them I have placed the code which displays indexers, I want to swipe on indexes to pass between pages. I can't figure out how to set it up. I will be grateful for your help.
Container(
child: SmoothPageIndicator(
controller: _pageController,
count: _pages.length,
effect: JumpingDotEffect(
dotHeight: 16,
dotWidth: 16,
jumpScale: .7,
verticalOffset: 15,
),
onDotClicked: _onchanged
),
),
List of pages:
List<Widget> _pages = [
Form_scan(),
Form_ttn()
];
Image indecators
I will be grateful if someone helps me to go from the first page to the second (swipe right) with these indicators
Try out below code:-
import 'dart:async';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:sizer/sizer.dart';
import 'package:livekeeping/Common/Constant.dart';
import 'package:livekeeping/Common/IconNames.dart';
import 'package:livekeeping/Common/Reusable.dart';
import 'package:livekeeping/Controller/Authentication/LoginWithOtpScreen.dart';
import 'package:lottie/lottie.dart';
class Onboarding extends StatefulWidget {
#override
State<StatefulWidget> createState() {
return OnboardingState();
}
}
class OnboardingState extends State<Onboarding> {
int _current = 0;
Widget widgetChange = firstWidget();
var i = 0;
#override
void initState() {
super.initState();
}
#override
void dispose() {
super.dispose();
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
height: double.maxFinite,
width: double.maxFinite,
child: Stack(
children: <Widget>[
PageView.builder(
onPageChanged: (pageIndex) {
setState(() {
_current = pageIndex;
});
},
itemCount: 4,
itemBuilder: (context, index) {
if (index == 0) {
return firstWidget();
} else if (index == 1) {
return secondWidget();
} else if (index == 2) {
return thirdWidget();
} else {
return fourthWidget();
}
},
),
Positioned(
bottom: 120,
left: 0,
right: 0,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [1, 2, 3, 4].map((url) {
int index = [1, 2, 3, 4].indexOf(url);
return Container(
width: 8.0,
height: 8.0,
margin:
EdgeInsets.symmetric(vertical: 10.0, horizontal: 2.0),
decoration: BoxDecoration(
shape: BoxShape.circle,
color: _current == index
? Color.fromRGBO(0, 0, 0, 0.9)
: Color.fromRGBO(0, 0, 0, 0.4),
),
);
}).toList(),
),
),
Padding(
padding: const EdgeInsets.only(bottom: 30.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: [
ButtonTheme(
height: 45,
minWidth: 150,
child: new Center(
child: RaisedButton(
color: AppTextStyle.mainThemeColor(),
onPressed: () {
Navigator.of(context).pushAndRemoveUntil(
CupertinoPageRoute(
builder: (context) => Login()),
(route) => false);
},
child: new Text(
"Get Started".toUpperCase(),
style: GoogleFonts.openSans(
color: Colors.white,
fontSize: 15,
fontWeight: FontWeight.w500,
),
),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(50)),
)),
),
],
),
)
],
),
),
);
}
}
class firstWidget extends StatefulWidget {
#override
_firstWidgetState createState() => _firstWidgetState();
}
class _firstWidgetState extends State<firstWidget>{
#override
void initState() {
super.initState();
}
#override
Widget build(BuildContext context) {
return Stack(
children: [
Container(
height: double.maxFinite,
width: double.maxFinite,
child: Image.asset(
SplashBG, // You can put your Background image as well
fit: BoxFit.cover,
),
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
height: 45.0.h,
width: 75.0.w,
child: Image.asset(Icon1),
),
],
),
],
),
],
);
}
}
class secondWidget extends StatefulWidget {
#override
_secondWidgetState createState() => _secondWidgetState();
}
class _secondWidgetState extends State<secondWidget>{
#override
void initState() {
super.initState();
}
#override
Widget build(BuildContext context) {
return Stack(
children: [
Container(
height: double.maxFinite,
width: double.maxFinite,
child: Image.asset(
SplashBG, // You can put your Background image as well
fit: BoxFit.cover,
),
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
height: 45.0.h,
width: 75.0.w,
child: Image.asset(Icon2),
),
],
),
],
),
],
);
}
}
class thirdWidget extends StatefulWidget {
#override
_thirdWidgetState createState() => _thirdWidgetState();
}
class _thirdWidgetState extends State<thirdWidget> {
#override
void initState() {
super.initState();
}
#override
Widget build(BuildContext context) {
return Stack(
children: [
Container(
height: double.maxFinite,
width: double.maxFinite,
child: Image.asset(
SplashBG, // You can put your Background image as well
fit: BoxFit.cover,
),
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
height: 45.0.h,
width: 75.0.w,
child: Image.asset(Icon3),
),
],
),
],
),
],
);
}
}
class fourthWidget extends StatefulWidget {
#override
_fourthWidgetState createState() => _fourthWidgetState();
}
class _fourthWidgetState extends State<fourthWidget> {
#override
void initState() {
super.initState();
}
#override
Widget build(BuildContext context) {
return Stack(
children: [
Container(
height: double.maxFinite,
width: double.maxFinite,
child: Image.asset(
SplashBG, // You can put your Background image as well
fit: BoxFit.cover,
),
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
height: 45.0.h,
width: 75.0.w,
child: Image.asset(Iconn4),
),
],
),
],
),
],
);
}
}
use PageView, :
PageView(
controller: _pageController,
children: [
Form_scan(),
Form_ttn()
],
),
make a PageController :
final PageController _pageController = PageController();
onDotClicked: _onchanged
void _onchanged(){
_pageController.animateToPage(
indexHalaman,
duration: Duration(milliseconds: 500),
curve: Curves.fastOutSlowIn
);
}
indexHalaman = page index, if you have 2 widget on pageView children then first page index = 0, next index page = 1, if you use stateful widget, dont forget to use setState, or maybe you can use bloc pattern for this
I am trying to achieve something like this in flutter. I have a horizontal scrollable which has these rounded containers. I want the width of these containers to shrink if the elements in the scrollable is more than 3 and it should expand as per the image if the elements are less than 2. What i want is exactly like this image, i have been reading about flexible widget but when i wrap it inside a scrollable row it gives layout specific issues. Any workaround to achieve this?
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SingleChildScrollView(
padding: EdgeInsets.zero,
scrollDirection: Axis.horizontal,
child: Row(
children: [
...List.generate(
9,
(index) => Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
color: Colors.green,
),
height: 100,
width: 100,
),
),
)
],
)),
SizedBox(
height: 20,
),
Row(
children: [
...List.generate(
2,
(index) => Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
height: 100,
width: 180,
decoration: BoxDecoration(
color: Colors.green,
borderRadius: BorderRadius.circular(20))),
))
],
),
SizedBox(
height: 20,
),
Row(
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
height: 100,
width: 350,
decoration: BoxDecoration(
color: Colors.green,
borderRadius: BorderRadius.circular(20))),
),
],
)
],
),
),
);
}
The above build method produces the following result.(The values here are hardcoded and is just for demonstration). The list values are going to be dynamic and the desired result should be like the one in the video. How do i proceed with this?
https://streamable.com/w142je
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(debugShowCheckedModeBanner: false, home: MyHomePage());
}
}
class MyHomePage extends StatefulWidget {
final String hintText = 'hing';
#override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
#override
#override
Widget build(BuildContext context) {
var list1 = List.filled(2, '2');
var list2 = List.filled(4, '4');
var list3 = List.filled(1, '1');
return SafeArea(
child: Scaffold(
body: Column(
children: [
_getList(context, list1),
_getList(context, list2),
_getList(context, list3),
],
),
),
);
}
Widget _getList(BuildContext context, List<String> list) {
bool ownSize = list.length == 2;
if (ownSize) {
return SingleChildScrollView(
padding: EdgeInsets.zero,
scrollDirection: Axis.horizontal,
child: Row(
children: list.map((t) => rowItem(t, 250)).toList(),
),
);
} else {
return Row(
children: list
.map(
(t) => Expanded(child: rowItem(t)),
)
.toList(),
);
}
}
Widget rowItem(String text, [double? width]) {
return Container(
margin: const EdgeInsets.all(8.0),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
color: Colors.green,
),
height: 100,
width: width,
alignment: Alignment.center,
child: Text(text),
);
}
}
Hello i am new to Flutter and I want to know if there is a way to add new Widgets with a button click.
I looked into many stack overflow similar Questions. but due to my poor knowledge most of them seems complex to me and hard to grasp. All i need to do is add some containers below old build containers
class MedPreC extends StatefulWidget {
#override
_MedPreCState createState() => _MedPreCState();
}
Widget returnWidget() {
return Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
width: double.infinity,
height: 40,
color: Colors.red,
),
);
}
class _MedPreCState extends State<MedPreC> {
var child2 = Column(
children: [
returnWidget(),
],
);
#override
Widget build(BuildContext context) {
return Container(
child: Column(
children: [
Expanded(
child: Container(
color: Colors.yellow,
height: 400,
width: double.infinity,
child: child2,
),
),
RaisedButton(
child: Text("Add"),
onPressed: () {
setState(() {
//
child2.children.add(returnWidget());
//
});
},
)
],
),
);
}
}
This is the code i have made so far. This whole code will be called inside another class with scafold and stuffs
returnWidget() Returns a red container
child2 is a Column called inside a yellow Container with one red container as one of its children
i need to add more redcontainers on button press
Thank you thats all
Try this
class AddWidget extends StatefulWidget {
#override
_AddWidgetState createState() => _AddWidgetState();
}
class _AddWidgetState extends State<AddWidget> {
List<Widget> containerList = [];
Widget returnWidget() {
return Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
width: double.infinity,
height: 40,
color: Colors.red,
),
);
}
#override
Widget build(BuildContext context) {
return Container(
child: Column(
children: [
Expanded(
child: Container(
color: Colors.yellow,
height: 400,
width: double.infinity,
child: Column(children: containerList),
),
),
RaisedButton(
child: Text("Add"),
onPressed: () {
setState(() {
containerList.add(returnWidget());
});
},
)
],
),
);
}
}
For this you need also check the overflow of widget. So you can check the below code.
import 'package:flutter/material.dart';
class MedPreC extends StatefulWidget {
#override
_MedPreCState createState() => _MedPreCState ();
}
class _MedPreCState extends State<MedPreC > {
List<Widget> data = [];
Widget CustomWidget() {
return Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
width: double.infinity,
height: 40,
color: Colors.red,
),
);
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: [
Container(
color: Colors.yellow,
height: MediaQuery.of(context).size.height - 60,
width: double.infinity,
child: SingleChildScrollView(child: Column(children: data)),
),
],
),
bottomNavigationBar: Container(
height: 60,
width: MediaQuery.of(context).size.width,
color: Colors.white,
child: InkWell(
child: Center(
child: Container(
color: Colors.red,
width: 100,
height: 40,
child: Center(child: Text("Add"))),
),
onTap: () {
setState(() {
data.add(CustomWidget());
});
},
),
),
);
}
}
I'm trying to use Flow widget instead of BottomNavigationBar.
this is my code.
#override
Widget build(BuildContext context) {
final delegate = S.of(context);
return SafeArea(
child: Scaffold(
drawer: DrawerWidget(),
body: Stack(
children: [
_pages[_selectedPageIndex]['page'],
Positioned(
child: Container(
child: Flow(
delegate: FlowMenuDelegate(menuAnimation: menuAnimation),
children: menuItems
.map<Widget>((IconData icon) => flowMenuItem(icon))
.toList(),
),
),
),
]),
}
But after adding left, right, bottom, or top properties to the Positioned widget, the Flow widget gon.
You can copy paste run full code below
You can use ConstrainedBox and set Stack fit and Positioned with Container
SafeArea(
child: Scaffold(
body: ConstrainedBox(
constraints: BoxConstraints.expand(),
child: Stack(
alignment: Alignment.topLeft,
fit: StackFit.expand,
children: [
...
Positioned(
left: 0,
top: 0,
child: Container(
alignment: Alignment.topLeft,
width: MediaQuery.of(context).size.width,
height: 65,
child: FlowMenu()))
]),
),
),
);
working demo
full code
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: FlowTest(),
);
}
}
class FlowTest extends StatefulWidget {
#override
_FlowTestState createState() => _FlowTestState();
}
class _FlowTestState extends State<FlowTest> {
#override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
body: ConstrainedBox(
constraints: BoxConstraints.expand(),
child: Stack(
alignment: Alignment.topLeft,
fit: StackFit.expand,
children: [
ListView(
shrinkWrap: true,
children: <Widget>[
Column(
children: <Widget>[
SizedBox(height: 20.0),
ListView.builder(
shrinkWrap: true,
itemCount: 5,
physics: PageScrollPhysics(),
itemBuilder: (context, index) {
return Column(
children: <Widget>[
Container(
height: 50.0,
color: Colors.green,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Icon(Icons.format_list_numbered,
color: Colors.white),
Padding(
padding: const EdgeInsets.only(right: 5.0)),
Text(index.toString(),
style: TextStyle(
fontSize: 20.0, color: Colors.white)),
],
),
),
Container(
child: GridView.count(
crossAxisCount: 3,
shrinkWrap: true,
physics: PageScrollPhysics(),
childAspectRatio: 1.2,
children: List.generate(
8,
(index) {
return Container(
child: Card(
color: Colors.blue,
),
);
},
),
),
),
SizedBox(height: 20.0),
],
);
},
),
],
),
],
),
Positioned(
left: 0,
top: 0,
child: Container(
alignment: Alignment.topLeft,
width: MediaQuery.of(context).size.width,
height: 65,
child: FlowMenu()))
]),
),
),
);
}
}
class FlowMenu extends StatefulWidget {
#override
_FlowMenuState createState() => _FlowMenuState();
}
class _FlowMenuState extends State<FlowMenu>
with SingleTickerProviderStateMixin {
AnimationController menuAnimation;
IconData lastTapped = Icons.notifications;
final List<IconData> menuItems = <IconData>[
Icons.home,
Icons.new_releases,
Icons.notifications,
Icons.settings,
Icons.menu,
];
void _updateMenu(IconData icon) {
if (icon != Icons.menu) setState(() => lastTapped = icon);
}
#override
void initState() {
super.initState();
menuAnimation = AnimationController(
duration: const Duration(milliseconds: 250),
vsync: this,
);
}
Widget flowMenuItem(IconData icon) {
final double buttonDiameter =
MediaQuery.of(context).size.width / menuItems.length;
return Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0),
child: RawMaterialButton(
fillColor: lastTapped == icon ? Colors.amber[700] : Colors.blue,
splashColor: Colors.amber[100],
shape: CircleBorder(),
constraints: BoxConstraints.tight(Size(buttonDiameter, buttonDiameter)),
onPressed: () {
_updateMenu(icon);
menuAnimation.status == AnimationStatus.completed
? menuAnimation.reverse()
: menuAnimation.forward();
},
child: Icon(
icon,
color: Colors.white,
size: 45.0,
),
),
);
}
#override
Widget build(BuildContext context) {
return Container(
child: Flow(
delegate: FlowMenuDelegate(menuAnimation: menuAnimation),
children: menuItems
.map<Widget>((IconData icon) => flowMenuItem(icon))
.toList(),
),
);
}
}
class FlowMenuDelegate extends FlowDelegate {
FlowMenuDelegate({this.menuAnimation}) : super(repaint: menuAnimation);
final Animation<double> menuAnimation;
#override
bool shouldRepaint(FlowMenuDelegate oldDelegate) {
return menuAnimation != oldDelegate.menuAnimation;
}
#override
void paintChildren(FlowPaintingContext context) {
double dx = 0.0;
for (int i = 0; i < context.childCount; ++i) {
dx = context.getChildSize(i).width * i;
context.paintChild(
i,
transform: Matrix4.translationValues(
dx * menuAnimation.value,
0,
0,
),
);
}
}
}