通过更改父项的参数,Flutter重新初始化有状态的小部件

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

我正在努力做到这一点:

  1. 我有一个有状态的小部件PageModule,其中包含一个带有底栏的PageView
  2. 一旦单击中央按钮,它就会打开一个底页以选择是要从相机还是从图库中选择图像
  3. 基于选择,我需要打开NewPost小部件,并考虑使用image_picker包的选择。

问题是当我从底表中选择值时。我无法使NewPost小部件通过选择的内容进行重建。

每次我从底表中选择源时,我应该遵循什么方法来打开正确的ImageSource?

希望我的要求明确。在下面的代码中,我尝试实现了Provider程序,希望解决该问题,但我肯定在这里没有指出要点。

PageModule

class PageModule extends StatefulWidget {
  static const String id = 'start';
  @override
  _PageModuleState createState() => _PageModuleState();
}

class _PageModuleState extends State<PageModule> {
  int _selectedIndex = 0;
  String source = 'gallery';

  PageController pageController = PageController(
    initialPage: 0,
    keepPage: true,
  );

  void onPageChange(int index) {
    setState(() {
      _selectedIndex = index;
    });
  }

  void onTabChange(int index) {
    setState(() {
      _selectedIndex = index;
      pageController.jumpToPage(index);
    });
  }

  void _bottomSheet() {
    showModalBottomSheet(
      shape: kBottomSheetShape,
      context: context,
      builder: (context) => CameraSelector(
        onAction: (String value) {
          Provider.of<SharedData>(context).changeSource(value);
          onTabChange(2);
        },
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Provider<SharedData>(
      create: (context) => SharedData(),
      child: Scaffold(
        floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
        floatingActionButton: FloatingActionButton(
          child: const Icon(Icons.camera),
          onPressed: () {
            _bottomSheet();
          },
        ),
        bottomNavigationBar: BottomAppBar(
          shape: CircularNotchedRectangle(),
          notchMargin: 4.0,
          child: new Row(
            mainAxisSize: MainAxisSize.max,
            mainAxisAlignment: MainAxisAlignment.spaceAround,
            children: <Widget>[
              IconButton(
                icon: Icon(Icons.home),
                onPressed: () {
                  onTabChange(0);
                },
              ),
              IconButton(
                icon: Icon(Icons.search),
                onPressed: () {
                  onTabChange(1);
                },
              ),
              SizedBox(
                width: 50.0,
              ),
              IconButton(
                icon: Icon(Icons.notifications),
                onPressed: () {
                  onTabChange(3);
                },
              ),
              IconButton(
                icon: Icon(Icons.person_pin),
                onPressed: () {
                  onTabChange(4);
                },
              ),
            ],
          ),
        ),
        body: PageView(
          controller: pageController,
          physics: NeverScrollableScrollPhysics(),
          onPageChanged: (index) {
            onPageChange(index);
          },
          children: <Widget>[
            HomeScreen(),
            SearchScreen(),
            NewPostScreen(),
            NotificationScreen(),
            ProfileScreen(),
          ],
        ),
      ),
    );
  }
}

CameraSelector底页

class CameraSelector extends StatelessWidget {
  final Function onAction;

  CameraSelector({@required this.onAction});

  @override
  Widget build(BuildContext context) {
    return SingleChildScrollView(
      child: Container(
          padding: EdgeInsets.only(bottom: 45, top: 25),
          child: Column(
            children: <Widget>[
              Heading(
                size: kH2,
                text: 'Scegli una opzione',
                bold: true,
              ),
              SizedBox(
                height: 20,
              ),
              Row(
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
                  SelectorButton(
                    icon: Icons.photo_size_select_actual,
                    label: 'Libreria',
                    source: Source.gallery,
                    action: (String value) {
                      onAction(value.toLowerCase());
                    },
                  ),
                  SizedBox(
                    width: 20,
                  ),
                  SelectorButton(
                    icon: Icons.camera_alt,
                    label: 'Camera',
                    source: Source.camera,
                    action: (String value) {
                      onAction(value.toLowerCase());
                    },
                  ),
                ],
              ),
            ],
          )),
    );
  }
}

class SelectorButton extends StatelessWidget {
  final IconData icon;
  final String label;
  final String source;
  final Function action;

