Flutter PageView:在多个屏幕中显示来自MySQL数据库的单行数据

huangapple go评论73阅读模式
英文:

Flutter PageView: displaying single row of data from mysql database in multiple screen

问题

我想在Flutter的PageView中显示来自MySQL数据库的单行数据,并且在不同的屏幕上显示。以下网站包含MySQL数据库的JSON数据:https://telugu-signaler.000webhostapp.com/get_user.php。它包含10个用户数据,每个用户有四个列,分别是user_first_name、user_last_name、user_district和user_state。我想在一个屏幕上显示user_first_name和user_last_name,然后向右滑动后在另一个屏幕上显示user_district和user_state。因此,对于10个用户,将有20个页面切换。

以下是我的代码,它在单个屏幕上显示一个用户数据的所有4个字段,但我希望按照上述描述的逻辑来显示。请帮助我解决这个逻辑错误。

import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';

class GetUserData extends StatefulWidget {
  const GetUserData({super.key});

  @override
  State<GetUserData> createState() => _GetUserDataState();
}

class _GetUserDataState extends State<GetUserData> {
  late PageController pageController;

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

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

  Future<List> getUserData() async {
    String url = 'https://telugu-signaler.000webhostapp.com/get_user.php';
    var response = await http.post(Uri.parse(url), body: '');
    var allUserData = jsonDecode(response.body.toString());
    return allUserData;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Get User Data'),
      ),
      body: SafeArea(
        child: Column(
          children: <Widget>[
            Expanded(
              flex: 8,
              child: FutureBuilder<List<dynamic>>(
                future: getUserData(),
                builder: (context, snapshot) {
                  if (snapshot.hasData) {
                    return Padding(
                      padding: const EdgeInsets.all(8.0),
                      child: PageView.builder(
                        controller: pageController,
                        itemCount: snapshot.data!.length * 2,
                        itemBuilder: (context, index) {
                          final userDataIndex = index ~/ 2;
                          var userFirstName =
                              snapshot.data![userDataIndex]['user_first_name'];
                          var userLastName =
                              snapshot.data![userDataIndex]['user_last_name'];
                          var userDistrict =
                              snapshot.data![userDataIndex]['user_district'];
                          var userState =
                              snapshot.data![userDataIndex]['user_state'];

                          return Column(
                            children: [
                              Container(
                                color: Color.fromARGB(255, 231, 229, 229),
                                child: Text(
                                  '$index- First Name: $userFirstName',
                                  style: TextStyle(fontSize: 30),
                                ),
                              ),
                              Container(
                                color: Color.fromARGB(255, 231, 229, 229),
                                child: Text(
                                  'Last Name: $userLastName',
                                  style: TextStyle(fontSize: 30),
                                ),
                              ),
                              SizedBox(
                                height: 50,
                              ),
                              if (index % 2 == 1) // Show district and state on odd pages
                                Container(
                                  color: Colors.lightGreen,
                                  child: Text(
                                    '$index- District: $userDistrict',
                                    style: TextStyle(fontSize: 30),
                                  ),
                                ),
                              if (index % 2 == 1)
                                Container(
                                  color: Colors.lightGreen,
                                  child: Text(
                                    'State: $userState',
                                    style: TextStyle(fontSize: 30),
                                  ),
                                ),
                            ],
                          );
                        },
                      ),
                    );
                  }
                  return const Center(
                    child: CircularProgressIndicator(),
                  );
                },
              ),
            ),
          ],
        ),
      ),
    );
  }
}

希望这有助于解决您的逻辑错误。在这个修改后,奇数页将显示user_district和user_state,而偶数页将显示user_first_name和user_last_name。

英文:

I want to display a single row of data from mysql database in multiple screen in flutter PageView. The following website contains json data of mysql database. https://telugu-signaler.000webhostapp.com/get_user.php. It contains 10 user data, for each user, it has for columns namely user_first_name, user_last_name, user_district and user_state. I want to display user_first_name and user_last_name in a single screen and after swipe right display user_district and user_state in another screen. So, for 10 user there will be 20 page swipe.

