Flutter change offset of draggable widgets in a stack at the same time as scrolling a SingleChildScrollView - flutter

I have a stack of widgets in Flutter. The lowest stack is a large image that is contained inside SingleChildScrollView. I've set up a ScrollController so I know when the image has been horizontally scrolled in the view.
Next in the stack I have several Positioned widgets (these are draggable so that they can moved around independent of each other).
What I'd like to do is when the SingleChildScrollView is scrolled, I'd like to update the position of each of the positioned widgets higher up the stack.
I've considered Stream, rebuildAllChildren and ValueNotifier but all seem quite complex for what, on the face of it, should be quite a simple thing to achieve. I'm probably missing something very obvious somewhere!
Here's my code so far:
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
class LayoutScreen extends StatefulWidget {
LayoutScreen();
#override
_LayoutScreenState createState() => _LayoutScreenState();
}
class _LayoutScreenState extends State<LayoutScreen> {
ScrollController _controller;
Offset boxoneposition;
BuildContext context;
_scrollListener() {
print(_controller.offset);
boxoneposition=Offset(100.0, 100);
setState(() {
print(boxoneposition);
// this was a test - the value of boxoneposition is updated, however the view isn't
});
}
#override
void initState() {
_controller = ScrollController();
_controller.addListener(_scrollListener);
boxoneposition = Offset(0.0, 30);
super.initState();
}
DragBox boxOne() {
// Trying to set up outside of widget build
return DragBox(boxoneposition, 'Box One Yep', Colors.blueAccent, 1);
}
#override
Widget build(BuildContext context) {
return Stack(
children: <Widget>[
SingleChildScrollView(
scrollDirection: Axis.horizontal,
controller: _controller,
child: Container(
width: 1000,
height: 1000,
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('assets/images/logo.png'),
fit: BoxFit.cover,
repeat: ImageRepeat.noRepeat,
),
),
),
),
//DragBox(boxoneposition, 'Box One', Colors.blueAccent, 1),
boxOne(),
DragBox(Offset(200.0, 50.0), 'Box Two', Colors.orange, 2),
DragBox(Offset(300.0, 80.0), 'Box Three', Colors.lightGreen, 3),
],
);
}
}
class DragBox extends StatefulWidget {
final Offset initPos;
final String label;
final Color itemColor;
final int boxnumber;
DragBox(this.initPos, this.label, this.itemColor, this.boxnumber);
#override
DragBoxState createState() => DragBoxState();
}
class DragBoxState extends State<DragBox> {
Offset position = Offset(0.0, 0.0);
String imagePath="";
#override
void initState() {
super.initState();
position = widget.initPos;
}
getBoxPic() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
setState(() {
String key='picture'+widget.boxnumber.toString();
imagePath=prefs.getString(key);
});
print(imagePath);
return File(imagePath);
}
#override
Widget build(BuildContext context) {
return Positioned(
left: position.dx,
top: position.dy,
child: Draggable(
data: widget.itemColor,
child: Container(
width: 100.0,
height: 100.0,
color: widget.itemColor,
child: Center(
child:
Image.asset('assets/images/logo.png')
),
),
onDragStarted: () {
setState(() {
print("Foobar");
});
},
onDraggableCanceled: (velocity, offset) {
setState(() {
position = offset;
if (widget.boxnumber==1) {
print("Wibble");
}
});
},
feedback: Container(
width: 120.0,
height: 120.0,
color: widget.itemColor.withOpacity(0.5),
child: Center(
child: Text(
widget.label,
style: TextStyle(
color: Colors.white,
decoration: TextDecoration.none,
fontSize: 18.0,
),
),
),
),
)
);
}
}
Any help greatly appreciated!

