Notice
Recent Posts
Recent Comments
Link
250x250
«   2025/01   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Tags more
Archives
Today
Total
관리 메뉴

혼자서 앱 만드는 개발자 함께하는 AI 세상

[펫버틀러] 반려 동물 고민 상담 앱 - 개발 13 일차 (설정 화면 만들기) 본문

펫버틀러

[펫버틀러] 반려 동물 고민 상담 앱 - 개발 13 일차 (설정 화면 만들기)

혼앱사 2023. 1. 23. 17:06
반응형
  • 설정화면은 앱개발에 있어서 거의 필수 적용해야 하는 페이지다
  • 커뮤니티 앱을 만들 계획이라 따라서 항목들은 프로필 설정 및 공개 설정 알람받기등 공개정보와 링크페이지 공지사항과 카카오톡 문의 
  • 공개 하지 않으면 앱을 서버에 저장하지 않기 때문에 데이터를 백업하거나 복구 할 수 있는기능을 설정페이지에 추가 하고
  • 로그아웃 및 로그인 기능을 설정페이지에 적용했다.
  • 설정페이지가 끝나면 하나씩 기능구현 할 예정이다..

 

  • 아래 최종 적용 페이지 이다.

 

적용 패키지 apache2.0 라이센스 

https://pub.dev/packages/settings_ui

 

settings_ui | Flutter Package

Create native settings for Flutter app in minutes. Use single interfaces to build

pub.dev

 

샘플중에 애플 화면처럼 적용한 예제가 있어 적용 해봤다.

https://github.com/yako-dev/flutter-settings-ui/tree/master/example/lib/screens/gallery

 

GitHub - yako-dev/flutter-settings-ui: Create native settings for Flutter app in a minutes.

Create native settings for Flutter app in a minutes. - GitHub - yako-dev/flutter-settings-ui: Create native settings for Flutter app in a minutes.

github.com

 

 

  • 적용을 위해
  •  flutter pub add  settings_ui

  • import 'package:settings_ui/settings_ui.dart';  추가

  • 전체 소스 입니다.(개발중)
import 'dart:io';
import 'dart:isolate';
import 'dart:ui';

import 'package:flutter/material.dart';
import 'package:flutter_downloader/flutter_downloader.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:intl/intl.dart';
import 'package:path_provider/path_provider.dart';
//import 'package:permission_handler/permission_handler.dart';
import 'package:settings_ui/settings_ui.dart';
import 'package:sqflite/sqflite.dart';
import 'package:filesystem_picker/filesystem_picker.dart';

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

  @override
  State<SettingWidget> createState() => _MyWidgetState();
}

void downloadCallback(String id, DownloadTaskStatus status, int progress) {
  print(
      'Background Isolate Callback: task ($id) is in status ($status) and process ($progress)');
  final SendPort send =
      IsolateNameServer.lookupPortByName('downloader_send_port')!;
  send.send([id, status, progress]);
}

bool darkTheme = true;

