0

I've got a PageView.builder that returns pages. Each has a title and a tag. I've also got an EditPagewhich allows the user to edit the title. The edited title is updated via PHP on a MySQL database.
Can I get the individual page to automatically update with the new title? Or do I have to completely rebuild the PageView each time I update the title?

Here's the PageView.builder code;

class StageBuilder extends StatelessWidget {
  final List<SpeakContent> speakcrafts;

  StageBuilder(this.speakcrafts);

  @override
  Widget build(context) {
    return PageView.builder(
      itemCount: speakcrafts.length,
      itemBuilder: (context, int currentIndex) {
        return createViewItem(speakcrafts[currentIndex], context);
      },
    );
  }

  Widget createViewItem(SpeakContent speakcraft, BuildContext context) {

    return Column(
      children: <Widget>[
        Row(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              speakcraft.title,
            ),
          ],
        ),
        Row(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              speakcraft.tagname,
            ),
          ],
        ),
      ],
    );
  }
}

And here's the code for posting to the PHP/MYSQL database;

Future<String> titleUpdate({String opid, String title}) async {
  String upDateUrl;
  upDateUrl = "http://example.com?title=" + title;

  final response = await get(upDateUrl);

  if (response.statusCode == 200) {
    print(response.body);
    return response.body;
  } else
    throw Exception('We were not able to successfully update the title');
}
Meggy
  • 1,491
  • 3
  • 28
  • 63
  • Use a list of keys, assign one to each page and call setState on the required page after edit. – Crazzygamerr Aug 13 '20 at 08:53
  • Any chance of some example code? – Meggy Aug 13 '20 at 20:23
  • Wrap your pages in a form like ```Form(key: formKey, child:myWidget()),``` and define formKey as ```GlobalKey formKey = new GlobalKey();``` – Crazzygamerr Aug 14 '20 at 02:33
  • So in the above code I would wrap Column in that form? – Meggy Aug 14 '20 at 09:44
  • Naw, you have to use a different key for each page so wrap ```createViewItem```. Pls make sure to use a list of keys. Like: ```List> formKey = new List(items); for(int i=0;i;```. – Crazzygamerr Aug 14 '20 at 11:49
  • createViewItem being a method won't let me wrap it. Where exactly should I wrap? – Meggy Aug 14 '20 at 12:11
  • So I wrapped createViewItem (the return) and added List> formKey = new List(items); for(int i=0;i; But I'm guessing "items" should contain something other than "items" cuz Android Studio has underlined it in red. – Meggy Aug 14 '20 at 12:33
  • My bad, I forgot that you don't have to initialize the list. It's syntax is: ```List test = new List>(speakCreafts.length);```. And your createViewItem looks like: ```itemBuilder: (context, int currentIndex) { return Form(key: test[currentIndex], child: createViewItem(speakcrafts[currentIndex], context),); },``` And yes, items is the number of createViewItems you have – Crazzygamerr Aug 15 '20 at 07:51
  • Sorry for the bad formatting, comments don't accept line breaks – Crazzygamerr Aug 15 '20 at 07:53
  • 1
    RE: "comments don't accept line breaks" If you put the code into the "answer" button, I can accept it so you can get points. – Meggy Aug 15 '20 at 10:08
  • OK, that code didn't throw any errors. Now how do I call the page to be rebuilt? – Meggy Aug 15 '20 at 10:22

2 Answers2

0

The ListView's syntax is: List test = new List<GlobalKey<FormState>>(speakCreafts.length);.

And your createViewItem looks like:

  return Form(
    key: test[currentIndex], 
    child: createViewItem(speakcrafts[currentIndex], context),
    );      
  }, 

And yes, items is the number of createViewItems you have.

To rebuild your page, you have to call the same setState with reference like:

test[index].currentState.setState(() {});

Thx for the points @Meggy! XD

Crazzygamerr
  • 346
  • 2
  • 11
  • Pls make sure to give a proper value to index. Preferrably call it inside the ListView where you can use currentIndex itself. It is okay to call outside too, just make sure you don't mix up the indexes. – Crazzygamerr Aug 16 '20 at 16:00
  • How do I pass test[currentIndex] to the "EditPage" so that I can use it to call setState and rebuild the page upon a successful 200 response from my server? – Meggy Aug 16 '20 at 18:39
  • Wait wait wait. Don't tell me you are not using futurebuilder? It just hit me now, coz I was thinking that you needed to ahh goddamn. Just look up FutureBuilder and StreamBuilder – Crazzygamerr Aug 17 '20 at 05:23
  • And no, you can't pass currentIndex like that. I was thinking where you called your future coz you asked this question and it never occured to me that FutureBuilder is just what you need. It rebuilds the page after recieving the future. Sorry..... – Crazzygamerr Aug 17 '20 at 05:27
  • So you're saying that "createViewItem" should be wrapped in a future and give the title and tagname as snapshot.data? – Meggy Aug 17 '20 at 08:54
0

Though not exactly what I wanted, in the end, I decided to allow the user back to the updated page through the appbar; The parameters I sent rebuilt a new page with just the one edited page.

 appBar: AppBar(
    title: Text(
      "Back to edited page",
      style: TextStyle(
        fontSize: 14,
        color: Colors.blueGrey,
      ),
    ),

    leading: new IconButton(
      icon: new Icon(
        Icons.arrow_back,
        color: Colors.white,
      ),
      onPressed: () {
        Navigator.push(
            context,
            PageTransition(
              type: PageTransitionType.downToUp,
              child: HomePage(stagetype: 'edit', currentaudioid: widget.opid,),
            ));
      },
    ),
   ),
Meggy
  • 1,491
  • 3
  • 28
  • 63