1. 화면 회전에 따라 레이아웃이 변경되는 것을 막는 방법과, 회전 후 레이아웃을 변경하는 방법을 알아보자.
- main.dart
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:expense_tracker/widgets/expenses.dart';
var kColorScheme = ColorScheme.fromSeed(
seedColor: const Color.fromARGB(255, 96, 59, 181),
);
var kDarkColorScheme = ColorScheme.fromSeed(
brightness: Brightness.dark,
seedColor: const Color.fromARGB(255, 5, 99, 125),
);
void main() {
WidgetsFlutterBinding.ensureInitialized();
SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp,
]).then((fn) {
runApp(
MaterialApp(
darkTheme: ThemeData.dark().copyWith(
useMaterial3: true,
colorScheme: kDarkColorScheme,
cardTheme: const CardTheme().copyWith(
color: kDarkColorScheme.secondaryContainer,
margin: const EdgeInsets.symmetric(
horizontal: 16,
vertical: 8,
),
),
elevatedButtonTheme: ElevatedButtonThemeData(
style: ElevatedButton.styleFrom(
backgroundColor: kDarkColorScheme.primaryContainer,
foregroundColor: kDarkColorScheme.onPrimaryContainer,
),
),
),
theme: ThemeData().copyWith(
useMaterial3: true,
colorScheme: kColorScheme,
appBarTheme: const AppBarTheme().copyWith(
backgroundColor: kColorScheme.onPrimaryContainer,
foregroundColor: kColorScheme.primaryContainer,
),
cardTheme: const CardTheme().copyWith(
color: kColorScheme.secondaryContainer,
margin: const EdgeInsets.symmetric(
horizontal: 16,
vertical: 8,
),
),
elevatedButtonTheme: ElevatedButtonThemeData(
style: ElevatedButton.styleFrom(
backgroundColor: kColorScheme.primaryContainer,
),
),
textTheme: ThemeData().textTheme.copyWith(
titleLarge: TextStyle(
fontWeight: FontWeight.bold,
color: kColorScheme.onSecondaryContainer,
fontSize: 16,
),
),
),
// themeMode: ThemeMode.system, // default
home: const Expenses(),
),
);
});
}
1) 화면 회전 할 때 레이아웃 고정 (시작 부분 참조)
- expenses.dart
import 'package:expense_tracker/widgets/chart/chart.dart';
import 'package:expense_tracker/widgets/expenses_list/expenses_list.dart';
import 'package:expense_tracker/widgets/new_expense.dart';
import 'package:flutter/material.dart';
import 'package:expense_tracker/models/expense.dart';
class Expenses extends StatefulWidget {
const Expenses({super.key});
@override
State<Expenses> createState() {
return _ExpensesState();
}
}
class _ExpensesState extends State<Expenses> {
final List<Expense> _registeredExpenses = [
Expense(
title: 'Flutter Course',
amount: 19.99,
date: DateTime.now(),
category: Category.work,
),
Expense(
title: 'Cinema',
amount: 15.69,
date: DateTime.now(),
category: Category.leisure,
),
];
void _openAddExpenseOverlay() {
showModalBottomSheet(
isScrollControlled: true,
context: context,
builder: (ctx) => NewExpense(
onAddExpense: _addExpense,
));
}
void _addExpense(Expense expense) {
setState(() {
_registeredExpenses.add(expense);
});
}
void _removeExpense(Expense expense) {
final expenseIndex = _registeredExpenses.indexOf(expense);
setState(() {
_registeredExpenses.remove(expense);
});
ScaffoldMessenger.of(context).clearSnackBars();
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
duration: const Duration(seconds: 3),
content: const Text("Expense deleted."),
action: SnackBarAction(
label: "Undo",
onPressed: () {
setState(() {
_registeredExpenses.insert(expenseIndex, expense);
});
},
),
),
);
}
@override
Widget build(BuildContext context) {
final width = MediaQuery.of(context).size.width;
Widget mainContent = const Center(
child: Text("비용 없음, 비용을 추가해주세요."),
);
if (_registeredExpenses.isNotEmpty) {
mainContent = ExpensesList(
expenses: _registeredExpenses,
onRemoveExpense: _removeExpense,
);
}
return Scaffold(
appBar: AppBar(
title: const Text("Flutter ExpenseTracker"),
actions: [
IconButton(
onPressed: _openAddExpenseOverlay, icon: const Icon(Icons.add))
],
),
body: width < 600
? Column(
children: [
Chart(
expenses: _registeredExpenses,
),
Expanded(
child: mainContent,
),
],
)
: Row(
children: [
Expanded(
child: Chart(
expenses: _registeredExpenses,
),
),
Expanded(
child: mainContent,
),
],
),
);
}
}
1) 화면 회전 후, 레이아웃을 변경 하기 위해서는 가로 길이가 어느정도 일 때 이렇게 바꾸라는 식으로 삼항연산자를 활용해서 세팅한다. 아래 코드 부분 참조
final width = MediaQuery.of(context).size.width;
- 결과 화면
'코딩강의 > expense_tracker-반응형,적응형 (플러터-유데미)' 카테고리의 다른 글
139. Building Adaptive Widgets (0) | 2023.09.11 |
---|---|
138. Using the LayoutBuilder Widget (0) | 2023.09.11 |
~137. Understanding "Safe Areas" (0) | 2023.09.10 |