请参考我的 Github https://github.com/anandh-ps/flutter_mvvm_example
。这与编程有关。
MediaService.dart
import 'dart:convert';
import 'dart:io';
import 'package:meta/meta.dart';
import 'package:http/http.dart' as http;
import 'package:mvvm_flutter_app/model/apis/app_exception.dart';
class MediaService {
final String _baseUrl = "https://itunes.apple.com/search?term=";
Future<dynamic> get(String url) async {
dynamic responseJson;
try {
final response = await http.get(_baseUrl + url);
responseJson = returnResponse(response);
} on SocketException {
throw FetchDataException('No Internet Connection');
}
return responseJson;
}
@visibleForTesting
dynamic returnResponse(http.Response response) {
switch (response.statusCode) {
case 200:
dynamic responseJson = jsonDecode(response.body);
return responseJson;
case 400:
throw BadRequestException(response.body.toString());
case 401:
case 403:
throw UnauthorisedException(response.body.toString());
case 500:
default:
throw FetchDataException(
'Error occured while communication with server' +
' with status code : ${response.statusCode}');
}
}
}
MediaRepository.dart
import 'package:mvvm_flutter_app/model/media.dart';
import 'package:mvvm_flutter_app/model/services/media_service.dart';
class MediaRepository {
MediaService _mediaService = MediaService();
Future<List<Media>> fetchMediaList(String value) async {
dynamic response = await _mediaService.get(value);
final jsonData = response['results'] as List;
List<Media> mediaList =
jsonData.map((tagJson) => Media.fromJson(tagJson)).toList();
return mediaList;
}
}
MediaViewModel.dart
import 'package:flutter/cupertino.dart';
import 'package:mvvm_flutter_app/model/apis/api_response.dart';
import 'package:mvvm_flutter_app/model/media.dart';
import 'package:mvvm_flutter_app/model/media_repository.dart';
class MediaViewModel with ChangeNotifier {
ApiResponse _apiResponse = ApiResponse.loading('Fetching artist data');
Media _media;
ApiResponse get response {
return _apiResponse;
}
Media get media {
return _media;
}
Future<void> fetchMediaData(String value) async {
try {
List<Media> mediaList = await MediaRepository().fetchMediaList(value);
_apiResponse = ApiResponse.completed(mediaList);
} catch (e) {
_apiResponse = ApiResponse.error(e.toString());
print(e);
}
notifyListeners();
}
void setSelectedMedia(Media media) {
_media = media;
notifyListeners();
}
}
HomeScreen.dart
import 'package:flutter/material.dart';
import 'package:mvvm_flutter_app/model/apis/api_response.dart';
import 'package:mvvm_flutter_app/model/media.dart';
import 'package:mvvm_flutter_app/view/widgets/player_list_widget.dart';
import 'package:mvvm_flutter_app/view/widgets/player_widget.dart';
import 'package:mvvm_flutter_app/view_model/media_view_model.dart';
import 'package:provider/provider.dart';
class HomeScreen extends StatefulWidget {
@override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
final _inputController = TextEditingController();
ApiResponse apiResponse = Provider.of<MediaViewModel>(context).response;
List<Media> mediaList = apiResponse.data as List<Media>;
return Scaffold(
appBar: AppBar(
title: Text('Media Player'),
),
body: Column(
children: <Widget>[
Padding(
padding: const EdgeInsets.symmetric(vertical: 10.0),
child: Row(
children: <Widget>[
Expanded(
child: Container(
margin: EdgeInsets.symmetric(horizontal: 20.0),
decoration: BoxDecoration(
color: Theme.of(context).accentColor.withAlpha(50),
borderRadius: BorderRadius.circular(30.0),
),
child: TextField(
style: TextStyle(
fontSize: 15.0,
color: Colors.grey,
),
controller: _inputController,
onChanged: (value) {},
onSubmitted: (value) {
if (value.isNotEmpty) {
Provider.of<MediaViewModel>(context)
.setSelectedMedia(null);
Provider.of<MediaViewModel>(context,
listen: false)
.fetchMediaData(value);
}
},
decoration: InputDecoration(
border: InputBorder.none,
enabledBorder: InputBorder.none,
focusedBorder: InputBorder.none,
prefixIcon: Icon(
Icons.search,
color: Colors.grey,
),
hintText: 'Enter Artist Name',
)),
),
),
],
),
),
mediaList != null && mediaList.length > 0
? Expanded(
child: PlayerListWidget(mediaList, (Media media) {
Provider.of<MediaViewModel>(context)
.setSelectedMedia(media);
}))
: Expanded(
child: Center(
child: Text('Search the song by Artist'),
),
),
if (Provider.of<MediaViewModel>(context).media != null)
Align(
alignment: Alignment.bottomCenter,
child: PlayerWidget(
function: () {
setState(() {});
},
)),
],
));
}
}