반응형

hint

입력이 없는 상태에서 사용자에게 안내하는 메시지입니다.

TextField(
  decoration: InputDecoration(
    hintText: 'name',
  ),
)

 

focusedBorder

입력창에 커서가 있는 경우의 입력창 밑줄을 꾸미는데 사용됩니다.

focusedBorder: OutlineInputBorder(
  borderSide: BorderSide(
    width: 1,
    color: Colors.green,
  ),
)

 

enabledBorder

입력창이 enable이며 focus가 없는 경우의 입력창의 밑줄을 꾸미는데 사용됩니다.

enabledBorder: OutlineInputBorder(
  borderSide: BorderSide(
    width: 1,
    color: Colors.green,
  ),
)

 

OutlineInputBorder

UnderlineInputBorder을 OutlineInputBorder으로 변경시 밑줄이 테두리로 변경됩니다.

enabledBorder: UnderlineInputBorder(
  borderSide: BorderSide(
    width: 1,
    color: Colors.green,
  ),
)

 

입력값 사용하기

입력된 값을 화면에서 사용하려면 onChanged를 구현해야 합니다.

// 멤버변수
String _title = '';

// 위젯
TextField(
  onChanged: (text) {
    _title = text;
  },
)
반응형
반응형

Container의 테두리 중 아래와 같이

맨 밑에만 색상을 주는 경우가 있습니다.

 

 

 

이때는 Container의  decoration의

border.bottom에 색상 밑 두께를 지정하면 됩니다.

(다른 방향은 left, top, right를 쓰면 됩니다.)

 

Container(
  decoration: const BoxDecoration(
    border: Border(
      bottom: BorderSide(
        color: Colors.black,
        width: 1.0,
      ),
    ),
  ),
)

 

전체소스

Container(
  decoration: const BoxDecoration(
    border: Border(
      bottom: BorderSide(
        color: Colors.black,
        width: 1.0,
      ),
    ),
  ),
  width: double.infinity,
  height: 50,
  child: Row(
    mainAxisAlignment: MainAxisAlignment.spaceBetween,
    children: [
      Container(
        margin: const EdgeInsets.only(left: 15),
        child: const Text('로그아웃'),
      ),
      Container(
        margin: const EdgeInsets.only(right: 15),
        child: const Icon(Icons.settings),
      ),
    ],
  ),
)
반응형
반응형

google sign in 사용시

한번 로그인을 하면 이후에는 이전 계정으로

바로 로그인이 되는 경우가 있다.

 

다른 계정으로 테스트하려는데

그냥 로그인이 되어버려서 난감하다.

 

바로 로그인 되는 코드는 아래와 같다.

final googleSignIn = GoogleSignIn();

 

아래와 같이 옵션을 추가하면

매번 계정을 선택하는 방식으로 변경된다.

final googleSignIn = GoogleSignIn(scopes: ['email', 'profile']);

 

전체소스

Future<UserCredential> signInWithGoogle() async {
  final googleSignIn = GoogleSignIn(scopes: ['email', 'profile']);

  final GoogleSignInAccount? googleUser = await googleSignIn.signIn();

  final GoogleSignInAuthentication? googleAuth =
      await googleUser?.authentication;

  final credential = GoogleAuthProvider.credential(
    accessToken: googleAuth?.accessToken,
    idToken: googleAuth?.idToken,
  );

  return await FirebaseAuth.instance.signInWithCredential(credential);
}

 

반응형

'flutter' 카테고리의 다른 글

[flutter] TextField  (0) 2023.01.25
[flutter] Container Border bottom line  (0) 2023.01.20
플러터로 첫코딩하기! 22- Button의 종류들  (0) 2023.01.03
[flutter] flutter에서 SQLite 사용하기  (0) 2023.01.02
[dart] List.generate  (0) 2023.01.01
반응형

현재 Flutter에서 제공하는 기본적인 버튼은 총 3가지입니다.

 

1.ElevatedButton

2.OutlinedButton

3.TextButton 

 

기본적인 틀은 아래와 같습니다. 

여기서 styleform으로 원하는 모양의 버튼을 만들 수 있습니다. 

 

그리고 Container도 버튼이 될 수 있습니다. 

 GestureDetector를 Container를 감싸주어서 

ontap:  파라미터를 이용해서 버튼으로 만들 수 있습니다. 

 

Flutter에서 제공하는 버튼이 마음에 안든다면 Container로 버튼을 만들어서 사용하는 것도 좋은 방법입니다! 

 

 

 

 

 

import 'package:flutter/material.dart';


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

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: HomePage(),
    );
  }
}

class HomePage extends StatefulWidget {
  const HomePage({Key? key}) : super(key: key);

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('버튼 예제'),),
      body: Center(
        child: Column(mainAxisAlignment: MainAxisAlignment.center,
          children: [
            ElevatedButton(onPressed: (){}, child: Text('ElveatedButton')),
            OutlinedButton(onPressed: (){}, child: Text('OutlinedButton')),
            TextButton(onPressed: (){}, child: Text('TextButton')),
            GestureDetector(
              onTap: (){},
              child: Container(height: 50,
              width: 100,child: Text('Container Button'),),
            ),
          ],
        ),
      ),
    );
  }
}