I was being a fool. Funny how walking away from something overnight and coming back to it clears the fog!
I sorted this out by simply placing an entire stack into the SingleChildScrollView. The scrollview is wider and horizontally scrollable and the rest of the elements in the stack correctly maintain their positons even if the scrollview is moved and they disappear off screen.
The solution was very simple. For completeness, here's the updated code:
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
class LayoutScreen extends StatefulWidget {
LayoutScreen();
#override
_LayoutScreenState createState() => _LayoutScreenState();
}
class _LayoutScreenState extends State<LayoutScreen> {
#override
void initState() {
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Arrange your images'),
backgroundColor: Colors.orange,
),
body: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Stack(
children: <Widget>[
Container(
width: 1000,
height: 1000,
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('assets/images/background.jpg'),
fit: BoxFit.cover,
repeat: ImageRepeat.noRepeat,
),
),
),
DragBox(Offset(100.0, 10.0), 'Box One', Colors.blueAccent, 1),
DragBox(Offset(200.0, 50.0), 'Box Two', Colors.orange, 2),
DragBox(Offset(300.0, 80.0), 'Box Three', Colors.lightGreen, 3),
]
),
)
);
}
}
class DragBox extends StatefulWidget {
final Offset initPos;
final String label;
final Color itemColor;
final int boxnumber;
DragBox(this.initPos, this.label, this.itemColor, this.boxnumber);
#override
DragBoxState createState() => DragBoxState();
}
class DragBoxState extends State<DragBox> {
Offset position = Offset(0.0, 0.0);
String imagePath="";
#override
void initState() {
super.initState();
position = widget.initPos;
}
getBoxPic() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
setState(() {
String key='picture'+widget.boxnumber.toString();
imagePath=prefs.getString(key);
});
print(imagePath);
return File(imagePath);
}
#override
Widget build(BuildContext context) {
return Positioned(
left: position.dx,
top: position.dy,
child: Draggable(
data: widget.itemColor,
child: Container(
width: 100.0,
height: 100.0,
color: widget.itemColor,
child: Center(
child:
Image.asset('assets/images/logo.png')
),
),
onDragStarted: () {
setState(() {
print("Foobar");
});
},
onDraggableCanceled: (velocity, offset) {
setState(() {
position = offset;
if (widget.boxnumber==1) {
print("Wibble");
}
});
},
feedback: Container(
width: 120.0,
height: 120.0,
color: widget.itemColor.withOpacity(0.5),
child: Center(
child: Text(
widget.label,
style: TextStyle(
color: Colors.white,
decoration: TextDecoration.none,
fontSize: 18.0,
),
),
),
),
)
);
}
}

Related

How to run widget over the container screen in flutter

