mobile/flutter

flutter - ID 카드 만들기 - stateless widget / stateful widget

예츄 2020. 12. 13. 20:08

간단한 ID 카드를 만들어보자

메인 메소드에서는 NinjaCard()라는 클래스를 실행시켜준다.

그리고 NinjaCard()는 StatelessWidget을 상속하여 (데이터 변하지 않음) 아이디 카드를 만들어본다.

NinjaCard 클래스는 Scaffold() 위젯을 리턴하고, Scaffold() 안에 위젯을 넣어 꾸미면 된다.

 

1. appBar 부분에는 AppBar 위젯을 선언하여, 제목, 제목의 위치, 배경색을주고 플랫하게 만들기 위해 elevation을 0.0으로 설정한다.

2. body 부분는 일단 패딩을 주어 left, top, right, bottom  패딩을 설정한다.

child로 Column위젯을 넣고, Column위젯에 children을 주는데, children은 <Widget> 타입들이다.

처음에 나오는 child에는 동그란 아이콘이 뜨도록 CircleAvatar()을 넣어, 원하는 아이콘 이미지와 radius를 설정한다.

그리고 divider를 넣어 height를 설정하면 줄이 나오고 원하는 만큼 간격을 띌 수 있다.

밑에는 이름, 레벨, 이메일이 나오게 설정을 해주고 간격을 조금씩 띄기 위해서 SizedBox를 이용한다.

! 이메일 부분은 아이콘과 이메일이 가로로 정렬되게 나오기 해야하기 때문에 Row 위젯을 넣어준다.

void main() =>runApp(MaterialApp(

  home: NinjaCard(),

));

class NinjaCard extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.grey[900],
      appBar: AppBar(
        title: Text('Ninja id card'),
        centerTitle: true,
        backgroundColor: Colors.grey[850],
        elevation: 0.0,
      ),
      body:Padding(
        padding: EdgeInsets.fromLTRB(30.0, 40.0, 40.0, 0.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: <Widget>[
            Center(
              child: CircleAvatar(
                backgroundImage: AssetImage('assets/blue.png'),
                radius: 40.0,
              ),
            ),
            Divider(
              height: 60.0, //space between
              color: Colors.grey[800],
            ),
            Text(
              'NAME',
              style: TextStyle(
                color: Colors.grey,
                letterSpacing: 2.0,
              ),
            ),
            SizedBox(height:10.0), //empty box
            Text(
              'Chun-Li',
              style: TextStyle(
                color: Colors.amberAccent[200],
                letterSpacing: 2.0,
                fontSize: 28.0,
                fontWeight:  FontWeight.bold,
              ),
            ),
            SizedBox(height:30.0), //empty box
            Text(
              'CURRENT NINJA LEVEL',
              style: TextStyle(
                color: Colors.grey,
                letterSpacing: 2.0,
              ),
            ),
            SizedBox(height:10.0), //empty box
            Text(
              '8',
              style: TextStyle(
                color: Colors.amberAccent[200],
                letterSpacing: 2.0,
                fontSize: 28.0,
                fontWeight:  FontWeight.bold,
              ),
            ),
            SizedBox(height:30.0),
            Row(
              children: <Widget>[
                Icon(
                  Icons.email,
                  color:Colors.grey[400],
                ),
                SizedBox(width:10.0),
                Text(
                    'chun.li@ninja.com',
                  style: TextStyle(
                    color:Colors.grey[400],
                    fontSize: 18.0,
                    letterSpacing: 1.0,
                  ),
                ),
              ],
            ),
          ],
        ),
      ),
    );
  }
}

Stateless 위젯은 데이터가 변하지 않는다. 

버튼을 눌렀을 때, 위의 데이터가 변하게 만들고 싶다면 Stateful Widget을 사용해야 한다.

버튼을 누르면 레벨이 1씩 오르도록 만들어보자.


아까와는 다르게 NinjaCard는 StatefulWidget을 상속한다.

