简体   繁体   English

如何使用flutter_bloc通过api获取具体数据

[英]How to get the specific data through api by using flutter_bloc

I am beginner in flutter and working on fetching the specific data by using flutter_bloc package.我是 flutter 的初学者,正在使用 flutter_bloc 包获取特定数据。 I have successfully fetch the api data by using flutter_bloc in HomePage but how do i fetch the more specific data.For example in Home Page it fetch the data when i open the app and there is a button at the bottom which moves to new screen that is a Settings Screen which has Two radio buttons and one Raised Button named as Save.When i select any of the radiobutton and click on save button it should moves back to the homepage and calls the api and update the data which was already fetched in homepage.我已经通过在主页中使用 flutter_bloc 成功获取了 api 数据,但是我如何获取更具体的数据。例如,在主页中,它在我打开应用程序时获取数据,底部有一个按钮移动到新屏幕是一个设置屏幕,它有两个单选按钮和一个名为保存的凸起按钮。当我选择任何一个单选按钮并单击保存按钮时,它应该返回主页并调用 api 并更新已在主页中获取的数据. Below is the dart code and bloc code, it will be lengthy but hope you understand my code下面是 dart 代码和 bloc 代码,它会很长但希望你理解我的代码

Main.dart Main.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(),
    );

HomePage.dart首页.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 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());
      }
    }
  }
}

PrayerEvent.dart祈祷活动.dart

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

PrayerState.dart祈祷状态.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祈祷库.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();
    }
  }
}

So these dart code fetch the data from api and load in HomePage when i open the application.Now the second page which is settings page, below is the code所以当我打开应用程序时,这些 dart 代码从 api 获取数据并加载到 HomePage 中。现在第二页是设置页面,下面是代码

SettingsPage.dart设置页面.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')
                        )
                      ],
                    ),
                  ],
                );
              },
            )
          ],
        ),
      ),
    );
  }
  }

MethodBloc.dart方法块.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());
    }
    }
  }
}

MethodEvent.dart方法事件.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;
}

MethodState.dart方法状态.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];
}

MethodRepository.dart MethodRepository.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();
    }
  }
}

PrayerModel.dart祈祷模型.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,
  };
}

Once you've defined the Model for the Stream in bloc, you can easily access the object using BlocBuilder.一旦在 bloc 中为流定义了模型,就可以使用 BlocBuilder 轻松访问该对象。 As demonstrated on the code you've shared, you're able to build a List with buildArticleList() from the Stream.如您共享的代码所示,您可以使用流中的buildArticleList()构建列表。 To access a specific data, you can follow a similar approach for that object.要访问特定数据,您可以对该对象采用类似的方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM