1

我是flutter的初学者,正在使用flutter_bloc包获取特定数据。我已经通过在主页中使用flutter_bloc成功获取了api数据,但是我如何获取更具体的数据。例如,在主页中,当我打开应用程序时它会获取数据,底部有一个按钮可以移动到新屏幕是一个设置屏幕,有两个单选按钮和一个名为保存的凸起按钮。当我选择任何单选按钮并单击保存按钮时,它应该返回主页并调用 api 并更新已在主页中获取的数据. 下面是dart代码和bloc代码,会比较长,希望大家看懂我的代码

主要.dart

void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MultiBlocProvider(
      providers: [
        BlocProvider<PrayerBloc>(
          create: (BuildContext context) => PrayerBloc(repository: PrayerRepositoryImpl()),
        ),
        BlocProvider<MethodBloc>(
          create: (BuildContext context) => MethodBloc(methodRepository: MethodRepositoryImpl()),
        ),
      ],
      child: HomePage(),
    );

主页.dart

class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
  PrayerBloc prayerBloc;
  @override
  void initState() {
    super.initState();
    prayerBloc = BlocProvider.of<PrayerBloc>(context);
    prayerBloc.add(FetchPrayerEvent());
  }
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Builder(
        builder: (context) {
          return Material(
            child: Scaffold(
              appBar: AppBar(
                title: Text("Prayer API"),
              ),
              body: Container(
                child: BlocListener<PrayerBloc, PrayerState>(
                  listener: (context, state) {
                    if (state is PrayerErrorState) {
                      Scaffold.of(context).showSnackBar(
                        SnackBar(
                          content: Text(state.message),
                        ),
                      );
                    }
                  },
                  child: BlocBuilder<PrayerBloc, PrayerState>(
                    builder: (context, state) {
                      if (state is InitialPrayerState) {
                        return buildLoading();
                      } else if (state is PrayerLoadingState) {
                        return buildLoading();
                      } else if (state is PrayerLoadedState) {
                        return buildArticleList(state.item);
                      } else if (state is PrayerErrorState) {
                        return buildErrorUi(state.message);
                      }
                    },
                  ),
                ),
              ),
            ),
          );
        },
      ),
    );
  }
  Widget buildLoading() {
    return Center(
      child: CircularProgressIndicator(),
    );
  }
  Widget buildErrorUi(String message) {
    return Center(
      child: Padding(
        padding: const EdgeInsets.all(8.0),
        child: Text(
          message,
          style: TextStyle(color: Colors.red),
        ),
      ),
    );
  }
  Widget buildArticleList(List<Item> item) {
    return ListView.builder(
      itemCount: item == null ? 0 : item.length,
      itemBuilder: (BuildContext ctx, int pos) {
        return new Container(
          child: new Center(
            child: new Column(
              crossAxisAlignment: CrossAxisAlignment.center,
              children: <Widget>[
                new Card(
                  child: Padding(
                    padding: const EdgeInsets.all(8.0),
                    child: new Container(
                      child: Column(
                        children: <Widget>[
                          Padding(
                            padding: EdgeInsets.only(top: 10.0),
                          ),
                          Row(
                            children: <Widget>[
                              Text("Fajr"),
                              Padding(
                                padding: EdgeInsets.only(left: 50.0),
                              ),
                              Text(item[pos].fajr),
                            ],
                          ),
                          Row(
                            children: <Widget>[
                              Text("Dhuhr"),
                              Padding(
                                padding: EdgeInsets.only(left: 30.0),
                              ),
                              Text(item[pos].dhuhr),
                            ],
                          ),
                          Builder(
                            builder: (context)=>
                                RaisedButton(
                                  onPressed: (){
                                    Navigator.push(
                                      context,
                                      MaterialPageRoute(builder: (context) => SettingsPage()),
                                    );
                                  },
                                ),
                          )
                        ],
                      ),
                    ),
                  ),
                )
              ],
            ),
          ),
        );
      },
    );
  }

Prayer_bloc.dart

class PrayerBloc extends Bloc<PrayerEvent, PrayerState> {
  PrayerRepository repository;
  PrayerBloc({@required this.repository});
  @override
  PrayerState get initialState => InitialPrayerState();
  @override
  Stream<PrayerState> mapEventToState(
    PrayerEvent event,
  ) async* {
    if (event is FetchPrayerEvent) {
      yield PrayerLoadingState();
      try {
        List<Item> item = await repository.getItem();
        yield PrayerLoadedState(item: item);
      } catch (e) {
        yield PrayerErrorState(message: e.toString());
      }
    }
  }
}

祈祷活动.dart

abstract class PrayerEvent extends Equatable {}
class FetchPrayerEvent extends PrayerEvent {
  @override
  // TODO: implement props
  List<Object> get props => null;
}

