Pixxu Waku
Pixxu Waku

Reputation: 443

Access data between screens in flutter

Im having two screens.

lets say Screen1 and Screen2.

Screen 1 is within a TabView and have couple of checkboxes which I need to validate if either is chosen before proceeding to get them from there and pass to an API call from a button which is in Screen2. Screen2 is the parent(holder) of the TabViews.

Basically ,

I can manage the API calling part. but wanna have an idea or an example of managing the above between Screen1 and Screen2. Can someone provide and insight or an example?

Update

with a helpful comment from a fellow flutter enthusiast, I've update the code. The widget flow is as follows.

//ParentWidget ==> has the list if TabViews and also a button to submit, 

TabBarView(
            controller: _tabController,
            physics: NeverScrollableScrollPhysics(),
            children: _tabViewList,
)

//and the button 
Consumer<UpdateItemProvider>(
        builder: (_, UpdateItemProvider updateItemProvider, __) {
          return ButtonWidget(
            btnColor: CustomColors.green600,
            borderColor: CustomColors.green600,
            textColor: CustomColors.mWhite,
            text: "Continue",
            eButtonType: eButtonType.bText,
            eButtonState: _continueBtnState,
            onPressed: () {
              if (updateItemProvider.updateItems!.isEmpty) {
                setState(() {
                  _continueBtnState = eButtonState.bDisable;
                });
              } else {
                setState(() {
                  _continueBtnState = eButtonState.bActive;
                });
                forwardTabPage(updateItemProvider.updateItems!);
              }
              // _tabState = eTabState.tCompleted;
            },
          );
        },
        // child:
      );


---------- 

//A TabView widget(child) is a Stateful widget

@override
  Widget build(BuildContext context) {
    final UpdateItemProvider _updateItemProvider =
        Provider.of<UpdateItemProvider>(context, listen: false);

//inside the child widget I have a list view which loads checkbox list tiles 
and im using the provider there

ListView(
                        shrinkWrap: true,
                        children: _rampValues.keys.map((String key) {
                          return CheckboxListTile(
                            title: Text(key, style: tBody5),
                            value: _rampValues[key],
                            onChanged: (value) {
                              setState(() {
                                _rampValues[key] = value!;
                              });
                              if (_rampValues[key] == true) {
                                _updateItemProvider.addItem(new UpdateItem(
                                    title: key, selected: _rampValues[key]));
                              } else {
                                _updateItemProvider.removeWhere(key);
                              }
                            },
                          );
                        }).toList(),
                      ),

}

When I execute with above updates. I get this error

Error: Could not find the correct Provider<UpdateItemProvider> above this {child_here} Widget
This happens because you used a `BuildContext` that does not include the provider
of your choice. There are a few common scenarios:

Upvotes: 0

Views: 1396

Answers (3)

Tasnuva Tavasum oshin
Tasnuva Tavasum oshin

Reputation: 4750

Your Code is Fine , the Missing Part is You need to register the provider in main.dart file . Example : **Provider<UpdateItemProvider>** this Provider is missing. So

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  SystemChrome.setPreferredOrientations(
      [DeviceOrientation.portraitUp, DeviceOrientation.portraitDown]).then((_) {
    runApp(MyApp());
  });
}
/*
this is main page of this project we will use the provider system to maintian the application states 
*/

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MultiProvider(
      /**
       * Providers For the Block Module of the System
       */
      providers: [
        ChangeNotifierProvider(create: (ctx) => LoginProvider()), // Add your Provider Here            
      ],
      child: Consumer<LoginProvider>(
        builder: (ctx, auth, _) => MaterialApp(
          title: 'Baghaa',
          debugShowCheckedModeBanner: false,
          theme: ThemeData(
            primarySwatch: Colors.orange,
            accentColor: Colors.black,
            fontFamily: 'RobotoCondensed',
            textTheme: ThemeData.light().textTheme.copyWith(
                bodyText1: TextStyle(
                  color: Color.fromRGBO(20, 51, 51, 1),
                ),
                bodyText2: TextStyle(
                  color: Color.fromRGBO(20, 51, 51, 1),
                ),
                headline1: TextStyle(
                  fontSize: 18,
                  fontWeight: FontWeight.bold,
                  fontFamily: 'RobotoCondensed',
                )),
            canvasColor: Color.fromRGBO(255, 254, 229, 1),
            visualDensity: VisualDensity.adaptivePlatformDensity,
          ),
          home:  .... Your Home widget 
      ),
    );
  }
}

Upvotes: 2

Gourango Sutradhar
Gourango Sutradhar

Reputation: 1619

You may use any kind of reactive way to access the data globally using Provider, GetX, Bloc and etc.

You may use GetX observables like below:

Reactive programming with Get is as easy as using setState.

Let's imagine that you have a name variable and want that every time you change it, all widgets that use it are automatically changed.

This is your count variable:

var name = 'Jonatas Borges';

To make it observable, you just need to add ".obs" to the end of it:

var name = 'Jonatas Borges'.obs;

And in the UI, when you want to show that value and update the screen whenever the values changes, simply do this:

Obx(() => Text("${controller.name}"));

That's all. It's that simple.

You will find the plugin here

Upvotes: 1

griffins
griffins

Reputation: 8274

Without any code to go by, We can use a shopping cart as an example.

Ideally you need a way to manage your list of items and checkout in the next page.

We will use provider for this.

class MyCartProvider extends ChangeNotifier{
List<CartItem>? cartItems=[];
List<CartItem>? get  getCartItems=>cartItems;

removeATIndex(int i){
cartItems.removeAt(i);
notifyListeners();
}

inserAtIndex(int i,CartItem? item){
cartItems![i]=item;
notifyListeners();
}

addItem(CartItem? item){
cartItems.add(item);
notifyListeners()
}

}


Once we have our provider now we can insert/add data as we wish and use a consumer in the second screen to get our data.

how to add data ...

class MyItemsScreen extends StatefulWidget {
  const MyItemsScreen({ Key? key }) : super(key: key);

  @override
  _MyItemsScreenState createState() => _MyItemsScreenState();
}

class _MyItemsScreenState extends State<MyItemsScreen> {
  @override
  Widget build(BuildContext context) {
     final cartItemsProvider = Provider.of<MyCartProvider>(context,
                    listen: false);
    return Scaffold(
      appBar: AppBar(),
      body: Column(children: [
//my cart items
        mycartitem(onTap:(
        cartItemsProvider.addItem(mycartItem);
        ))


      ],),
      
    );
  }
}


In screen B

Container(
            child: Consumer<MyCartProvider>(
              builder: (context,MyCartProvider cartProvider, child) {
//you can even return a list view of all the items here
                return ElevatedButton(
                      onPressed:(){ //your api calls
                    cartProvider.cartItems // the data you need is here
              },
            ),
          ),

Upvotes: 3

Related Questions