Flutter

Flutter App Bar/화면크기조절/화면전환

kakaroo 2022. 2. 6. 13:35
반응형

article logo

 

앱 상단부분을 BoxDecoration 위젯으로 감싼뒤, LinearGradient 속성을 적용하여 그라데이션 효과를 줍니다.

 

 

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';

import 'common.dart';

class MyAppBar extends StatelessWidget implements PreferredSizeWidget {
  String _title;
  MyAppBar(this._title);

  @override
  Widget build(BuildContext context) {
    return AppBar(
      toolbarHeight: Common.APPBAR_HEIGHT,
      title: Text(this._title,
        style: TextStyle(
          fontWeight: FontWeight.w600,
          fontFamily: 'Poppins',
          fontSize: Common.APPBAR_FONTSIZE,
        ),
      ),
      centerTitle: true,
      flexibleSpace: Container(
        decoration: BoxDecoration(
            gradient: LinearGradient(
              begin: const FractionalOffset(0.0, 0.0),
              end: const FractionalOffset(1.0, 1.0),
              colors: <Color>[
                const Color(0xFF3366FF),
                const Color(0xFF00CCFF),
              ],
              stops: <double>[0.0, 1.0],
              tileMode: TileMode.clamp,
            )
        ),
      ),
    );
  }

  @override
  Size get preferredSize => new Size.fromHeight(kToolbarHeight);
}

 

<적용화면>

 

 

AppBar에 Icon 적용시 widget property는 다음과 같습니다.

|-----------------------------|

|Leading  Title    Actions[] |

|                                  |

|           Bottom             |

|-----------------------------|

 

PreferredSize 위젯으로 AppBar Size를 조절할 수 있습니다.

 

 


 

<화면크기>

I want to be as big as my parent allows (double.infinity)

I want to be as big as the screen (MediaQuery).

 

1. final width = MediaQuery.of(context).size.width * 0.8;

or

2. double.infinity

 

 


 

 

=========================
화면전환(Navigation)
=========================
lib >> main.dart
    >> first_page.dart
>> second_page.dart

Navigator.push()
Navigator.pop() //현재 화면을 종료하고, 이전 화면으로 전환

import 'package:flutter/material.dart';
import 'package:project_name/first_page.dart';
import 'package:project_name/second_page.dart';

import 'package:flutter/material.dart';
import 'package:flutter_app/second_page.dart';
import 'package:flutter_app/person.dart';
import 'package:flutter_app/GlobalVariable.dart';

class MyApp extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        brightness: Brightness.light,
        primaryColor: Colors.blue,
      ),
      navigatorKey: GlobalVariable.naviagatorState, //context가 없는 클래스에서 사용하기 위해
      home: FirstPage(),//WidgetTest(),
    );
  }
}

//context가 없는 클래스에서 사용하기 위해
class GlobalVariable {
  static final GlobalKey<NavigatorState> naviagatorState =
  GlobalKey<NavigatorState>();
}

class FirstPage extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('First'),
      ),
      body: RaisedButton(
        child: Text('Next page'),
//Future 타입의 반환타입으로 설정 (async, await)
//push 메소드가 어떤 값을 반환할때까지 기다림, 기다리는 동안 앱이 멈추지 않음
//이렇게 일이 끝날때까지 기다리면서 앱이 멈추지 않도록 하는 방식 : 비동기방식
        onPressed: () async {
          final person = Person('넥슨지티', 142);   
          final result = await Navigator.push(context,
              MaterialPageRoute(builder: (context) => SecondPage(person: person)) //인자를 넘김
          );

          firstPageDialog(result);
        },
      ),
    );
  }

  void firstPageDialog(String result) {
    showDialog(
//context가 없는 클래스에서 사용함
        context: GlobalVariable.naviagatorState.currentContext as BuildContext, //as BuildContext 가 없으면 error
        //barrierDismissible - Dialog를 제외한 다른 화면 터치 x
        barrierDismissible: false,
        builder: (BuildContext context) {
          return AlertDialog(
            // RoundedRectangleBorder - Dialog 화면 모서리 둥글게 조절
            shape: RoundedRectangleBorder(
                borderRadius: BorderRadius.circular(10.0)),
            //Dialog Main Title
            title: Column(
              children: <Widget>[
                new Text("Dialog Title"),
              ],
            ),
            //
            content: Column(
              mainAxisSize: MainAxisSize.min,
              crossAxisAlignment: CrossAxisAlignment.start,
              children: <Widget>[
                Text(
                  result,
                ),
              ],
            ),
            actions: <Widget>[
              new FlatButton(
                child: new Text("확인"),
                onPressed: () {
                  Navigator.pop(context);
                },
              ),
            ],
          );
        });
  }
}


import 'package:flutter/material.dart';
import 'package:flutter_app/first_page.dart';
import 'package:flutter_app/person.dart';

class SecondPage extends StatelessWidget {
  final Person person;

  SecondPage({required this.person});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Second'),
      ),
      body: RaisedButton(
        child: Text('Previous page'),
        onPressed: () {
          Navigator.pop(context, 'ok'); //인자를 넘겨줌, 넘겨주지 않으면 null 참조 에러남
        },
      ),
    );
  }
}


=========================
routes를 활용한 네비게이션 (네임드 라우트)
=========================
이동할 페이지의 클래스명을 작성하는 대신 간결하고 체계적인 방법
return MaterialApp(
..
home:FirstPage(),
routes: {
'/1page':(context) => FirstPage(),
'/2page':(context) => SecondPage(),
},
),

** 데이터 전달 관련은 추후에 다시 찾아볼 것


=========================
StatefulWidget 클래스에서 네비게이션 동작시 보이지 않는 뒷페이지의 build 함수도 실행됨
pop 으로 빠져나올 경우에도 새로 그려지므로 build 함수가 재실행됨

네트워크 접속처럼 오래 걸리면서 자주 호출되면 안 되는 처리들은 특정 메소드에 실행해야 한다.
initState() : 위젯이 생성될 때 호출.
dispose() : 위젯이 완전히 종료될 때(pop) 호출.  --> 이전 위젯이 먼저 불리우고, 호출된다.
=========================

반응형

'Flutter' 카테고리의 다른 글

Flutter - 주요 단축기/배너제거/플랫폼구분  (0) 2022.02.06
Flutter - File IO / Delay / 가로모드  (0) 2022.02.06
Flutter - ToJson  (0) 2022.02.06
Flutter - Database  (0) 2022.02.06
Flutter 앱 구조/Widget/Singleton  (0) 2022.02.06