祷告状态.dart

abstract class PrayerState extends Equatable {
  const PrayerState();
}
class InitialPrayerState extends PrayerState {
  @override
  List<Object> get props => [];
}
class PrayerLoadingState extends PrayerState {
  @override
  List<Object> get props => [];
}
class PrayerLoadedState extends PrayerState {
  List<Item> item;
  PrayerLoadedState({@required this.item});
  @override
  List<Object> get props => null;
}
class PrayerErrorState extends PrayerState {
  String message;
  PrayerErrorState({@required this.message});
  @override
  List<Object> get props => [message];
}

PrayerRepository.dart

abstract class PrayerRepository {
  Future<List<Item>> getItem();
}
class PrayerRepositoryImpl implements PrayerRepository {
  @override
  Future<List<Item>> getItem() async {
    var response = await http.get("https://muslimsalat.com/riyadh.json?key=");
    if (response.statusCode == 200) {
      var data = json.decode(response.body);
      List<Item> item = Welcome.fromJson(data).items;
      return item;
    } else {
      throw Exception();
    }
  }
}

因此,当我打开应用程序时,这些 dart 代码从 api 获取数据并加载到主页中。现在第二页是设置页面,下面是代码

设置页面.dart

class SettingsPage extends StatefulWidget {
  @override
  _SettingsPageState createState() => _SettingsPageState();
}
class _SettingsPageState extends State<SettingsPage> {
  int selectedRadio;
  @override
  void initState() {
    super.initState();
    selectedRadio=0;
  }
  setSelectedRadio(int val){
    setState(() {
      selectedRadio=val;
    });
  }
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: Container(
        child: ListView(
          children: <Widget>[
            BlocBuilder<MethodBloc,MethodState>(
              builder: (context,state){
                return Column(
                  mainAxisAlignment: MainAxisAlignment.start,
                  children: <Widget>[
                    Container(
                      padding: EdgeInsets.all(15.0),
                      child: Text(
                        "Prayer Methods",
                        style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
                      ),
                    ),
                    Column(
                      children: <Widget>[
                        RadioListTile(
                            value: 1,
                            groupValue: selectedRadio,
                            activeColor: Colors.black,
                            title: Text(
                              "Egyptian General Authority of Survey",
                            ),
                            onChanged: (val) {
                              print(val);
                              setSelectedRadio(val);
                            }),
                        RadioListTile(
                            value: 2,
                            groupValue: selectedRadio,
                            activeColor: Colors.black,
                            title: Text(
                              "University Of Islamic Sciences, Karachi (Shafi)",
                            ),
                            onChanged: (val) {
                              print(val);
                              setSelectedRadio(val);
                            }),
                        FloatingActionButton(
                            onPressed: (){
                              Navigator.pop(context);
                              BlocProvider.of<MethodBloc>(context).add(MethodChangedEvent(method: selectedRadio));  //I have try this code in onpressed but unfortunately not succeed
                              print(selectedRadio);
                            },
                            child: Text('Save')
                        )
                      ],
                    ),
                  ],
                );
              },
            )
          ],
        ),
      ),
    );
  }
  }

方法块.dart

class MethodBloc extends Bloc<MethodEvent, MethodState> {
  MethodRepository methodRepository;
  MethodBloc({@required this.methodRepository});
  @override
  MethodState get initialState => InitialMethodState();
  @override
  Stream<MethodState> mapEventToState(
    MethodEvent event,
  ) async* {
    if(event is MethodChangedEvent){
    yield MethodLoadingState();
    try {
    List<Item> item = await methodRepository.getMethod(event.method);
    yield MethodLoadedState(item: item);
    } catch (e) {
    yield MethodErrorState(message: e.toString());
    }
    }
  }
}

方法事件.dart

abstract class MethodEvent extends Equatable {
  const MethodEvent();
}
class MethodChangedEvent extends MethodEvent {
  final int method;
  MethodChangedEvent({this.method}) : assert(method != null);
  @override
  List<Object> get props => null;
}

方法状态.dart

abstract class MethodState extends Equatable {
  const MethodState();
}
class InitialMethodState extends MethodState {
  @override
  List<Object> get props => [];
}
class MethodLoadingState extends MethodState {
  @override
  List<Object> get props => [];
}
class MethodLoadedState extends MethodState {
  List<Item> item;
  MethodLoadedState({@required this.item});
  @override
  List<Object> get props => null;
}
class MethodErrorState extends MethodState {
  String message;
  MethodErrorState({@required this.message});
  @override
  List<Object> get props => [message];
}

方法库.dart

