簡體   English   中英

如何使用flutter_bloc通過api獲取具體數據

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

我是 flutter 的初學者,正在使用 flutter_bloc 包獲取特定數據。 我已經通過在主頁中使用 flutter_bloc 成功獲取了 api 數據,但是我如何獲取更具體的數據。例如,在主頁中,它在我打開應用程序時獲取數據,底部有一個按鈕移動到新屏幕是一個設置屏幕,它有兩個單選按鈕和一個名為保存的凸起按鈕。當我選擇任何一個單選按鈕並單擊保存按鈕時,它應該返回主頁並調用 api 並更新已在主頁中獲取的數據. 下面是 dart 代碼和 bloc 代碼,它會很長但希望你理解我的代碼

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

首頁.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];
}

祈禱庫.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 獲取數據並加載到 HomePage 中。現在第二頁是設置頁面,下面是代碼

設置頁面.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];
}

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

祈禱模型.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,
  };
}

一旦在 bloc 中為流定義了模型,就可以使用 BlocBuilder 輕松訪問該對象。 如您共享的代碼所示,您可以使用流中的buildArticleList()構建列表。 要訪問特定數據,您可以對該對象采用類似的方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM