Dasar Flutter untuk Pemula (Bagian VII)

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:





  • Tautan ke Github





  • Kelas gambar





  • Menambahkan aset dan gambar





Kode yang bagus semuanya!








All Articles