I want to show some widget onTap() event over screen like below image .
Here is my code
In this the build method is return Container().
Container has one child named SingleChildScrollView and also it has some children.
So I don't want to change on this all children when new widget will create.
In simple, saw widget onTap() over the running screen without disturb another widget.
class _SettingScreenState extends State<SettingScreen> {
List<Widget> _iconList=[];
List<Widget> _titleList=[];
List<Widget> _settingLIst=[];
#override
void initState() {
super.initState();
for(int i=0;i<5;i++){
_iconList.add(_addInIcon(i));
}
for(int i=0;i<5;i++){
_titleList.add(_addInTitle(i));
}
for(int i=0;i<24;i++){
_settingLIst.add(_addInSetting(i));
}
}
#override
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(
color: Colors.white
),
child: SingleChildScrollView(
child: Column(
children: <Widget>[
_titleList[0],
_addInSetting(0),
_addInSetting(1),
_titleList[1],
_settingLIst[2],
_settingLIst[3],
_titleList[2],
_settingLIst[4],
_settingLIst[5],
_settingLIst[6],
_settingLIst[7],
_settingLIst[8],
_settingLIst[9],
GestureDetector(
onTap: (){
//open widget over the this screen
},
child: Button(
image: _coverImage(),
width: double.infinity,
height: 50,
alignment: Alignment.center,
fit: BoxFit.fitHeight,
),
),
],
),
),
);
}
}
Ans , is setState() is necessary while create new widget over the previous Container() widget ?
Because we cant change anything on previous Container()
In Android-java development, what i did
onClick()
{
ImageView imageView = new ImageView(this);
Glide.with(getApplicationContext()).load(position).into(imageView);
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams( Math.round((float) 35 * density), Math.round((float) 35 * density));
imageView.setX(reactionButton.getX());
imageView.setY(reactionButton.getY());
imageView.setLayoutParams(layoutParams);
messageRelativeLayout.addView(imageView);
imageView.bringToFront();
animateReaction(imageView);
}
It means every time new ImageView will added on tree, no matter if previous ImageView is appear or not.
Simple click button and create new ImageView and show front of screen.
this feature i want to apply in flutter
Child of OverlayWidget
class OverlayChild extends StatefulWidget {
final Function clearCallBack;
final double maxWidth;
final double maxHeight;
final int itemIndex;
const OverlayChild({
Key? key,
required this.clearCallBack,
required this.maxWidth,
required this.maxHeight,
required this.itemIndex,
}) : super(key: key);
#override
_OverlayChildState createState() => _OverlayChildState();
}
class _OverlayChildState extends State<OverlayChild> {
late Timer timer;
final Random random = Random();
#override
void initState() {
super.initState();
print("int ${widget.itemIndex}");
timer = Timer.periodic(Duration(seconds: 5), (timer) {
setState(() {
widget.clearCallBack(widget.itemIndex);
timer.cancel();
print("after delay");
});
});
}
#override
void dispose() {
timer.cancel();
super.dispose();
}
#override
Widget build(BuildContext context) {
return Positioned(
top: random.nextDouble() * widget.maxHeight,
left: random.nextDouble() * widget.maxWidth,
child: Container(
height: 20,
width: 20,
padding: EdgeInsets.all(3),
decoration: BoxDecoration(
shape: BoxShape.circle,
color:
widget.itemIndex.isEven ? Colors.deepPurple : Colors.cyanAccent,
),
child: Center(child: Text("${widget.itemIndex}")),
),
);
}
}
Main Widget
class HomeOverLay extends StatefulWidget {
#override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<HomeOverLay> {
List<OverlayChild> overlayItems = [];
int itemId = 0;
#override
Widget build(BuildContext context) {
return LayoutBuilder(
builder: (context, constraints) => Scaffold(
floatingActionButton: FloatingActionButton(
onPressed: () async {
setState(() {
overlayItems.add(
OverlayChild(
key: UniqueKey(),
clearCallBack: (id) {
setState(() {
overlayItems
.removeWhere((element) => element.itemIndex == id);
});
},
itemIndex: itemId,
//same as container height
maxHeight: constraints.maxHeight * .1,
maxWidth: constraints.maxWidth,
),
);
itemId++;
});
},
),
body: Stack(
children: [
Align(
alignment: Alignment.topCenter, // you may want some changes here
child: SizedBox(
height: constraints.maxHeight,
width: constraints.maxWidth,
child: SingleChildScrollView(
child: Column(
children: [
...List.generate(
22,
(index) => Container(
height: 100,
width: double.infinity,
color: index.isEven
? Colors.deepPurple
: Colors.orangeAccent,
),
)
],
),
),
),
),
Positioned(
top: constraints.maxHeight * .2,
left: 0,
right: 0,
child: Container(
width: overlayItems.length > 0 ? constraints.maxWidth : 0,
height:
overlayItems.length > 0 ? constraints.maxHeight * .1 : 0,
color: Colors.pinkAccent,
child: Stack(
children: [
...overlayItems.toList(),
],
),
),
),
],
),
),
);
}
}

Keyboard automatically disappears from TextField in ListView.Builder