abstract class MethodRepository{
  Future<List<Item>> getMethod(int method);
}
class MethodRepositoryImpl implements MethodRepository {
  @override
  Future<List<Item>> getMethod(int method) async {
    var response = await http.get("https://muslimsalat.com/riyadh/$method.json?key=");
    if (response.statusCode == 200) {
      var data = json.decode(response.body);
      List<Item> item = Welcome.fromJson(data).items;
      return item;
    } else {
      throw Exception();
    }
  }
}

祷告模型.dart

class Welcome {
  String title;
  String query;
  String welcomeFor;
  int method;
  String prayerMethodName;
  String daylight;
  String timezone;
  String mapImage;
  String sealevel;
  TodayWeather todayWeather;
  String link;
  String qiblaDirection;
  String latitude;
  String longitude;
  String address;
  String city;
  String state;
  String postalCode;
  String country;
  String countryCode;
  List<Item> items;
  int statusValid;
  int statusCode;
  String statusDescription;
  Welcome({
    this.title,
    this.query,
    this.welcomeFor,
    this.method,
    this.prayerMethodName,
    this.daylight,
    this.timezone,
    this.mapImage,
    this.sealevel,
    this.todayWeather,
    this.link,
    this.qiblaDirection,
    this.latitude,
    this.longitude,
    this.address,
    this.city,
    this.state,
    this.postalCode,
    this.country,
    this.countryCode,
    this.items,
    this.statusValid,
    this.statusCode,
    this.statusDescription,
  });
  factory Welcome.fromJson(Map<String, dynamic> json) => Welcome(
    title: json["title"],
    query: json["query"],
    welcomeFor: json["for"],
    method: json["method"],
    prayerMethodName: json["prayer_method_name"],
    daylight: json["daylight"],
    timezone: json["timezone"],
    mapImage: json["map_image"],
    sealevel: json["sealevel"],
    todayWeather: TodayWeather.fromJson(json["today_weather"]),
    link: json["link"],
    qiblaDirection: json["qibla_direction"],
    latitude: json["latitude"],
    longitude: json["longitude"],
    address: json["address"],
    city: json["city"],
    state: json["state"],
    postalCode: json["postal_code"],
    country: json["country"],
    countryCode: json["country_code"],
    items: List<Item>.from(json["items"].map((x) => Item.fromJson(x))),
    statusValid: json["status_valid"],
    statusCode: json["status_code"],
    statusDescription: json["status_description"],
  );
  Map<String, dynamic> toJson() => {
    "title": title,
    "query": query,
    "for": welcomeFor,
    "method": method,
    "prayer_method_name": prayerMethodName,
    "daylight": daylight,
    "timezone": timezone,
    "map_image": mapImage,
    "sealevel": sealevel,
    "today_weather": todayWeather.toJson(),
    "link": link,
    "qibla_direction": qiblaDirection,
    "latitude": latitude,
    "longitude": longitude,
    "address": address,
    "city": city,
    "state": state,
    "postal_code": postalCode,
    "country": country,
    "country_code": countryCode,
    "items": List<dynamic>.from(items.map((x) => x.toJson())),
    "status_valid": statusValid,
    "status_code": statusCode,
    "status_description": statusDescription,
  };
}
class Item {
  String dateFor;
  String fajr;
  String shurooq;
  String dhuhr;
  String asr;
  String maghrib;
  String isha;
  Item({
    this.dateFor,
    this.fajr,
    this.shurooq,
    this.dhuhr,
    this.asr,
    this.maghrib,
    this.isha,
  });
  factory Item.fromJson(Map<String, dynamic> json) => Item(
    dateFor: json["date_for"],
    fajr: json["fajr"],
    shurooq: json["shurooq"],
    dhuhr: json["dhuhr"],
    asr: json["asr"],
    maghrib: json["maghrib"],
    isha: json["isha"],
  );
  Map<String, dynamic> toJson() => {
    "date_for": dateFor,
    "fajr": fajr,
    "shurooq": shurooq,
    "dhuhr": dhuhr,
    "asr": asr,
    "maghrib": maghrib,
    "isha": isha,
  };
}
class TodayWeather {
  int pressure;
  String temperature;
  TodayWeather({
    this.pressure,
    this.temperature,
  });
  factory TodayWeather.fromJson(Map<String, dynamic> json) => TodayWeather(
    pressure: json["pressure"],
    temperature: json["temperature"],
  );
  Map<String, dynamic> toJson() => {
    "pressure": pressure,
    "temperature": temperature,
  };
}
4

1 回答 1

0

为 bloc 中的流定义模型后,您可以使用 BlocBuilder 轻松访问该对象。如您共享的代码所示,您可以buildArticleList()从 Stream 构建一个列表。要访问特定数据,您可以对该对象采用类似的方法。

于 2021-11-08T08:37:08.903 回答