본문 바로가기

소프트웨어 /Flutter

[Flutter] 이미지 불러올 때 로딩 바 생성, loadingBuilder 사용하기

반응형

이미지를 불러오다보면 이미지의 크기가 크거나 네트워크가 약할 경우 불러오는데 로딩이 있을 수 있다.

따로 CircularProgressIndicator만 사용하여 로딩을 표시하는 방법도 있지만

loadingBuilder는 이미지를 불러오는 동안 위젯을 표시하여 로딩 상태(진행 상태)를 간편하게 나타낼 수 있다.

 

* 계속 이전에 만든 것들을 활용해 이어서 추가할 예정이다.

 

 

loadingBuilder property - Image class - widgets library - Dart API

ImageLoadingBuilder? loadingBuilder final A builder that specifies the widget to display to the user while an image is still loading. If this is null, and the image is loaded incrementally (e.g. over a network), the user will receive no indication of the p

api.flutter.dev

* 해당 문서를 참고하였습니다.

 

실행화면

 

loadingbuilder를 네트워크 이미지를 활용해서 사용해보자. 

  Widget _showImage(context, image){
    return Padding(
      padding: EdgeInsets.only(top: 20.0),
      child: Container(
        width: double.infinity,
        height: 200,
        child: Image.network(image, loadingBuilder: (BuildContext context, Widget child, ImageChunkEvent? loadingProgress){
          if(loadingProgress == null){
            return child;
          }
          return Center(
            child: CircularProgressIndicator(
              value: loadingProgress.expectedTotalBytes != null ? loadingProgress.cumulativeBytesLoaded / loadingProgress.expectedTotalBytes! : null,
            ),
          );
        },
        ),),
    );
  }

 

 

중요한 부분은 Widgetdml _showImage(context, image)이다.

 

loadbuilder 안에

child : 기본 이미지 위젯을 포함하며 null이 보장된다.

loadingProgress : 이미지의 로딩, 진행 상황을 갖고있다.

 

loadingProgress 값을 받아와 CircularProgressIndicator에 진행상황을 value로 입력해주면 이미지가 로드되는 진행률을 나타낼 수 있다.

 

 

*전체코드

 

main.dart

import 'package:flutter/material.dart';
import 'package:test_20210719/home.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Home(),
    );
  }
}

 

 

home.dart

import 'package:flutter/material.dart';
import 'package:test_20210719/detailview.dart';

class Home extends StatelessWidget {
  const Home({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    List<String> mainList = [
      'Cold',
      'Poll',
      'Beam',
      'Greek',
      'Song',
      'Tight',
      'Run',
      'Count'
    ];

    final PageController pageController = PageController(initialPage: 0);

    return Scaffold(
        appBar: AppBar(
          title: Text('TEST'),
        ),
        body: Column(
          children: [
            Container(
              height: 100,
              child: PageView(
                  scrollDirection: Axis.horizontal,
                  controller: pageController,
                  children: [
                      Image.asset('assets/images/a.jpg'),
                      Image.asset('assets/images/b.jpg'),
                      Image.asset('assets/images/c.jpg'),
                  ],
                ),
              ),
            Expanded(
              child: ListView.separated(
                itemCount: mainList.length,
                itemBuilder: (BuildContext context, int index) {
                  return ListTile(
                    onTap: () {
                      Navigator.push(
                        context,
                        MaterialPageRoute(builder: (context) => DetailView()),
                      );
                    },
                    title: Container(
                      alignment: Alignment.centerLeft,
                      height: 50,
                      child: Text(
                        mainList[index],
                        textAlign: TextAlign.start,
                      ),
                    ),
                  );
                }, separatorBuilder: (BuildContext context, int index) { return Divider(thickness: 1); },),
            )
          ],
        )
    );
  }


}

 

detailview.dart

import 'package:flutter/material.dart';

class DetailView extends StatelessWidget {
  const DetailView({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Padding(
        padding: EdgeInsets.only(top: 50.0),
        child: Column(
          children: [
            _showImage(context, 'https://t1.daumcdn.net/cfile/blog/1932F44C4FF2B5CE30?original'),
            _showImage(context, 'https://t1.daumcdn.net/cfile/blog/1152D44C4FF2B5CF04?original'),
          ],
        ),
      )
    );
  }

  Widget _showImage(context, image){
    return Padding(
      padding: EdgeInsets.only(top: 20.0),
      child: Container(
        width: double.infinity,
        height: 200,
        child: Image.network(image, loadingBuilder: (BuildContext context, Widget child, ImageChunkEvent? loadingProgress){
          if(loadingProgress == null){
            return child;
          }
          return Center(
            child: CircularProgressIndicator(
              value: loadingProgress.expectedTotalBytes != null ? loadingProgress.cumulativeBytesLoaded / loadingProgress.expectedTotalBytes! : null,
            ),
          );
        },
        ),),
    );
  }
}