stful을 입력하면 SatefulWidget이 밑에 뜬다. 이를 클릭하고 클래스 이름을 NinjaCard로 설정한다. 

일단 fab를 만들어서 이를 클릭하면 level이 1씩 증가하도록 만들어야 한다.

먼저 레벨은 0부터 시작하도록 전역으로 선언한 뒤,

appbar에서 floatingActionButton을 추가하여, 누를때마다 +1이 되도록 작성한다.

클릭할 때 setState함수가 실행되어야 데이터를 변경할 수 있다. 

setState가 호출되면 빌드 함수가 trigger된다.

 

flutter API를 확인해보면 다음과 같이 나와있다.

Calling setState notifies the framework that the internal state of this object has changed in a way that might impact the user interface in this subtree, which causes the framework to schedule a build for this State object.

 

나머지는 동일하고, 레벨에 텍스트가 아닌 변수인 ninjaLevel을 넣어주기만 하면된다. 

텍스트로 변수에 해당되는 값을 출력하기 위해 '$ninjaLevel'로 작성한다.

 

import 'package:flutter/material.dart';

void main() =>runApp(MaterialApp(

  home: NinjaCard(),

));
//stateful object --> 시간이 지나면서 데이터 변경할 수 있음.

class NinjaCard extends StatefulWidget {
  @override
  _NinjaCardState createState() => _NinjaCardState();
}

class _NinjaCardState extends State<NinjaCard> {

  int ninjaLevel = 0;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.grey[900],
      appBar: AppBar(
        title: Text('Ninja id card'),
        centerTitle: true,
        backgroundColor: Colors.grey[850],
        elevation: 0.0,
      ),
      floatingActionButton: FloatingActionButton(
        //update ninjaLevel when clicked
        onPressed: (){
          setState((){//when it's called trigger build function!! -- only way
            ninjaLevel+= 1;
          });
        },
        child: Icon(Icons.add),
        backgroundColor: Colors.grey[800],
      ),
      body:Padding(
        padding: EdgeInsets.fromLTRB(30.0, 40.0, 40.0, 0.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: <Widget>[
            Center(
              child: CircleAvatar(
                backgroundImage: AssetImage('assets/blue.png'),
                radius: 40.0,
              ),
            ),
            Divider(
              height: 60.0, //space between
              color: Colors.grey[800],
            ),
            Text(
              'NAME',
              style: TextStyle(
                color: Colors.grey,
                letterSpacing: 2.0,
              ),
            ),
            SizedBox(height:10.0), //empty box
            Text(
              'Chun-Li',
              style: TextStyle(
                color: Colors.amberAccent[200],
                letterSpacing: 2.0,
                fontSize: 28.0,
                fontWeight:  FontWeight.bold,
              ),
            ),
            SizedBox(height:30.0), //empty box
            Text(
              'ninja level',
              style: TextStyle(
                color: Colors.grey,
                letterSpacing: 2.0,
              ),
            ),
            SizedBox(height:10.0), //empty box
            Text(
              '$ninjaLevel',
              style: TextStyle(
                color: Colors.amberAccent[200],
                letterSpacing: 2.0,
                fontSize: 28.0,
                fontWeight:  FontWeight.bold,
              ),
            ),
            SizedBox(height:30.0),
            Row(
              children: <Widget>[
                Icon(
                  Icons.email,
                  color:Colors.grey[400],
                ),
                SizedBox(width:10.0),
                Text(
                    'chun.li@ninja.com',
                  style: TextStyle(
                    color:Colors.grey[400],
                    fontSize: 18.0,
                    letterSpacing: 1.0,
                  ),
                ),
              ],
            ),
          ],
        ),
      ),
    );
  }
}

 

'mobile > flutter' 카테고리의 다른 글

flutter -카드형태로 List를 출력하기  (0) 2020.12.13
flutter - expanded widget / 액션 메뉴, flutter outline  (0) 2020.12.09
flutter - rows, columns  (0) 2020.12.08
flutter - container / padding  (0) 2020.12.08
flutter - button/ icon /  (0) 2020.12.08