post-custom-banner

# 디자이너에게 전달 받은 컴포넌트🙋🏻‍♀️

1. 기존 컴포넌트 버튼 코드

flutter 2.0 부터 새로운 버튼 테마들과 함께 스타일 선언방식이 바뀌었다.

  • Material Design variation을 만들려는 경우 styleFrom()를 사용하여 ButtonStyle을 만드는 것이 좋습니다.
  • 가장 유연한 접근 방식은 모양을 재정의하려는 상태에 대한 MaterialStateProperty 값을 사용하여 ButtonStyle을 직접 정의하는 것입니다.

요약하자면,

  • 고정된 Material Design variation사용할 때 styleFrom
TextButton(
  style: TextButton.styleFrom(
    primary: Colors.blue,
    onSurface: Colors.red,
  ),
  ...
)
  • 유동적으로 버튼의 상태 또는 특정 조건에 의해 스타일이 달라질 땐
TextButton(
  style: ButtonStyle(
    overlayColor: MaterialStateProperty.resolveWith<Color>(
      (Set<MaterialState> states) {
        if (states.contains(MaterialState.focused))
          return Colors.red;
        if (states.contains(MaterialState.hovered))
            return Colors.green;
        if (states.contains(MaterialState.pressed))
            return Colors.blue;
        return null; // Defer to the widget's default.
    }),
  ),
  ...
)

component/button.dart

import 'package:flutter/material.dart';
import 'package:flutter_screenutil/screen_util.dart';

import '../../../themes/candy_theme.dart';
import '../../../themes/color_styles.dart';

class CandyButtonStyle {
  CandyButtonStyle._();

  static ButtonStyle get containedButton => ElevatedButton.styleFrom(
        primary: CandyColors.candyBlue,
        shape: RoundedRectangleBorder(
          borderRadius: BorderRadius.circular(2.0),
        ),
        textStyle: CandyTheme.textTheme.headline6,
        minimumSize: Size.fromHeight(
          ScreenUtil().setHeight(56.0),
        ),
      );

  static ButtonStyle get containedButton48 => containedButton.copyWith(
        minimumSize: MaterialStateProperty.all(
          Size.fromHeight(
            ScreenUtil().setHeight(48.0),
          ),
        ),
        textStyle: MaterialStateProperty.all(
          CandyTheme.textTheme.subtitle2,
        ),
      );

  static ButtonStyle get containedButton32 => containedButton.copyWith(
        minimumSize: MaterialStateProperty.all(
          Size.fromHeight(
            ScreenUtil().setHeight(32.0),
          ),
        ),
        textStyle: MaterialStateProperty.all(
          CandyTheme.textTheme.subtitle2,
        ),
      );
      ...

2. 엥? 높이 설정 왜그래

선언 코드

Column(
  mainAxisAlignment: MainAxisAlignment.center,
  children: [
    Row(
      children: [
        Expanded(
          child: ElevatedButton(
            child: const Text('contained button'),
            style: CandyButtonStyle.containedButton,
            onPressed: () {},
          ),
        ),
        Expanded(
          child: TextButton(
            child: const Text('contained disabled button'),
            style: CandyButtonStyle.containedButton,
            onPressed: null,
          ),
        ),
      ],
    ),
    Row(
      children: [
        Expanded(
          child: ElevatedButton(
            child: const Text('contained button'),
            style: CandyButtonStyle.containedButton,
            onPressed: () {},
          ),
        ),
        Expanded(
          child: TextButton(
            child: const Text('contained disabled button'),
            style: CandyButtonStyle.containedButton,
            onPressed: null,
          ),
        ),
      ],
    ),
    ...

높이 설정 이슈 발생..ㅠ

선언해둔 위 버튼은 크기를 스타일 설정하는 속성은 minimumSize뿐이고, 말그대로 minimumSize이기에 해당 위젯의 스타일(예를 들어 텍스트 크기라던지 등) 작을 때만 minimumSize가 유의미하게 쓰일 뿐! 설정해둔 사이즈보다 작을 땐 작은 사이즈가 설정된 것!!

cf.
setting minimumSize height 20

  • A button: height 43 -> 20 ⭕️
  • B button: height 74 -> 20 ⭕️
  • C button: height 14 -> 14 ❌ (minimum size 설정 안됨)


3. 해결책

  • 컴포넌트 코드가 아닌, 선언 코드에서 ConstrainedBox 제약조건 설정 박스로 위젯을 감싸준다.
    • 선언 코드 즉, 밖에서 높이 설정해주고 그에 맞춰 스타일만 적용된 컴포넌트를 사용하면된다.
    • 사이즈 높이만 다를 경우, 스타일 컴포넌트 하나만 만들어줘도 되지만 나와같은 경우 크기에 따라 text size도 달라지기에 각각의 컴포넌트를 살릴 수 밖에
ConstrainedBox(
  constraints: const BoxConstraints.tightFor(height: 48),
  child: Row(
    children: [
      Expanded(
        child: ElevatedButton(
          child: const Text('contained button2'),
          style: CandyButtonStyle.containedButton48,
          onPressed: () {},
        ),
      ),
      Expanded(
        child: TextButton(
          child: const Text('contained disabled button2'),
          style: CandyButtonStyle.containedButton48,
          onPressed: null,
        ),
      ),
    ],
  ),
),

or

Container(
  height: 48,
  width: double.maxFinite,
  child: ElevatedButton(
    child: const Text('contained large'),
    style: CandyButtonStyle.containedButtonLarge,
    onPressed: () {},
  ),
)

or

Container(
	height: 48,
	width: double.maxFinite,
	child: Row(
		children: [
		  Expanded(
		    child: ElevatedButton(
		      child: const Text('contained large'),
		      style: CandyButtonStyle.containedButtonLarge,
		      onPressed: () {},
		    ),
		  ),
		  Expanded(
		    child: TextButton(
		      child: const Text('contained large'),
		      style: CandyButtonStyle.containedButtonLarge,
		      onPressed: null,
		    ),
		  ),
		],
	),
)
profile
𝙸 𝚊𝚖 𝚊 𝚌𝚞𝚛𝚒𝚘𝚞𝚜 𝚍𝚎𝚟𝚎𝚕𝚘𝚙𝚎𝚛 𝚠𝚑𝚘 𝚎𝚗𝚓𝚘𝚢𝚜 𝚍𝚎𝚏𝚒𝚗𝚒𝚗𝚐 𝚊 𝚙𝚛𝚘𝚋𝚕𝚎𝚖. 🇰🇷👩🏻‍💻
post-custom-banner

0개의 댓글