일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Tags
- 오류
- GitHub
- 닷넷
- MSSQL
- AnimationController
- MS-SQL
- page
- Flutter
- HTML
- listview
- .NET
- 바인딩
- MVVM
- 리엑트
- Maui
- typescript
- 깃허브
- 파이어베이스
- 함수
- 애니메이션
- React JS
- 플러터
- 마우이
- Binding
- db
- Firebase
- 자바스크립트
- Animation
- spring boot
- JavaScript
Archives
- Today
- Total
개발노트
81. [Flutter] bottomNavigationBar 로 화면 전환하는 화면에서 미니 플레이어 구현하기 (AnimatedContainer,PopScope) 본문
앱 개발/Flutter
81. [Flutter] bottomNavigationBar 로 화면 전환하는 화면에서 미니 플레이어 구현하기 (AnimatedContainer,PopScope)
mroh1226 2024. 9. 25. 23:46반응형
PopScope의 핵심은 뒤로가기 버튼의 순기능인 뒤로가기를 막고 다른 액션을 줄 수 있다는 것이다.
이 위젯을 이용하여 뒤로가기 버튼을 Player의 크기가 작아지는 버튼으로 사용해본다.
AnimatedContainer의 핵심은 특정 값을 분기를 두고 컨테이너의 크기나 다른 번동사항이 애니메이션으로 편하게 적용된다는 점이다. 이로 크기를 변동시켜본다.
작아졌다 커졌다 하는 Player 소스 (GetX의 GetBuilder 사용함)
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
class MiniPlayerController extends GetxController {
late bool isMinimized; // MiniPlayer의 최소화 상태
void togglePlayerSize() {
isMinimized = !isMinimized; // 상태 전환
update(); // GetBuilder가 UI를 업데이트하도록 알림
}
@override
void onInit() {
isMinimized = true;
super.onInit();
}
}
class MiniPlayer extends StatelessWidget {
MiniPlayer({super.key});
final MiniPlayerController controller =
Get.put(MiniPlayerController()); // 컨트롤러 인스턴스를 생성 및 등록
@override
Widget build(BuildContext context) {
return GetBuilder<MiniPlayerController>(
builder: (controller) => PopScope(
canPop: controller.isMinimized ? true : false,
//canPop: 뒤로가기 버튼 무시여부 false면 무시함
onPopInvokedWithResult: (didPop, result) {
//onPopInvokedWithResult: didPop 상관없이
//뒤로가기 버튼 누르면 실행되는 Function
controller.togglePlayerSize();
},
child: AnimatedContainer(
duration: const Duration(milliseconds: 300),
height: controller.isMinimized ? 70 : 1000, // 상태에 따라 높이를 조정
decoration: BoxDecoration(
color: Colors.blueAccent,
borderRadius: controller.isMinimized
? BorderRadius.circular(30)
: BorderRadius.circular(0), // 작게 표시될 때 테두리를 둥글게
),
child: GestureDetector(
onVerticalDragUpdate: (details) {
if (details.primaryDelta! > 10 && !controller.isMinimized) {
controller.togglePlayerSize();
}
},
child: Column(
children: [
!controller.isMinimized
? const Expanded(
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('Now Playing:'),
SizedBox(height: 10),
Text(
'Song Title',
style: TextStyle(
fontSize: 18, fontWeight: FontWeight.bold),
),
SizedBox(height: 10),
Icon(
Icons.music_note,
size: 50,
color: Colors.white,
),
],
),
),
)
:
// 작아진 상태의 UI
ListTile(
leading:
const Icon(Icons.music_note, color: Colors.white),
title: const Text('Song Title',
style: TextStyle(color: Colors.white)),
trailing: IconButton(
icon: const Icon(Icons.expand_less,
color: Colors.white),
onPressed: controller.togglePlayerSize, // 다시 확장
),
),
],
),
),
),
),
);
}
}
bottomNavigationBar로 화면 전환이 되는 메인 화면
void main() {
runApp(const MainApp()); // MainApp을 실행하는 main 함수
}
class MainApp extends StatelessWidget {
const MainApp({super.key});
@override
Widget build(BuildContext context) {
return GetMaterialApp(
home: Scaffold(
body: Stack(
alignment: Alignment.bottomCenter,
children: [
const IndexedStack(
index: 0,
children: [
Center(child: Text('Page 1')),
Center(child: Text('Page 2')),
Center(child: Text('Page 3')),
],
),
MiniPlayer(), // MiniPlayer를 여기서 호출
],
),
bottomNavigationBar: const BottomNavigation(),
),
);
}
}
class BottomNavigation extends StatelessWidget {
const BottomNavigation({super.key});
@override
Widget build(BuildContext context) {
return GetBuilder<MiniPlayerController>(
init: MiniPlayerController(), // 컨트롤러 초기화
builder: (controller) {
return AnimatedContainer(
height: controller.isMinimized
? kBottomNavigationBarHeight
: 0, // 상태에 따라 높이 조정
duration: const Duration(milliseconds: 300),
child: BottomAppBar(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
IconButton(
icon: const Icon(Icons.ac_unit),
onPressed: () {},
),
IconButton(
icon: const Icon(Icons.access_alarm_outlined),
onPressed: () {},
),
IconButton(
icon: const Icon(Icons.accessibility_sharp),
onPressed: () {},
),
],
),
),
);
},
);
}
}
완료된 사항
반응형
'앱 개발 > Flutter' 카테고리의 다른 글
83. [Flutter] const, final / class형, Function형 위젯 차이 알아보기 (3) | 2024.11.04 |
---|---|
82. [Flutter] GetX 처음 화면으로 이동하기 (until, offAllNamed 차이) (0) | 2024.10.23 |
80. [Flutter] CustomScrollView Sliver안에 Scroll류 위젯을 쓰고 싶다면 (0) | 2024.09.01 |
79. [Flutter] GetBuilder VS Obx 비교 (0) | 2024.08.11 |
78. [Flutter] GetX GetView로 View - Controller - Binding 패턴으로 만들기 (0) | 2024.08.09 |
Comments