본문 바로가기

Flutter-플러터/클론코딩

플러터 계산기 클론코딩 11.7 staggered grid view package

반응형

Ressurectionx/calci at flutterawesome.com (github.com)

 

GitHub - Ressurectionx/calci

Contribute to Ressurectionx/calci development by creating an account on GitHub.

github.com

 

 

 

 

배운점 

1. staggered_grid_view 패키지로 계산기 버튼을 구현  

(더 자세한 사용법은 아래 링크 )

flutter_staggered_grid_view | 플러터 패키지 (pub.dev)

 

flutter_staggered_grid_view | Flutter Package

Provides a collection of Flutter grids layouts (staggered, masonry, quilted, woven, etc.).

pub.dev

 

사용법 

1. flutter 프로젝트에서 다음 종속성을 추가합니다.pubspec.yaml

dependencies: ... flutter_staggered_grid_view: <latest_version>

2. 라이브러리에서 다음 가져오기를 추가합니다.

import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart';


 
 

 

 

 

AlignedGridView.count(
  crossAxisCount: 4,
  mainAxisSpacing: 4,
  crossAxisSpacing: 4,
  itemBuilder: (context, index) {
    return Tile(
      index: index,
      extent: (index % 7 + 1) * 30,
    );
  },
);

 

 

2. 계산기 버튼의 자릿수가 커지면 글자 크기 줄이는 함수 

 

TextStyle(fontSize: result.length>5? 50 :80   

삼항연산자 
결과값의 자릿수가 5개 미만이면 글자 크기는 50 아니면 80
 

 

 

 

 

 

 

Main.dart

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'homescreen.dart';

void main(){
  SystemChrome.setSystemUIOverlayStyle(const SystemUiOverlayStyle(
      statusBarColor: Colors.transparent,
      systemNavigationBarColor:   Color(0xffcfd9df),
      systemNavigationBarIconBrightness: Brightness.dark,
      statusBarIconBrightness: Brightness.dark,
    systemNavigationBarDividerColor: Colors.grey

  ));
  runApp(const MyApp());
}

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      theme: ThemeData(primaryColor: Colors.purpleAccent),
      home:const HomeScreen(),
      
    );
  }
}

 

 

Homepage.dart

 

import 'package:flutter/material.dart';
import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart';
import 'package:intl/intl.dart';

