翩翩起舞的PageView在setState值时不断重建主部件

问题描述 投票:0回答:1

目前扑通应用结构

StackedHome有一个有2个孩子的pageview。

  • Pageview(parent):
    • 主屏幕(子屏幕#1)
      • 垂直页面视图
      • 底部导航栏
    • UserProfilePage(child#2)

HomeScreen应该把索引值传给UserProfilePage,所以当水平滚动时,我们将得到从HomeScreen传来的ID的用户配置文件屏幕,根据传来的ID,我将显示相关的用户配置文件。

这里是示例视频显示的问题。

https:/drive.google.comfiled1tIypNOHewcFSo2Pf-F97hsQGfDgNVqfWview?usp=sharing。

问题:我设法做到了,而且工作正常,但我的问题是在该变量的setState上。

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

在每次调用HomeScreen > onPageChanged时,我都会更新索引值,并将其传递给父类(StackedHome),而且由于有一个setState来更新配置文件索引(UserProfilePage)......整个应用程序将在每次页面浏览变化时被重建......。

我需要的是禁止主部件在值更新时一次又一次的重建。

叠加首页

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,
        )
      ],
    );
  }
}

主屏幕

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"),
      ]),
    );
  }


}

我希望我的问题足够清楚......我需要把值传给父级,这样我就可以把它传给第二个子级,也就是个人资料屏幕,这样它就会显示与该职位相关的用户资料。

flutter flutter-layout
1个回答
0
投票

哦,哇,用provider和consumer解决了这个问题,通过监听index id的任何更新......这个帖子帮助我解决了这个问题。https:/medium.comflutter-nyca-closer-look-the-provider-packag-993922d3a5a5。

© www.soinside.com 2019 - 2024. All rights reserved.