The following my code displaying all 4 fields of a user data in a single screen but I want the logic as described above. Please help me to solve this logical error.

import &#39;package:flutter/material.dart&#39;;
import &#39;package:http/http.dart&#39; as http;
import &#39;dart:convert&#39;;
class GetUserData extends StatefulWidget {
const GetUserData({super.key});
@override
State&lt;GetUserData&gt; createState() =&gt; _GetUserDataState();
}
class _GetUserDataState extends State&lt;GetUserData&gt; {
late PageController pageController;
@override
void initState() {
super.initState();
pageController = PageController();
}
@override
void dispose() {
pageController.dispose();
super.dispose();
}
Future&lt;List&gt; getUserData() async {
String url = &#39;https://telugu-signaler.000webhostapp.com/get_user.php&#39;;
var response = await http.post(Uri.parse(url), body: &#39;&#39;);
var allUserData = jsonDecode(response.body.toString());
return allUserData;
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text(&#39;Get User Data&#39;),
),
body: SafeArea(
child: Column(
children: &lt;Widget&gt;[
Expanded(
flex: 8,
child: FutureBuilder&lt;List&lt;dynamic&gt;&gt;(
future: getUserData(),
builder: (context, snapshot) {
if (snapshot.hasData) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: PageView.builder(
controller: pageController,
itemCount: snapshot.data!.length,
itemBuilder: (context, index) {
var userFirstName =
snapshot.data![index][&#39;user_first_name&#39;];
var userLastName =
snapshot.data![index][&#39;user_last_name&#39;];
var userDistrict =
snapshot.data![index][&#39;user_district&#39;];
var userState = snapshot.data![index][&#39;user_state&#39;];
return Column(
children: [
Container(
color: Color.fromARGB(255, 231, 229, 229),
//// I want following two Text() in one screen/page
child: Text(
&#39;$index- First Name: $userFirstName&#39;,
style: TextStyle(fontSize: 30),
),
),
Container(
color: Color.fromARGB(255, 231, 229, 229),
child: Text(
&#39;Last Name: $userLastName&#39;,
style: TextStyle(fontSize: 30),
),
),
SizedBox(
height: 50,
),
//// and after swipe right, I want to display following two Text() in another screen/page
Container(
color: Colors.lightGreen,
child: Text(
&#39;$index- District: $userDistrict&#39;,
style: TextStyle(fontSize: 30),
),
),
Container(
color: Colors.lightGreen,
child: Text(
&#39;State: $userState&#39;,
style: TextStyle(fontSize: 30),
),
),
],
);
},
),
);
}
return const Center(
child: CircularProgressIndicator(),
);
},
),
),
],
),
),
);
}
}

答案1

得分: 1

首先,您需要停止在API调用中使用FutureBuilder,因为FutureBuilder会自我重建并在每次状态更改时调用future函数,这将导致重复调用API。您可以改用bloc或cubit。

现在这里是解决方案:

您只需操纵PageViewBuilder的索引,使PageView的长度为dataList的两倍。在builder中,将索引除以2并取整,然后将其传递给dataList并获取数据,现在如果页面索引是偶数,显示firstName和lastName,否则根据情况显示district和state。

在这里,我在future函数中使用了一些虚拟数据。

您可以参考下面的代码:

@override
Widget build(BuildContext context) {
  return Scaffold(
    appBar: AppBar(
      title: const Text('Get User Data'),
    ),
    body: SafeArea(
      child: Column(
        children: <Widget>[
          Expanded(
            flex: 8,
            child: FutureBuilder<List<dynamic>>(
              future: getUserData(),
              builder: (context, snapshot) {
                if (snapshot.hasData) {
                  return Padding(
                    padding: const EdgeInsets.all(8.0),
                    child: PageView.builder(
                      controller: PageController(),
                      itemCount: snapshot.data!.length * 2,
                      itemBuilder: (context, index) {
                        bool isEvenIndex = index % 2 == 0;
                        int i = (index / 2).floor();
                        String userFirstName =
                            snapshot.data![i]['user_first_name'];
                        String userLastName =
                            snapshot.data![i]['user_last_name'];
                        String userDistrict =
                            snapshot.data![i]['user_district'];
                        String userState = snapshot.data![i]['user_state'];

                        return Column(
                          mainAxisAlignment: MainAxisAlignment.center,
                          children: [
                            Container(
                              color: isEvenIndex
                                  ? const Color.fromARGB(255, 231, 229, 229)
                                  : Colors.lightGreen,
                              child: Text(
                                '${i + 1}. ${isEvenIndex ? 'First Name: $userFirstName' : 'District: $userDistrict'}',
                                style: const TextStyle(fontSize: 30),
                              ),
                            ),
                            Container(
                              color: isEvenIndex
                                  ? const Color.fromARGB(255, 231, 229, 229)
                                  : Colors.lightGreen,
                              child: Text(
                                isEvenIndex
                                    ? 'Last Name: $userLastName'
                                    : 'State: $userState',
                                style: const TextStyle(fontSize: 30),
                              ),
                            ),
                          ],
                        );
                      },
                    ),
                  );
                }
                return const Center(
                  child: CircularProgressIndicator(),
                );
              },
            ),
          ),
        ],
      ),
    ),
  );
}

请按照这个代码示例进行操作。

英文:

Firstly, you need to stop using the FutureBuilder for the api calls, as the FutureBuilder rebuilds it self and calls the future function on every changing state so it will make api call repeatedly, you can use bloc or cubit instead.

For now here is the solution:

you just need manipulate the index of the PageViewBuilder, make the PageView with double the length of the dataList. in the builder divide the index by 2 floor it and pass it to the dataList and and get the data, now if the page index is in even show the firstName and lastName otherwise show district and state accordingly.

here i'm using some dummy data in the future function.

you can refer the below code:

  @override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text(&#39;Get User Data&#39;),
),
body: SafeArea(
child: Column(
children: &lt;Widget&gt;[
Expanded(
flex: 8,
child: FutureBuilder&lt;List&lt;dynamic&gt;&gt;(
future: getUserData(),
builder: (context, snapshot) {
if (snapshot.hasData) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: PageView.builder(
controller: PageController(),
itemCount: snapshot.data!.length * 2,
itemBuilder: (context, index) {
bool isEvenIndex = index % 2 == 0;
int i = (index / 2).floor();
String userFirstName =
snapshot.data![i][&#39;user_first_name&#39;];
String userLastName =
snapshot.data![i][&#39;user_last_name&#39;];
String userDistrict =
snapshot.data![i][&#39;user_district&#39;];
String userState = snapshot.data![i][&#39;user_state&#39;];
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
color: isEvenIndex
? const Color.fromARGB(255, 231, 229, 229)
: Colors.lightGreen,
child: Text(
&#39;${i + 1}. ${isEvenIndex ? &#39;First Name: $userFirstName&#39; : &#39;District: $userDistrict&#39;}&#39;,
style: const TextStyle(fontSize: 30),
),
),
Container(
color: isEvenIndex
? const Color.fromARGB(255, 231, 229, 229)
: Colors.lightGreen,
child: Text(
isEvenIndex
? &#39;Last Name: $userLastName&#39;
: &#39;State: $userState&#39;,
style: const TextStyle(fontSize: 30),
),
),
],
);
},
),
);
}
return const Center(
child: CircularProgressIndicator(),
);
},
),
),
],
),
),
);
}

huangapple
  • 本文由 发表于 2023年6月19日 12:43:19
  • 转载请务必保留本文链接:https://go.coder-hub.com/76503660.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定