Bases de flutter pour les débutants (partie VII)

La plupart des applications mobiles contiennent diverses images.





Mais qu'en est-il sans eux ? Les images rendent l'interface utilisateur plus riche et plus claire.





Flutter a un support intégré pour les images. La classe la plus couramment utilisée est Image, que nous examinerons dans cet article.





Eh bien, allons-y !





Notre plan
  • Partie 1  - introduction au développement, première annexe, notion d'état ;





  • Partie 2  - fichier pubspec.yaml et utilisation de flutter sur la ligne de commande ;





  • Partie 3  - BottomNavigationBar et Navigator ;





  • Partie 4  - MVC. Nous utiliserons ce modèle particulier comme l'un des plus simples ;





  • Partie 5  - paquet http. Création de la classe Repository, premières demandes, listing des posts ;





  • Partie 6 - travailler avec des formulaires, des zones de texte et créer un article.





  • Partie 7 (article en cours) - travailler avec des images, afficher des images sous forme de grille, recevoir des images du réseau, ajouter les vôtres à l'application ;





  • Partie 8 - créer votre propre thème, ajouter des polices et des animations personnalisées ;





  • Partie 9 - un peu sur les tests ;





Ajouter des images au projet

Tout d'abord, essayons d'ajouter nos propres images au projet.





Attention : les images ajoutées à votre projet augmentent la taille de l'application, alors n'en faites pas trop !





Pour ajouter des images, nous devons créer un nouveau répertoire images



à la racine du projet :





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



n'est pas une panacée et il est donc préférable d'utiliser des bibliothèques spéciales avec plus de fonctionnalités dans les projets de combat.





L'une de ces bibliothèques prometteuses est cached_network_image





Il s'agit d'une bibliothèque assez simple qui prend en charge tous les problèmes et complexités techniques.





Liens utiles:





  • Lien vers Github





  • Classe d'images





  • Ajout d'éléments et d'images





Bon code à tous !








All Articles