본문 바로가기
버킷리스트/앱 만들기

오공완 (with Do it! 플러터 앱 프로그램밍) #9_2

by 또또도전 2024. 5. 12.
반응형

// 이곳에 쓴 내용은 앱 만들기라는 버킷리스트를 달성하기 위해 플러터를 공부하면서 정리하고 있는 내용입니다.

플러터에 대해 아는 것이 거의 없기 때문에 정리하면서 오류가 있을 수 있습니다.

오류를 발견하신 분은 댓글 남겨 주시면 감사하겠습니다.

 

main.dart

import 'package:flutter/material.dart';
import 'largeFileMain.dart';
import 'introPage.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.green),
        useMaterial3: true,
      ),
      home: const IntroPage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Text(widget.title),
        actions: <Widget>[
          MaterialButton(
            onPressed: (){
              Navigator.of(context).push(
                MaterialPageRoute(builder: (context) => const LargeFileMain()));
            },
            child: const Text(
              '로고바꾸기',
              style: TextStyle(color:Colors.white),
            ),
          )
        ],
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            const Text(
              'You have pushed the button this many times:',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.headlineMedium,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: const Icon(Icons.add),
      ), // This trailing comma makes auto-formatting nicer for build methods.
    );
  }
}

 

largeFileMain.dart

import 'dart:io';
import 'package:flutter/material.dart';
import 'package:dio/dio.dart';
import 'package:path_provider/path_provider.dart';

class LargeFileMain extends StatefulWidget {
  const LargeFileMain({super.key});

  @override
  State<StatefulWidget> createState() => _LargeFileMain();
}

class _LargeFileMain extends State<LargeFileMain> {
  final imgUrl=
      'https://www.motherjones.com/wp-content/uploads/2019/12/Getty121719.jpg?w=1200&h=630&crop=1';
  bool downloading = false;
  var progressString = "";
  var file;

  TextEditingController? _editingController;

  @override
  void initState() {
    super.initState();
    _editingController = TextEditingController(
        text: 'https://www.motherjones.com/wp-content/uploads/2019/12/Getty121719.jpg?w=1200&h=630&crop=1');
  }

  Future<void> downloadFile() async {
    Dio dio = Dio();
    try {
      var dir = await getApplicationDocumentsDirectory();
      await dio.download(
          _editingController!.value.text, '${dir.path}/myimage.jpg',
          onReceiveProgress: (rec, total) {
            print('Rec: $rec, Total: $total');
            file = '${dir.path}/myimage.jpg';
            setState(() {
              downloading = true;
              progressString = '${((rec / total) * 100).toStringAsFixed(0)}%';
            });
          });
    } catch (e) {
      print(e);
    }
    setState(() {
      downloading = false;
      progressString = 'Completed';
    });
    print('Download completed');
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: TextField(
            controller: _editingController,
            style: const TextStyle(color: Colors.black),
            keyboardType: TextInputType.text,
            decoration: const InputDecoration(hintText: 'url 입력하세요'),
          ),
        ),
        body: Center(
          child: downloading
              ? SizedBox(
            height: 120,
            width: 200,
            child: Card(
              color: Colors.black,
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
                  const CircularProgressIndicator(),
                  const SizedBox(
                    height: 20,
                  ),
                  Text(
                    'Downloading File: $progressString',
                    style: const TextStyle(
                      color: Colors.white,
                    ),
                  )
                ],
              ),
            ),
          )
              : FutureBuilder(
              builder: (context, snapshot) {
                switch (snapshot.connectionState) {
                  case ConnectionState.none:
                    print('none');
                    return const Text('데이터 없음');
                  case ConnectionState.waiting:
                    print('waiting');
                    return const CircularProgressIndicator();
                  case ConnectionState.active:
                    print('active');
                    return const CircularProgressIndicator();
                  case ConnectionState.done:
                    print('done');
                    if(snapshot.hasData){
                      return snapshot.data as Widget;
                    }
                }
                return const Text('데이터 없음');
              },
              future: downloadWidget(file!),
        )),
    floatingActionButton: FloatingActionButton(
    onPressed: (){
    downloadFile();
    },
    child: const Icon(Icons.file_download),
    ),
    );
  }

  Future<Widget> downloadWidget(String filePath) async{
    File file = File(filePath);
    bool exist = await file.exists();
    FileImage(file).evict();
    if (exist) {
      return Center(
        child: Column(
          children: <Widget>[Image.file(file)],
        ),
      );
    } else {
      return const Text('No Data');
    }
  }
}

 

introPage.dart

import 'dart:io';
import 'package:flutter/material.dart';
import 'package:path_provider/path_provider.dart';
import 'main.dart';

class IntroPage extends StatefulWidget {
  const IntroPage({super.key});

  @override
  State<IntroPage> createState() => _IntroPageState();
}

class _IntroPageState extends State<IntroPage> {
  Widget logo = const Icon(Icons.info, size: 50,);

  @override
  void initState(){
    super.initState();
    initData();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            logo,
            ElevatedButton(
              onPressed: (){
                Navigator.of(context)
                    .pushReplacement(MaterialPageRoute(builder: (context) {
                      return const MyHomePage(
                      title: 'Internal Example',
                      );
                }));
              },
              child: const Text('다음으로 가기'),
           )],
         ),
      ),
    );
  }
  void initData() async {
    var dir = await getApplicationDocumentsDirectory();
    bool fileExist = await File('${dir.path}/myimage.jpg').exists();
    if (fileExist){
      setState(() {
        logo = Image.file(
          File('${dir.path}/myimage.jpg'),
          height: 200,
            width: 200,
            fit: BoxFit.contain,
        );
      });
    }
  }
  }

 

어제 작성했던 내용이 날라가 버려서 이렇게 간단하게 정리하고 끝하려고 한다.

작동은 하나 자꾸 오류 메세지가 뜬다.

이것말고도 리스트 목록을 만들어 놓은 것도 있었는데, 포스팅 글이 날라갔다.

어제 공부는 이렇게 정리.

반응형