I'm trying to implement a solution where a row (containing both a TextField and a Text) in ListView.Builder is automatically for every record retrieved from a webserver.
However when I want to start typing in such a TextField the keyboard appears and immediatly disappears again.
This is the code of my screen.
class GameScreen extends StatelessWidget {
static const RouteName = "/GameScreen";
#override
Widget build(BuildContext context) {
var size = MediaQuery.of(context).size;
const horizontalMargin = 20.0;
return Scaffold(
appBar: getAppBar(),
backgroundColor: Colors.transparent,
body: Stack(
children: <Widget>[
Background(),
Column(
children: <Widget>[
Header("Starting letter: B"),
Expanded(
child: ListBlocProvider(
listWidget: GameCategoriesList(),
itemsService: CategoriesService(),
margin: EdgeInsets.only(
left: horizontalMargin,
bottom: 10,
right: horizontalMargin,
),
),
),
SizedBox(
height: 20,
),
SizedBox(
width: size.width - 40,
height: 60,
child: Container(
height: 60,
child: TextButtonWidget(
() {
// Navigator.of(context).pushNamed(GameScreen.RouteName);
},
"Stop game",
),
),
),
SizedBox(
height: 20,
)
],
),
],
),
);
}
}
This is the code of my ListBlocProvider:
class ListBlocProvider extends StatelessWidget {
final ListWidget listWidget;
final ItemsService itemsService;
final bool useColor;
final bool usePaddingTop;
final double height;
final EdgeInsets margin;
const ListBlocProvider({
#required this.listWidget,
#required this.itemsService,
this.useColor = true,
this.usePaddingTop = true,
this.height = 200,
this.margin,
});
#override
Widget build(BuildContext context) {
const horizontalMargin = 20.0;
return BlocProvider(
create: (context) => ItemsBloc(itemsService: itemsService)..add(ItemsFetched()),
child: Container(
padding: usePaddingTop ? EdgeInsets.only(top: 10) : null,
decoration: BoxDecoration(
color: this.useColor ? Color.fromRGBO(10, 50, 75, 0.9) : null,
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(10),
bottomRight: Radius.circular(10),
),
),
margin: this.margin,
height: this.height,
child: this.listWidget,
),
);
}
}
This is the code of my List:
class GameCategoriesList extends ListWidget {
#override
_GameCategoriesListState createState() => _GameCategoriesListState();
}
class _GameCategoriesListState extends State<GameCategoriesList> {
#override
Widget build(BuildContext context) {
return BlocBuilder<ItemsBloc, ItemsState>(
builder: (context, state) {
if (state is ItemsFailure) {
return Center(
child: Text('failed to fetch categories'),
);
}
if (state is ItemsSuccess) {
if (state.items.isEmpty) {
return Center(
child: Text('no categories found.'),
);
}
return ListView.builder(
itemBuilder: (BuildContext context, int index) {
var textEditingController = TextEditingController();
return GameCategoryItemWidget(
key: UniqueKey(),
categoryModel: state.items[index],
textEditingController: textEditingController,
);
},
itemCount: state.items.length,
);
}
return Center(
child: LoadingIndicator(),
);
},
);
}
}
And this is the code where the both the TextField and the Text are build:
class GameCategoryItemWidget extends StatefulWidget {
final CategoryModel categoryModel;
final TextEditingController textEditingController;
const GameCategoryItemWidget({Key key, this.categoryModel, this.textEditingController}) :
super(key: key);
#override
_GameCategoryItemWidgetState createState() => _GameCategoryItemWidgetState();
}
class _GameCategoryItemWidgetState extends State<GameCategoryItemWidget> {
var formKey = GlobalKey<FormState>();
#override
Widget build(BuildContext context) {
return Container(
child: Form(
key: this.formKey,
child: Column(
children: <Widget>[
Container(
padding: EdgeInsets.only(left: 10, top: 20, bottom: 10),
child: Text(
this.widget.categoryModel.name,
style: TextStyle(
color: Colors.white,
fontSize: 18,
),
),
),
Container(
color: Colors.white,
child: InputField(
InputDecoration(labelText: this.widget.categoryModel.name),
this.widget.textEditingController,
false,
),
),
],
),
),
);
}
#override
void dispose() {
this.widget.textEditingController.dispose();
super.dispose();
}
}
The InputField is a custom widget to hide the switch between a Material and a Cupertino version of the TextField.
I've already tried to remove the Key from the custom TextField widget. The funny part is that the input is actually working, however it can't determine for which of the TextFields in the ListView the input is determined so it adds the input to all of them. I've also tried to swap things around with making Stateless widgets Statefull, but that didn't help either.
The entire build is based upon: https://bloclibrary.dev/#/flutterinfinitelisttutorial.
Hoping you guys can help me.

Drag and drop offset error when draggable is inside ListView