import 'button.dart';

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

  @override
  _HomeScreenState createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  String previousNum='';
  String currentNum='';
  String result='';
  String prev_result="";
  String selectedOperation='';

  _onButtonPressed(String value){
    setState((){
      switch(value){
        case "/":
        case "*":
        case "-":
        case "+":
          if(previousNum!=''){
            _calculateResult();
          }
          else{
            previousNum=currentNum;
          }
          currentNum='';
          selectedOperation=value;
          break;

        case "+/-":
          currentNum=convertStringToDouble(currentNum) < 0 ?  currentNum.replaceAll("-", '') : "-$currentNum";
          result=currentNum;
          break;

        case "%":
          currentNum = (convertStringToDouble(currentNum)/100).toString();
          result=currentNum;
          break;

        case "=":
          _calculateResult();
          previousNum='';
          selectedOperation='';
          break;

        case "C":
          _resetCalci();
          break;
          default:
            currentNum=currentNum+value;
            result=currentNum;
            prev_result=previousNum;
      }


    });
  }

  void _calculateResult(){
    double _previousNum=convertStringToDouble(previousNum);

    double _currentNum=convertStringToDouble(currentNum);

    switch(selectedOperation){
      case "+" :_previousNum=_previousNum+_currentNum;
                break;

      case "-" :
        _previousNum=_previousNum - _currentNum;
                break;

      case "/" :
        _previousNum=_previousNum / _currentNum;
                 break;

      case "*" :
        _previousNum=_previousNum * _currentNum;
                 break;
      default:
                  break;
    }

    currentNum=(_previousNum % 1 == 0 ? _previousNum.toInt() : _previousNum ).toString();


    result=currentNum;


  }

  void _resetCalci(){
    previousNum='';
    currentNum='';
    result='';
    selectedOperation='';
    prev_result='';
  }

  convertStringToDouble(String number){
    return double.tryParse(number);
  }

  void _dragToDelete(){
    setState(() {
      if(result.length > 1){
        result=result.substring(0,result.length-1);
        currentNum=result;
      }else{
        result='';
        currentNum='';
      }
      
    });

  }

  // String _formatResult(String number){
  //   var formatter=NumberFormat("###,###.##","en_US");
  //   return formatter.format(number);
  // }
  //

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        decoration: const BoxDecoration(
            gradient: LinearGradient(
                begin: Alignment.topCenter,
                end: Alignment.bottomCenter,
                colors: [
                  Color(0xffe2ebf0),
                  Color(0xffcfd9df),
                ])
        ),
        child: Column(
          mainAxisAlignment: MainAxisAlignment.end,
          crossAxisAlignment: CrossAxisAlignment.end,
          children:  [
             Row(
               mainAxisAlignment: MainAxisAlignment.end,
               children: [
                 Padding(
                   padding: const EdgeInsets.symmetric(vertical: 5.0,horizontal: 25),
                   child: Text(prev_result,style:  const TextStyle(fontSize: 30,fontWeight: FontWeight.bold,color: Colors.brown),),
                 ),
                 Padding(
                   padding: const EdgeInsets.symmetric(vertical: 5.0,horizontal: 18),
                   child: Text(selectedOperation,style:  const TextStyle(fontSize: 50,fontWeight: FontWeight.bold,color: Colors.brown),),
                 ),
               ],
             ),
             GestureDetector(
               onHorizontalDragEnd: (details) => {_dragToDelete()},
               child: Padding(
                padding: const EdgeInsets.symmetric(vertical: 10.0,horizontal: 18),
                child: Text(result,style: TextStyle(fontSize: result.length > 5 ? 50 : 80  ,fontWeight: FontWeight.bold,color: Colors.black),),
            ),
             ),
             SizedBox(
              height: MediaQuery.of(context).size.height*0.61,
              child: Center(child: _buildButtonGrid()),
            )
          ],
        ),
      ),
    );
  }

  Widget _buildButtonGrid() => StaggeredGridView.countBuilder(
    crossAxisCount: 4,
    itemCount: buttons.length,
    padding: const EdgeInsets.symmetric(horizontal: 15,vertical: 5),
    itemBuilder: (context,index){
      return MaterialButton(
        shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(25)),
        elevation: 7,
        padding: const EdgeInsets.all(0),
        color:  (buttons[index].value == selectedOperation && currentNum != "") ? Colors.white :  buttons[index].bgColor,
        splashColor: Colors.purple,

        onPressed: () {
          _onButtonPressed(buttons[index].value);
        },
        child: Text(
          buttons[index].value,
          style: TextStyle(fontSize: buttons[index].value == '=' ? 55 : 30 , fontWeight: FontWeight.bold,
          color:  (buttons[index].value == selectedOperation && currentNum != "") ? Colors.black :  buttons[index].fgColor),),);
    },
    mainAxisSpacing: 10,
    crossAxisSpacing: 10,
    staggeredTileBuilder:(index)=> StaggeredTile.count( buttons[index].value == '=' ?  2:1,1),
  );

}

 

 

Button.dart

 

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

class Button{
  final String value;
  final Color bgColor;
  final Color fgColor;

  Button(this.value, this.bgColor, this.fgColor);
}

    List<Button> buttons=[
      Button("C",   const Color(0xff33e53c).withOpacity(0.6),   Colors.grey.shade800),
      Button("+/-", const Color(0xffd7f825).withOpacity(0.7),   Colors.grey.shade800),
      Button("%",   const Color(0xffd7f825).withOpacity(0.7),   Colors.grey.shade800),
      Button("/",   const Color(0xffffb199).withOpacity(0.6),   Colors.white),
      Button("7",   const Color(0xffe3eeff).withOpacity(0.8),   Colors.grey.shade900),
      Button("8",   const Color(0xffe3eeff).withOpacity(0.8),   Colors.grey.shade900),
      Button("9",   const Color(0xffe3eeff).withOpacity(0.8),   Colors.grey.shade900),
      Button("*",   const Color(0xffffb199).withOpacity(0.6),    Colors.white),
      Button("4",   const Color(0xffe3eeff).withOpacity(0.8),   Colors.grey.shade900),
      Button("5",   const Color(0xffe3eeff).withOpacity(0.8),   Colors.grey.shade900),
      Button("6",   const Color(0xffe3eeff).withOpacity(0.8),   Colors.grey.shade900),
      Button("+",   const Color(0xffffb199).withOpacity(0.6),    Colors.white),
      Button("1",   const Color(0xffe3eeff).withOpacity(0.8),   Colors.grey.shade900),
      Button("2",   const Color(0xffe3eeff).withOpacity(0.8),  Colors.grey.shade900),
      Button("3",   const Color(0xffe3eeff).withOpacity(0.8),   Colors.grey.shade900),
      Button("-",   const Color(0xffffb199).withOpacity(0.6),    Colors.white),
      Button(".",   const Color(0xffe3eeff).withOpacity(0.7),   Colors.grey.shade900),
      Button("0",   const Color(0xffe3eeff).withOpacity(0.7),   Colors.grey.shade900),
      Button("=",   const Color(0xff4791db).withOpacity(0.6),    Colors.grey.shade800),


    ];
반응형