다음시간에는 이 버튼을 이용해서 페이지 이동을 진행해보겠습니다 

반응형
반응형

패키지 설치

 

1. sqflite

flutter pub add sqflite

https://pub.dev/packages/sqflite/install

 

2. path_provider

flutter pub add path_provider

https://pub.dev/packages/path_provider/install

 

3. path

flutter pub add path

https://pub.dev/packages/path/install

 

 

user.dart

class User {
  int? userId;
  String displayName;

  User({this.userId, required this.displayName});
}

 

db_helper.dart

import 'dart:io';
import 'package:path/path.dart';
import 'package:path_provider/path_provider.dart';
import 'package:sqflite/sqflite.dart';
import 'package:sqflite_test/user.dart';

const String tableName = 'Users';

class DBHelper {
  DBHelper._();
  static final DBHelper _db = DBHelper._();
  factory DBHelper() => _db;

  static Database? _database;

  Future<Database> get database async {
    if (_database != null) return _database!;

    _database = await initDB();
    return _database!;
  }

  initDB() async {
    Directory documentsDirectory = await getApplicationDocumentsDirectory();
    String path = join(documentsDirectory.path, 'UserInfoDB.db');

    return await openDatabase(path, version: 1, onCreate: (db, version) async {
      await db.execute('''
          CREATE TABLE $tableName (
            userId INTEGER PRIMARY KEY,
            displayName TEXT
          )
        ''');
    }, onUpgrade: (db, oldVersion, newVersion) {});
  }

  createData(User user) async {
    final db = await database;
    var res = await db.rawInsert(
        'INSERT INTO $tableName(displayName) VALUES(?)', [user.displayName]);
    return res;
  }

  getUser(int userId) async {
    final db = await database;
    var res = await db
        .rawQuery('SELECT * FROM $tableName WHERE userId = ?', [userId]);
    return res.isNotEmpty
        ? User(
            userId: res.first['userId'] as int,
            displayName: res.first['displayName'] as String)
        : Null;
  }

  Future<List<User>> getAllUsers() async {
    final db = await database;
    var res = await db.rawQuery('SELECT * FROM $tableName');
    List<User> list = res.isNotEmpty
        ? res
            .map((c) => User(
                userId: c['userId'] as int,
                displayName: c['displayName'] as String))
            .toList()
        : [];

    return list;
  }

  deleteUser(int userId) async {
    final db = await database;
    var res = db.rawDelete('DELETE FROM $tableName WHERE userId = ?', [userId]);
    return res;
  }

  deleteAllUsers() async {
    final db = await database;
    db.rawDelete('DELETE FROM $tableName');
  }

  updateUser(User user) async {
    final db = await database;
    var res = db.rawUpdate(
        'UPDATE $tableName SET displayName = ? WHERE userId = ?',
        [user.displayName, user.userId]);
    return res;
  }
}

 

main.dart

import 'package:flutter/material.dart';
import 'package:sqflite_test/add_page.dart';
import 'package:sqflite_test/edit_page.dart';
import 'package:sqflite_test/home_page.dart';

void main() {
  runApp(MaterialApp(
    initialRoute: '/',
    routes: {
      '/': (context) => const HomePage(),
      '/add': (context) => const AddPage(),
      '/edit': (context) => const EditPage(),
    },
  ));
}

 

home_page.dart

import 'package:flutter/material.dart';
import 'package:sqflite_test/User.dart';
import 'package:sqflite_test/db_helper.dart';

class HomePage extends StatefulWidget {
  const HomePage({Key? key}) : super(key: key);

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('SQLite'),
      ),
      floatingActionButton: FloatingActionButton(
        child: const Icon(Icons.add),
        onPressed: () async {
          dynamic ret = await Navigator.pushNamed(context, '/add');
          if (ret != null) {
            User user = ret as User;
            DBHelper().createData(user);
            setState(() {});
          }
        },
      ),
      body: FutureBuilder(
        future: DBHelper().getAllUsers(),
        builder: (BuildContext context, AsyncSnapshot<List<User>> snapshot) {
          if (snapshot.hasData) {
            return ListView.builder(
              itemCount: snapshot.data!.length,
              itemBuilder: (BuildContext context, int index) {
                User item = snapshot.data![index];

                return Card(
                  child: ListTile(
                    onTap: () async {
                      await Navigator.pushNamed(context, '/edit',
                          arguments: item);
                      setState(() {});
                    },
                    onLongPress: () async {
                      await DBHelper().deleteUser(item.userId!);
                      setState(() {});
                    },
                    title: Text(item.displayName),
                  ),
                );
              },
            );
          } else {
            return const Center(
              child: CircularProgressIndicator(),
            );
          }
        },
      ),
    );
  }
}

 

 