I was making a new app and I have the need to put one or more drag and drop zones inside a ListView with draggable elements, there is no need of a drop target.
When the draggable element is dropped there is a big offset error on the vertical position.
I tried to "correct" the offset position by hand subtracting 100px to the vertical position, this is definetely not ideal.
import 'package:flutter/material.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text("Drag and drop bug"),
),
body: App(),
),
);
}
}
class App extends StatefulWidget {
#override
AppState createState() => AppState();
}
class AppState extends State<App> {
Color caughtColor = Colors.grey;
Container spacer({double height: 400, Color color: Colors.blue}) {
return Container(
color: color,
height: height,
);
}
#override
Widget build(BuildContext context) {
// I need a ListView because I have other elements before and after the stack that will certainly occupy more than the view height, the spacers simulate these elements
return ListView(
children: <Widget>[
spacer(color: Colors.amber),
Container(
height: 400,
child: Stack(
children: <Widget>[
DragBox(Offset(0.0, 0.0), 'Box One', Colors.blueAccent),
DragBox(Offset(200.0, 0.0), 'Box Two', Colors.orange),
DragBox(Offset(300.0, 0.0), 'Box Three', Colors.lightGreen),
],
),
),
spacer(color: Colors.cyan)
],
);
}
}
class DragBox extends StatefulWidget {
final Offset initPos;
final String label;
final Color itemColor;
DragBox(this.initPos, this.label, this.itemColor);
#override
DragBoxState createState() => DragBoxState();
}
class DragBoxState extends State<DragBox> {
Offset position = Offset(0.0, 0.0);
#override
void initState() {
super.initState();
position = widget.initPos;
}
#override
Widget build(BuildContext context) {
return Positioned(
left: position.dx,
top: position.dy,
child: Draggable(
data: widget.itemColor,
child: Container(
width: 100.0,
height: 100.0,
color: widget.itemColor,
child: Center(
child: Text(
widget.label,
style: TextStyle(
color: Colors.white,
decoration: TextDecoration.none,
fontSize: 20.0,
),
),
),
),
onDraggableCanceled: (velocity, offset) {
setState(() {
position = offset;
});
},
feedback: Container(
width: 120.0,
height: 120.0,
color: widget.itemColor.withOpacity(0.5),
child: Center(
child: Text(
widget.label,
style: TextStyle(
color: Colors.white,
decoration: TextDecoration.none,
fontSize: 18.0,
),
),
),
),
),
);
}
}
The expected result is to have the dropped element under the cursor/pointer but it is moved of about 100px on the vertical axis.
The offset difference is due to the height of the AppBar.
onDraggableCanceled: (velocity, offset) {
setState(() {
position = offset;
});
}
Here the offset is given in the global coordinate system where the origin is at the top and extreme left of the screen.
The solution to this is given here: How to move element anywhere inside parent container with drag and drop in Flutter?

How to make scrollable Drag and Drop in Flutter?

I am trying to make a scrollable and zoomable Stack using SingleChildScrollView in order to implement a canvas editor.
The Drag and Drop works perfectly when I put my dragabble item in the initial view but when I scroll down the view and I tried to drop my container is coming back in the initial view.
I'm new to the Flutter development so maybe I missunderstood in the implementation of a such thing.
Here's the code I currently have.
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: App(),
),
);
}
}
class App extends StatefulWidget {
#override
AppState createState() => AppState();
}
class AppState extends State<App> {
Color caughtColor = Colors.grey;
#override
Widget build(BuildContext context) {
return SingleChildScrollView(
child: Stack(
children: <Widget>[
Container(
height: 2000,
),
DragBox(Offset(0.0, 0.0), 'Box One', Colors.blueAccent),
],
),
);
}
}
class DragBox extends StatefulWidget {
final Offset initPos;
final String label;
final Color itemColor;
DragBox(this.initPos, this.label, this.itemColor);
#override
DragBoxState createState() => DragBoxState();
}
class DragBoxState extends State<DragBox> {
Offset position = Offset(0.0, 0.0);
#override
void initState() {
super.initState();
position = widget.initPos;
}
#override
Widget build(BuildContext context) {
return Positioned(
left: position.dx,
top: position.dy,
child: Draggable(
data: widget.itemColor,
child: Container(
width: 100.0,
height: 100.0,
color: widget.itemColor,
child: Center(
child: Text(
widget.label,
style: TextStyle(
color: Colors.white,
decoration: TextDecoration.none,
fontSize: 20.0,
),
),
),
),
onDraggableCanceled: (velocity, offset) {
setState(() {
position = offset;
});
},
feedback: Container(
width: 120.0,
height: 120.0,
color: widget.itemColor.withOpacity(0.5),
child: Center(
child: Text(
widget.label,
style: TextStyle(
color: Colors.white,
decoration: TextDecoration.none,
fontSize: 18.0,
),
),
),
),
));
}
}
Any suggestions or code samples would be really helpful to me.
I solve the problem like this, wrap your draggable with a listener.
Listener listenableDraggable = Listener(
child: draggable,
onPointerMove: (PointerMoveEvent event) {
if (event.position.dy > MediaQuery.of(context).size.height) {
// 120 is height of your draggable.
scrollController.scrollTo(scrollcontroller.offset + 120);
}
},
);

