2
votes

I had two Stateless Widgets in my Tab Bar View and my app was working fine. But then there was a requirement to make a button in one of the views and change the state of the button hence I made it as Stateful widgets but now the Tab Bar View doesn't accept it and gives the exception on running that ' type 'task' is not a subtype of type 'StatelessWidget''. Can we have only Stateless Widgets in TabBar views? How can i Fix this?

My main.dart file having the TabBarview

import 'package:flutter/material.dart';

import 'package:flutter_convertor/task.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter App',
      theme: ThemeData(

        primarySwatch: Colors.blue,
      ),
      home: DefaultTabController(length: 2,child: MyHomePage(title: '')),
    );
  }
}

class MyHomePage extends StatelessWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

 @override
  Widget build(BuildContext context){


   final list =  ListView.builder(
     itemBuilder: (context, position) {
       //some other implementation
     },
   );


   return Scaffold(

     appBar: AppBar(
       title: Text('Home'), bottom: TabBar(
         tabs: [
           Tab(icon: Icon(Icons.directions_car)),
           Tab(icon: Icon(Icons.directions_transit)),
         ]),
     ),

     body:  TabBarView(children: [list, task()]));
 }
}

My Stateful widget task



class task extends StatefulWidget{

  @override
  taskState createState() => new taskState();
}

class taskState extends State<task> {

 int current_step = 0;
 bool isButtonDisabled;

 @override void initState() {

    super.initState();
    isButtonDisabled = false;
  }

 formReady(){


   setState(() {
     isButtonDisabled = !isButtonDisabled ;
   });
 }


  @override
  Widget build(BuildContext context) {

    Column taskScreen = Column(
        children: <Widget>[Expanded(
            child: ListView(

              children: <Widget>[

                //other implementation

              FlatButton(
              color: Colors.red,
              textColor: Colors.black,
                shape: new RoundedRectangleBorder(borderRadius: new BorderRadius.circular(20.0)),
              disabledColor: Color(0XFFf9c3c1),
              disabledTextColor: Colors.white,
              padding: EdgeInsets.all(8.0),
              splashColor: Colors.red[400],
              onPressed: isButtonDisabled ? null : _completePage
              ,
              child: Text(
              "Completed",
              style: TextStyle(color: Colors.white, fontSize: 15.0, fontWeight: FontWeight.bold),
              ),
              )
              ,
            ],
          )

        ]);


    return taskScreen;
  }

}
1

1 Answers

0
votes

You need to use the AutomaticKeepAliveClientMixin for this to work. It's a fairly simple mixin to use. You only need to include the

@override
bool get wantKeepAlive => true;

and add super.build(context) to your build method.

Your updated class would look something like this:

class task extends StatefulWidget{

  @override
  taskState createState() => new taskState();
}

class taskState extends State<task> with AutomaticKeepAliveClientMixin<task> 


  @override
  Widget build(BuildContext context) {
    super.build(context);
    ...
  }

}