whitebear
whitebear

Reputation: 12433

How to access other widget's member

I have two class MyHomepage and BodyLayout.

MyHomePage is scaffold and has the BodyLayout as child

Now I want to access MyHomepage variable from onTapped of BodyLayout

Is it possible? or How should I do?

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);
  final String title; 
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  List<Category> cats = [];
  List<Widget> _myLayouts = [];
  int _currentIndex = 0;

  @override
  void initState() {
    super.initState();
    _myLayouts = [
      new BodyLayout("latest","",key: Key('1')),
      new BodyLayout("pop","",key: Key('2')),
    ];
  }
  void _onItemTapped(int index) {
    setState(() {
      _currentIndex = index; 
    });
  }
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: IndexedStack(children: _myLayouts, index: _currentIndex,),

      bottomNavigationBar: BottomNavigationBar(
      items: const <BottomNavigationBarItem>[
        BottomNavigationBarItem(
          icon: Icon(Icons.home),
          title: Text('Latest'),
        ),
        BottomNavigationBarItem(
          icon: Icon(Icons.business),
          title: Text('Fab'),
        ),
      ],
        currentIndex: _currentIndex,
        selectedItemColor: Colors.amber[800],
        onTap: _onItemTapped,
      ),
    );
  }
}



class BodyLayout extends StatefulWidget {
  final String mode;
  final String catKey;
  BodyLayout(this.mode,this.catKey,{Key key}) : super(key: key);
  @override
  _BodyLayoutState createState() => _BodyLayoutState();
}
class _BodyLayoutState extends State<BodyLayout>{

  void initState(){
    super.initState();


  }

  void onTapped(context,var url) {
   // I want to get variables '_currentIndex' of _MyHomePageState here.
  }

  @override
  Widget build(BuildContext context) {
    return Stack(
      children: <Widget>[
        ListView.builder(
          controller: _controller,
          itemCount: articles.length,
          itemBuilder: (context, index) {
            return ListTile(
              title: Text(articles[index].title),
              onTap: () => onTapped(context,articles[index].url),
            );
          },
        ),
      ]
    );
  }
}

Upvotes: 0

Views: 58

Answers (1)

Harkunwar
Harkunwar

Reputation: 683

You're trying to access private variables of a class in a way that's totally not recommended. But there's a better way to solve your problem. Why not pass the function from the parent?

Create an onTapped function inside of _MyHomePageState instead and pass the function to the BodyLayout

class _MyHomePageState extends State<MyHomePage> {
 ....
 void onTapped(context,var url) {
   // variables are accessible here
  }

@override
  void initState() {
    super.initState();
    _myLayouts = [
      new BodyLayout("latest","",key: Key('1'), onTapped: onTapped),
      new BodyLayout("pop","",key: Key('2'), onTapped: onTapped),
    ];
  }
 ....
}

Now catch this argument in body layout and pass it to the onTap method

class BodyLayout extends StatefulWidget {
  ...
  final Function onTapped;
  BodyLayout(this.mode,this.catKey,{Key key, this.onTapped}) : super(key: key);
  @override
  _BodyLayoutState createState() => _BodyLayoutState(onTapped: onTapped);
}

class _BodyLayoutState extends State<BodyLayout>{
  final Function onTapped;

  _BodyLayoutState({this.onTapped});

  @override
  Widget build(BuildContext context) {
    return Stack(
      children: <Widget>[
        ListView.builder(
          controller: _controller,
          itemCount: articles.length,
          itemBuilder: (context, index) {
            return ListTile(
              title: Text(articles[index].title),
              onTap: () => onTapped(context,articles[index].url),
            );
          },
        ),
      ]
    );
  }

}

Upvotes: 1

Related Questions