我是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,
};
}