Sebagian besar aplikasi seluler berisi berbagai gambar.
Tapi bagaimana tanpa mereka? Gambar membuat antarmuka pengguna lebih kaya dan lebih jelas.
Flutter memiliki dukungan bawaan untuk gambar. Kelas yang paling umum digunakan adalah Gambar, yang akan kita lihat di artikel ini.
Ayo pergi!
Rencana kita
Bagian 1 - pengantar pembangunan, lampiran pertama, konsep negara;
Bagian 2 - file pubspec.yaml dan menggunakan flutter pada baris perintah;
Bagian 3 - BottomNavigationBar dan Navigator;
Bagian 4 - MVC. Kami akan menggunakan pola khusus ini sebagai salah satu yang paling sederhana;
Bagian 5 - paket http. Pembuatan kelas Repositori, permintaan pertama, daftar posting;
Bagian 6 - bekerja dengan formulir, kotak teks dan membuat posting.
Bagian 7 (artikel saat ini) - bekerja dengan gambar, menampilkan gambar dalam bentuk kisi, menerima gambar dari jaringan, menambahkan gambar Anda sendiri ke aplikasi;
Bagian 8 - membuat tema Anda sendiri, menambahkan font dan animasi khusus;
Bagian 9 - sedikit tentang pengujian;
Menambahkan gambar ke proyek
Pertama, mari kita coba menambahkan gambar kita sendiri ke proyek.
Hati-hati: gambar yang ditambahkan ke proyek Anda meningkatkan ukuran aplikasi, jadi jangan berlebihan!
Untuk menambahkan gambar, kita perlu membuat direktori baru images
di root proyek:
images
pubspec.yaml:
# dependencies: flutter: sdk: flutter # ... # dev_dependencies: # ... # assets flutter: # , MaterialApp # Material Design uses-material-design: true # images # / , # images assets: - images/
. Github':
AlbumListPage
:
import 'package:flutter/material.dart';
import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart';
class AlbumListPage extends StatefulWidget {
@override
_AlbumListPageState createState() => _AlbumListPageState();
}
class _AlbumListPageState extends State<AlbumListPage> {
//
final fileImages = [
"applejack.png",
"fluttershy.png",
"rarity.png",
"starlight_glimmer.png",
"twillight_sparkle.png"
];
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Album List Page"),
),
body: _buildContent()
);
}
//
Widget _buildContent() {
// flutter_staggered_grid_view
// StaggeredGridView
return StaggeredGridView.countBuilder(
//
itemCount: fileImages.length,
// crossAxisCount
//
crossAxisCount: 8,
//
mainAxisSpacing: 10,
//
crossAxisSpacing: 10,
staggeredTileBuilder: (index) {
// 4 ( )
// 2 ( )
return StaggeredTile.count(4, index % 2 == 0 ? 4 : 8);
},
//
itemBuilder: (context, index) {
return Container(
decoration: BoxDecoration(
border: Border.all(color: Colors.pinkAccent, width: 1)
),
// Image.asset
// pubspec.yaml
// asset Image
child: Image.asset("images/${fileImages[index]}"),
);
},
);
}
}
.
! .
REST API .
, AlbumListPage. , , .
.
Photo
:
// Post
class Photo {
final int _id;
final String _title;
final String _url;
Photo.fromJson(Map<String, dynamic> json) :
_id = json["id"],
_title = json["title"],
_url = json["url"];
}
class PhotoList {
final List<Photo> photos = [];
PhotoList.fromJson(List<dynamic> jsonItems) {
for (var jsonItem in jsonItems) {
photos.add(Photo.fromJson(jsonItem));
}
}
}
abstract class PhotoResult {}
class PhotoResultSuccess extends PhotoResult {
final PhotoList photoList;
PhotoResultSuccess(this.photoList);
}
//
class PhotoResultFailure extends PhotoResult {
final String error;
PhotoResultFailure(this.error);
}
//
class PhotoResultLoading extends PhotoResult {
PhotoResultLoading();
}
Repository
:
Future<PhotoList> fetchPhotos() async {
// URL,
//
final url = Uri.parse("$SERVER/photos");
// GET
final response = await http.get(url);
//
if (response.statusCode == 200) {
//
// json.decode
return PhotoList.fromJson(json.decode(response.body));
} else {
//
throw Exception("failed request");
}
}
AlbumController
:
// AlbumController PostController
class AlbumController extends ControllerMVC {
final Repository repo = Repository();
//
PhotoResult currentState = PhotoResultLoading();
void init() async {
try {
//
final photoList = await repo.fetchPhotos();
//
setState(() => currentState = PhotoResultSuccess(photoList));
} catch (error) {
//
setState(() => currentState = PhotoResultFailure(" "));
}
}
}
AlbumListPage
:
class AlbumListPage extends StatefulWidget {
@override
_AlbumListPageState createState() => _AlbumListPageState();
}
class _AlbumListPageState extends StateMVC {
//
// late
late AlbumController _controller;
_AlbumListPageState() : super(AlbumController()){
_controller = controller as AlbumController;
}
@override
void initState() {
super.initState();
// JSONPlaceholder
_controller.init();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Album List Page"),
),
body: _buildContent()
);
}
Widget _buildContent() {
//
final state = _controller.currentState;
if (state is PhotoResultLoading) {
//
return Center(
child: CircularProgressIndicator(),
);
} else if (state is PhotoResultFailure) {
//
return Center(
child: Text(
state.error,
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.headline4!.copyWith(color: Colors.red)
),
);
} else {
final images = (state as PhotoResultSuccess).photoList.photos;
// StaggeredGridView
//
return StaggeredGridView.countBuilder(
//
itemCount: images.length,
// crossAxisCount
//
crossAxisCount: 8,
//
mainAxisSpacing: 10,
//
crossAxisSpacing: 10,
staggeredTileBuilder: (index) {
// 4 ( )
// 2 ( )
return StaggeredTile.count(4, index % 2 == 0 ? 4 : 8);
},
//
itemBuilder: (context, index) {
return Container(
decoration: BoxDecoration(
border: Border.all(color: Colors.pinkAccent, width: 1)
),
// Image.network
//
child: Image.network(
images[index].url,
//
width: double.infinity,
height: double.infinity,
//
fit: BoxFit.cover,
//
// Loading...
loadingBuilder: (context, widget, imageChunkEvent) {
if (imageChunkEvent == null) {
return widget;
}
return Center(child: Text("Loading..."));
},
//
// Error!
errorBuilder: (context, obj, stacktrace) => Center(child: Text("Error!")),
),
);
},
);
}
}
}
.
!
, Flutter .
Image.network
bukan obat mujarab dan oleh karena itu lebih baik menggunakan perpustakaan khusus dengan lebih banyak fungsionalitas dalam proyek pertempuran.
Salah satu perpustakaan yang menjanjikan ini adalah cached_network_image
Ini adalah perpustakaan yang cukup sederhana yang menangani semua masalah teknis dan kompleksitas.
Tautan yang berguna:
Kode yang bagus semuanya!