  SelectorButton({
    @required this.icon,
    @required this.label,
    @required this.source,
    @required this.action,
  });

  @override
  Widget build(BuildContext context) {
    return Container(
      decoration: BoxDecoration(
        borderRadius: BorderRadius.all(Radius.circular(20)),
      ),
      child: InkWell(
        onTap: () {
          Navigator.pop(context);
          action(source);
        },
        borderRadius: BorderRadius.all(Radius.circular(20)),
        child: Container(
          padding: EdgeInsets.symmetric(
            vertical: 20,
            horizontal: 30,
          ),
          decoration: BoxDecoration(
            borderRadius: BorderRadius.all(Radius.circular(20)),
            border: Border.all(color: Colors.grey[850], width: 1.5),
          ),
          child: Column(
            children: <Widget>[
              Icon(
                icon,
                size: 50.0,
                color: Colors.grey[850],
              ),
              SizedBox(
                height: 5,
              ),
              Text(
                label.toUpperCase(),
                style: TextStyle(
                  fontWeight: FontWeight.bold,
                  fontSize: 15,
                  color: Colors.grey[850],
                ),
              )
            ],
          ),
        ),
      ),
    );
  }
}

NewPost

  static const String id = 'newpost';
  @override
  _NewPostScreenState createState() => _NewPostScreenState();
}

class _NewPostScreenState extends State<NewPostScreen> {
  File _image;

  Future getImage() async {
    var image = await ImagePicker.pickImage(
      source: Provider.of<SharedData>(context).source == 'gallery' ? ImageSource.gallery : ImageSource.camera,
      imageQuality: 100,
      maxWidth: 1200,
    );

    setState(() {
      _image = image;
    });
  }

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

  Widget _bodyBuild() {
    if (_image != null) {
      return ListView(
        shrinkWrap: true,
        padding: EdgeInsets.all(20.0),
        children: <Widget>[
          Heading(
            size: kH1,
            text: 'Dettagli del post',
            bold: true,
          ),
          SizedBox(
            height: 20.0,
          ),
          Container(
            height: 100.0,
            child: Center(
              child: Row(
                children: <Widget>[
                  Container(
                    width: 100,
                    child: _image == null
                        ? Text('')
                        : ProfileImage(
                            size: 50,
                            image: _image,
                          ),
                  ),
                  SizedBox(
                    width: 20.0,
                  ),
                  Text('qui box per descrizione')
                ],
              ),
            ),
          ),
          SizedBox(
            height: 20.0,
          ),
          Container(
            decoration: BoxDecoration(
              border: Border(top: BorderSide(width: 1.0, color: Colors.grey[400])),
            ),
          ),
          SizedBox(
            height: 20.0,
          ),
          Heading(
            size: kH3,
            text: 'Tagga gli amici',
            bold: true,
          ),
          SizedBox(
            height: 20.0,
          ),
          Text('lista dei tag degli amici con un input di ricerca con autocompletamento dei risultati'),
          SizedBox(
            height: 20.0,
          ),
          Container(
            decoration: BoxDecoration(
              border: Border(top: BorderSide(width: 1.0, color: Colors.grey[400])),
            ),
          ),
          SizedBox(
            height: 20.0,
          ),
          Heading(
            size: kH3,
            text: 'Aggiungi tag',
            bold: true,
          ),
          SizedBox(
            height: 20.0,
          ),
          Text('lista dei tag argomenti con un input di ricerca con autocompletamento dei risultati')
        ],
      );
    } else {
      return Container();
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Nuovo Post'),
      ),
      body: _bodyBuild(),
    );
  }
}
flutter widget state
1个回答
0
投票

由于您使用的是provider,而不是initState,因此您要查找的是didChangeDependencies / build

这个想法是,当提供者的状态发生变化时,您正在初始化它而不是在创建时初始化它的状态[]这里是什么样子:

class _MyState extends State<MyStatefulWidget> { SomeClass previousSomeClass; @override void didChangeDependencies() { super.didChangeDependencies(); final someClass = Provider.of<Something>(context).someClass; if (someClass != previousSomeClass) { previousSomeClass = someClass; getImage(); } } void getImage() {...} }

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