Flutter how to pass back data from model

I'm practicing draggable widget. Thanks to amazing video by Tensor Programming. I was able to understand how things work.
However, there is one thing I'm not sure. Let's say if one of the DragBox tapped, I want to get text inside of the tapped DragBox. I wrapped Container with GestureDetector, but I have no idea how to make onTap function pass widget.label to AppState.
Should I use constructor or something to pass it?
Does anyone know hot to achieve this?
Thanks in advance.
import 'package:flutter/material.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: App(),
),
);
}
}
class App extends StatefulWidget {
#override
AppState createState() => AppState();
}
class AppState extends State<App> {
Color caughtColor = Colors.grey;
#override
Widget build(BuildContext context) {
return Stack(
children: <Widget>[
DragBox(Offset(0.0, 0.0), 'Box One', Colors.blueAccent),
DragBox(Offset(200.0, 0.0), 'Box Two', Colors.orange),
DragBox(Offset(300.0, 0.0), 'Box Three', Colors.lightGreen),
Positioned(
left: 100.0,
bottom: 0.0,
child: DragTarget(
onAccept: (Color color) {
caughtColor = color;
},
builder: (
BuildContext context,
List<dynamic> accepted,
List<dynamic> rejected,
) {
return Container(
width: 200.0,
height: 200.0,
decoration: BoxDecoration(
color: accepted.isEmpty ? caughtColor : Colors.grey.shade200,
),
child: Center(
child: Text("Drag Here!"),
),
);
},
),
)
],
);
}
}
class DragBox extends StatefulWidget {
final Offset initPos;
final String label;
final Color itemColor;
DragBox(this.initPos, this.label, this.itemColor);
#override
DragBoxState createState() => DragBoxState();
}
class DragBoxState extends State<DragBox> {
Offset position = Offset(0.0, 0.0);
#override
void initState() {
super.initState();
position = widget.initPos;
}
#override
Widget build(BuildContext context) {
return Positioned(
left: position.dx,
top: position.dy,
child: Draggable(
data: widget.itemColor,
child: GestureDetector(
onTap() {
// want to pass widget.label here
},
child: Container(
width: 100.0,
height: 100.0,
color: widget.itemColor,
child: Center(
child: Text(
widget.label,
style: TextStyle(
color: Colors.white,
decoration: TextDecoration.none,
fontSize: 20.0,
),
),
),
),
),
onDraggableCanceled: (velocity, offset) {
setState(() {
position = offset;
});
},
feedback: Container(
width: 120.0,
height: 120.0,
color: widget.itemColor.withOpacity(0.5),
child: Center(
child: Text(
widget.label,
style: TextStyle(
color: Colors.white,
decoration: TextDecoration.none,
fontSize: 18.0,
),
),
),
),
));
}
}
Can you please refer this answer. In the link
RootPage is similar to App,
AppState is similar to _RootPageState,
DragBox is similar to FeedPage and
DragBoxState is similar to _feedPageState
If it is not helpful, please comment, i can put example for your App