add_page.dart

import 'package:flutter/material.dart';
import 'package:sqflite_test/User.dart';

class AddPage extends StatefulWidget {
  const AddPage({Key? key}) : super(key: key);

  @override
  State<AddPage> createState() => _AddPageState();
}

class _AddPageState extends State<AddPage> {
  final TextEditingController _textController = TextEditingController();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('추가'),
      ),
      body: Column(
        children: [
          TextField(
            controller: _textController,
            decoration: const InputDecoration(
              hintText: '이름을 입력하세요.',
              border: OutlineInputBorder(), //외곽선
            ),
          ),
          ElevatedButton(
              onPressed: () {
                Navigator.pop(context, User(displayName: _textController.text));
              },
              child: const Text('완료')),
        ],
      ),
    );
  }
}

 

edit_page.dart

import 'package:flutter/material.dart';
import 'package:sqflite_test/User.dart';
import 'package:sqflite_test/db_helper.dart';

class EditPage extends StatefulWidget {
  const EditPage({Key? key}) : super(key: key);

  @override
  State<EditPage> createState() => _EditPageState();
}

class _EditPageState extends State<EditPage> {
  final TextEditingController _textController = TextEditingController();

  @override
  Widget build(BuildContext context) {
    User user = ModalRoute.of(context)!.settings.arguments as User;
    _textController.text = user.displayName;

    return Scaffold(
      appBar: AppBar(
        title: const Text('수정'),
      ),
      body: Column(
        children: [
          TextField(
            controller: _textController,
            decoration: const InputDecoration(
              hintText: '이름을 입력하세요.',
              border: OutlineInputBorder(), //외곽선
            ),
          ),
          ElevatedButton(
              onPressed: () {
                user.displayName = _textController.text;
                DBHelper().updateUser(user);
                Navigator.pop(context);
              },
              child: const Text('수정')),
        ],
      ),
    );
  }
}
반응형
반응형

형식

List<E>.generate(int length, E generator(int index),{bool growable: true})

 

설명

length 만큼 0 ~ (index - 1)의 index를 오름차순으로 만든 값을 리스트로 반환.
growable가 false인 경우 리스트 길이는 고정.

 

샘플코드

void main() {
  var list = List<Map>.generate(3, (int index) => {'index': index * index});
  print(list);
}

 

샘플 코드 결과

[{index: 0}, {index: 1}, {index: 4}]

 

반응형
반응형

main.dart

import 'package:flutter/material.dart';

void main() {
  runApp(MaterialApp(
    initialRoute: '/first',
    routes: {
      '/first': (context) => const FirstPage(),
      '/second': (context) => const SecondPage(),
    },
  ));
}

 

first_page.dart

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Welcome to Flutter'),
      ),
      body: Center(
        child: ElevatedButton(
          onPressed: () async {
            Navigator.pushNamed(context, '/second', arguments: '인자로 데이터를 넘깁니다.');
          },
          child: const Text('다음화면'),
        ),
      ),
    );
  }
}

 

second_page.dart

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

  @override
  Widget build(BuildContext context) {
    String argument = ModalRoute.of(context)!.settings.arguments as String;

    return Scaffold(
      appBar: AppBar(
        title: const Text('Second Page'),
      ),
      body: Center(
        child: Text(argument),
      ),
    );
  }
}
반응형
반응형

Button

어플에서 가장 중요한 위젯이 아닐까 합니다. 

 

어플의 기본적인 기능들은 Button에 의해서 실행되는 경우가 많기 때문입니다. 

 

계산기, todo, 일기 등등 Button이 없으면 절대 실행 될 수 없습니다. 

 

 

그렇기 때문에 Button의 필요 요소에 대해 알아보겠습니다. 

 

 

버튼의 종류는 다양합니다. 

 

floattingbutton,TextButton,ElveatedButton,OutlinedButton 등이 있습니다. 

 

위 버튼들의 필수 요소는 onPressed 입니다. 

 

 

onPressed () {}  

이 안에 버튼을 클릭하게 되었을 때 실행하고 싶은 함수들을 넣을 수 있습니다. 

 

 

 

void sum (int a, int b, int c) {

a= 2;
b=3;
c=a+b;

print (c);

}




floattingbutton (
onPressed : (){
sum
} 
child : Text('저장') )

 

int a = 2;

int b=3;

int c=a+b;

 

print(c); 의 값을 구하는 함수 sum을 floattingbutton에 넣었습니다. 

 

그러면 c의 값으로 5가 나올 것입니다. 

 

하나의 함수 뿐만 아니라 

여러 함수들을 동시에 넣을 수도 있습니다. 

 

그렇기에 버튼에 어떠한 기능을 넣을지 어떠한 순서대로 넣을지가 중요합니다! 

 

 

다음은 Button의 여러 기능들에 대해 알아보겠습니다. 

 

반응형

+ Recent posts