class _MyWidgetState extends State<SettingWidget> {
  bool vibration = false;
  late String path = "";
  @override
  initState() {
    // TODO: implement initState
    getDatabasesPath().then((value) {
      path = value;
    });

    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    var downloadfile =
        "/Diary_${DateFormat('yyyyMMddhh24mmss').format(DateTime.now())}.db";
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Colors.amberAccent,
        bottomOpacity: 0.0,
        elevation: 0.0,
        title: const Text(
          '설정',
          style: TextStyle(fontSize: 17),
        ),
        leading: IconButton(
          icon: const Icon(Icons.edit),
          tooltip: '설정',
          onPressed: () {},
        ),
      ),
      body: SettingsList(
        applicationType: ApplicationType.cupertino,
        platform: DevicePlatform.iOS,
        sections: [
          SettingsSection(
            title: Text('설정'),
            tiles: [
              SettingsTile.navigation(
                onPressed: (_) {},
                title: Text('프로필설정'),
                value: Text(''),
              ),
              SettingsTile.switchTile(
                onToggle: (value) {
                  setState(() {
                    darkTheme = value;
                  });
                },
                initialValue: darkTheme,
                title: Row(
                  children: [
                    Icon(Icons.dark_mode),
                    Text(' Dark 모드'),
                  ],
                ),
              ),
              SettingsTile.switchTile(
                onToggle: (value) {
                  setState(() {
                    darkTheme = value;
                  });
                },
                initialValue: darkTheme,
                title: Row(
                  children: [
                    Icon(Icons.people_rounded),
                    Text(' 프로필공개'),
                  ],
                ),
              ),
              SettingsTile.switchTile(
                onToggle: (value) {
                  setState(() {
                    darkTheme = value;
                  });
                },
                initialValue: darkTheme,
                title: Row(
                  children: [
                    Icon(Icons.alarm_on),
                    Text(' 알람받기'),
                  ],
                ),
              ),
            ],
          ),
          SettingsSection(
            title: Text('고객지원'),
            tiles: [
              SettingsTile.navigation(
                onPressed: (_) {},
                title: Row(
                  children: [
                    Icon(Icons.article),
                    Text(' 공지사항'),
                  ],
                ),
                value: Text(''),
              ),
              SettingsTile.navigation(
                onPressed: (_) {},
                title: Row(
                  children: [
                    Icon(Icons.phone_android),
                    Text(' 카카오톡1:1문의'),
                  ],
                ),
                value: Text(''),
              ),
            ],
          ),
          SettingsSection(
              title: Row(
                children: [
                  Text('백업'),
                ],
              ),
              tiles: [
                SettingsTile.navigation(
                  onPressed: (_) async {
                    var directory = await Directory(
                            '/storage/emulated/0/Download/PetButler')
                        .create(recursive: true);
                    getApplicationDocumentsDirectory().then((value) {
                      FilesystemPicker.open(
                        title: '저장폴더',
                        showGoUp: true,
                        rootName: 'Download/',
                        permissionText: '저장권한',
                        context: context,
                        // allowedExtensions: ['.db'],
                        rootDirectory:
                            Directory('/storage/emulated/0/Download'),
                        fsType: FilesystemType.folder,
                        pickText: '저장폴더 저장하기',
                      ).then((value) {
                        File(path + "/Diary.db")
                            .copy(value! + downloadfile)
                            .then((value) => {
                                  Fluttertoast.showToast(
                                      msg: "저장되었습니다. 파일명:" + downloadfile)
                                });
                      });
                    });
                  },
                  title: Row(
                    children: [
                      Icon(Icons.backup),
                      Text(' 백업'),
                    ],
                  ),
                ),
                SettingsTile.navigation(
                    description:
                        Text("백업/복구는 데이터 보증을 하지 않습니다. 중요한 정보는 백업하시기 바랍니다. "),
                    title: Row(
                      children: [
                        Icon(Icons.upload),
                        Text(' 복구'),
                      ],
                    ),
                    onPressed: (context) {
                      getApplicationDocumentsDirectory().then((value) {
                        FilesystemPicker.open(
                          title: '적용파일',
                          context: context,
                          rootDirectory:
                              Directory('/storage/emulated/0/Download'),
                          fsType: FilesystemType.file,

                          // allowedExtensions: ['.db'],
                          fileTileSelectMode: FileTileSelectMode.wholeTile,
                        ).then((value) {
                          if (value != null) {
                            showDialog(
                                context: context,
                                builder: (_) => AlertDialog(
                                        title: Text('적용하시겠습니까?'),
                                        content: Text(''),
                                        actions: <Widget>[
                                          TextButton(
                                            child: Text('취소'),
                                            onPressed: () {
                                              setState(() async {
                                                Navigator.of(context).pop();
                                              });
                                            },
                                          ),
                                          TextButton(
                                              child: Text(
                                                '복구',
                                                style: TextStyle(
                                                    color: Colors.red),
                                              ),
                                              onPressed: () {
                                                if (File(value).length() != 0 &&
                                                    value != null) {
                                                  var auto_path = value!
                                                          .substring(
                                                              0,
                                                              value!
                                                                  .lastIndexOf(
                                                                      "/")) +
                                                      downloadfile;

                                                  File(path + "/Diary.db")
                                                      .copy(auto_path);

                                                  File(value!)
                                                      .copy(path + "/Diary.db");
                                                  setState(() {
                                                    Fluttertoast.showToast(
                                                        msg: "백업된파일로 복구되었습니다.");
                                                    Navigator.of(context).pop();
                                                  });
                                                } else {
                                                  Fluttertoast.showToast(
                                                      msg:
                                                          "해당 파일을 복구 할수 없습니다.");
                                                }
                                              })
                                        ]));
                          }
                        });
                      });
                    }),
              ]),
          SettingsSection(
            title: Text('로그아웃'),
            tiles: [
              SettingsTile.navigation(
                onPressed: (_) {},
                title: Row(
                  children: [
                    Icon(Icons.logout),
                    Text(' 로그아웃'),
                  ],
                ),
              ),
              SettingsTile.navigation(
                onPressed: (_) {},
                title: Row(
                  children: [
                    Icon(Icons.remove_circle),
                    Text('  탈퇴'),
                  ],
                ),
              ),
            ],
          ),
        ],
      ),
    );
  }

  Future<void> _asyncConfirmDialog(BuildContext context) async {
    return showDialog<void>(
      context: context,
      builder: (context) {
        return AlertDialog(
          title: Text('로그아웃 하시겠습니까?'),
          content: Text(''),
          actions: <Widget>[
            TextButton(
              child: Text('취소'),
              onPressed: () {
                setState(() {
                  //sprint(current);
                  Navigator.of(context).pop();
                  //ctr.index = current;
                });
              },
            ),
            TextButton(
              child: Text('확인'),
              onPressed: () {
                Navigator.of(context).pop();
                //  exit(0);
              },
            )
          ],
        );
      },
    );
  }
}

개발에 중요한건 빠른 적용인것같다.

이렇게 정리해서 올리면 나중에 다시 적용할때 빠르게 적용 할 수 있을것같다.

728x90
반응형
Comments