alfarqi
alfarqi

Reputation: 41

Flutter PageView keep rebuilding the main widget on setState value

currently flutter app structure

StackedHome has a pageview with 2 children

HomeScreen should pass the index value to UserProfilePage, so when scrolling horizontally, we will get user profilescreen with id passed to that received from HomeScreen. based on the id passed i will display related user profile

Here is sample video showing the problem :

https://drive.google.com/file/d/1tIypNOHewcFSo2Pf-F97hsQGfDgNVqfW/view?usp=sharing

Problem: i managed to do that and its working fine, but my problem on setState of that variable

setState(() {
      _postIndex = postIndex;
    }); 

on each HomeScreen > onPageChanged call i am updating the index value pass it to the parent (StackedHome) class, and since there is a setState to update profile index (UserProfilePage)...the whole app will be rebuild on each pageview change...

What i need is to disable that main widget to be rebuilt again and again on value update..

StackedHome

class StackedHome extends StatefulWidget {
  final int data;
  final Function(int) onDataChange;

  const StackedHome({
    this.data,
    this.onDataChange,
    Key key,
  }) : super(key: key);

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

class _StackedHomeState extends State<StackedHome>{
  PageController pageController;



  int _count = 0;
  int _postIndex = 0;

  void _postId(int postIndex) {

//This cuasing main screen to be rebuilt everytime on pageview scroll
//but getting the value correctly 
  setState(() {
      _postIndex = postIndex;
    }); 

  }

  @override
  void initState() {
    super.initState();
    pageController = PageController();
  }

  @override
  void dispose() {
    pageController.dispose();
    super.dispose();
  }

  int index = 0;

  @override
  Future<void> _refreshPosts() async {
    PostApi postApi = PostApi();

    setState(() {
      postApi.fetchAllPosts();
    });
  }

  Widget build(BuildContext context) {
    PostApi postApi = PostApi();

    return FutureBuilder(
      future: postApi.fetchAllPosts(),
      builder: (BuildContext context, AsyncSnapshot<List<Post>> snapshot) {
        switch (snapshot.connectionState) {
          case ConnectionState.none:
            return apiError('No Connection Made');
            break;

          case ConnectionState.waiting:
          case ConnectionState.active:
            return ApiLoading(color:0xff000000);
            break;

          case ConnectionState.done:
            if (snapshot.hasError) {
              return apiError(snapshot.error.toString());
            }

            if (snapshot.hasData) {
              return _drawPostsList(snapshot.data, context);
            }
            break;
        }

        return Container();
      },
    );
  }




  Widget _drawPostsList(List<Post> posts, BuildContext context) {

    return PageView(      
      reverse: true,
      children: <Widget>[
        HomeScreen(
          posts: posts,
          index: index,
          postId: _postId,//function Passed
        ),
        UserProfilePage(
          posts: posts,
          index: _postIndex,
        )
      ],
    );
  }
}

HomeScreen

class HomeScreen extends StatefulWidget {
  @override
  final List posts;
  final int index;
  final Function(int) postId;

  int getPage() {
    return value;
  }

  void setPage(int page) {
    value = page;
  }

  HomeScreen({Key key, this.posts, this.index, this.postId}) : super(key: key);

  HomeScreenState createState() => HomeScreenState();
}

class HomeScreenState extends State<HomeScreen>
    with SingleTickerProviderStateMixin {
  final PageController _controller = PageController();
  PageController _pageController = PageController();


  int index = 0;   

  @override
  void initState() {
    super.initState();

    //Set pageview inital page
    _pageController = PageController(
      keepPage: true,
      initialPage: widget.getPage(),
    );

  }  

  @override
  Widget build(BuildContext context) {

    return RefreshIndicator(      
      onRefresh: _refreshPosts,
      child: Stack(children: <Widget>[
        PageView.builder(
          controller: _pageController,
          onPageChanged: (index) => setState(() {
            .
            widget.postId(index);//I am calling parent class and updating the vlaue with new index value
            .
          }),
          scrollDirection: Axis.vertical,
          itemBuilder: (context, position) {            

//Build image lists
return _homeList(widget.posts, position);           
          },
        ),
        BottomNavigation("light"),
      ]),
    );
  }


}

i hope my problem is clear enough....i need to pass the value to parent so i can pass it to second child which is the profile screen so it will show user profile realted to that post

Upvotes: 1

Views: 5452

Answers (1)

alfarqi
alfarqi

Reputation: 41

Ohh wow, managed to solve this problem using provider and consumer, by listening to any update on index id... this post helped me to solve it https://medium.com/flutter-nyc/a-closer-look-at-the-provider-package-993922d3a5a5

Upvotes: 1

Related Questions