티스토리 뷰
Marquee Widget 만들기 (1) - alternate 에서 이어지는 글입니다.
이 글에서는 1번 타입 (계속 한방향으로 흘러가는 Marquee) 을 만들어본 것을 기록합니다.

참고로 Marquee는 flutter package가 이미 몇개있는데,
text 하나만 받을 수 있게 구현되어있더라구요,,
저는 이미지 + text로 된 list를 받을 수 있는 위젯으로 만들어보려고 합니다.
text만 scroll하기 원하신다면 이미 잘되어있는 package를 쓰시기를 추천드립니다.
[1] 코드
이렇게 Marquee 위젯을 만들어주고
import 'package:flutter/cupertino.dart'; | |
class Marquee extends StatefulWidget { | |
final List<Widget> items; | |
final Duration moveDuration; | |
Marquee({ | |
Key key, | |
@required this.items, | |
this.moveDuration = const Duration(milliseconds: 100) | |
}): super(key: key); | |
@override | |
_MarqueeState createState() => _MarqueeState(); | |
} | |
class _MarqueeState extends State<Marquee> { | |
ScrollController _scrollController; | |
double _position = 0.0; | |
@override | |
void initState() { | |
_scrollController = ScrollController(); | |
WidgetsBinding.instance.addPostFrameCallback((_) async { | |
Future.doWhile(_scroll); | |
}); | |
super.initState(); | |
} | |
@override | |
Widget build(BuildContext context) { | |
return ListView.builder( | |
itemBuilder: (context, index) { | |
return Center( | |
child: widget.items[index % widget.items.length] | |
); | |
}, | |
scrollDirection: Axis.horizontal, | |
controller: _scrollController, | |
physics: NeverScrollableScrollPhysics(), // not allow the user to scroll. | |
); | |
} | |
@override | |
void dispose(){ | |
_scrollController.dispose(); | |
super.dispose(); | |
} | |
Future<bool> _scroll() async { | |
double _moveDistance = 10.0; | |
_position += _moveDistance; | |
_scrollController.animateTo(_position, duration: widget.moveDuration, curve: Curves.linear); | |
await Future.delayed(widget.moveDuration); | |
return true; | |
} | |
} |
앱에서 테스트 해봅니다.
import 'package:flutter/cupertino.dart'; | |
import 'marquee.dart'; | |
void main() { | |
runApp(MyApp()); | |
} | |
class MyApp extends StatelessWidget { | |
@override | |
Widget build(BuildContext context) { | |
return CupertinoApp( | |
home: _RootWidget() | |
); | |
} | |
} | |
class _RootWidget extends StatelessWidget { | |
var _textStyle = TextStyle(fontFamily: "Kakao", color: CupertinoColors.white, fontSize: 100); | |
@override | |
Widget build(BuildContext context) { | |
return SafeArea( | |
right: false, // 가로모드에서는 bottom이 아니라 right를 false로 해줘야함,, | |
child: Marquee( | |
items: [ | |
Text("안녕하세요", style: _textStyle), | |
SizedBox(width: 50) | |
], | |
moveDuration: Duration(milliseconds: 50) | |
) | |
); | |
} | |
} |

[2] 코드 설명
이전 글의 alternate marquee와 다른 점은 build 메소드와 scroll 메소드 밖에 없는 데요
이거 위주로 살펴보겠습니다
(나머지 부분은 Marquee Widget 만들기 (1) - alternate 를 참고해주세요!)
## 1.
@override
Widget build(BuildContext context) {
return ListView.builder(
itemBuilder: (context, index) {
return Center(
child: widget.items[index % widget.items.length]
);
},
scrollDirection: Axis.horizontal,
controller: _scrollController,
physics: NeverScrollableScrollPhysics(), // not allow the user to scroll.
);
}
원래 ListView.builder 를 쓸 때는 itemCount를 넘겨줘야합니다.
하지만 itemCount를 안넘겨주면 infinite list가 된다고 합니다. (_scrollController.position.maxScrollExtent를 찍어보면 Infinity가 나옴)
itemBuilder 안에서 index를 출력해보면 계속 index값이 올라가는 것을 확인할 수 있습니다.
이 index값이 계속 증가하는 것을 이용하여 list를 계속 반복해주면 됩니다.
==>
사실 이렇게 해도 문제가 없는 지 잘모르겠는데
구글링, marquee 패키지들을 보면 이렇게 ListView.builder에 itemCount를 안넘겨주시게 구현하셨더라구요,, 😳
## 2.
scroll 메소드에서는 10만큼 오른쪽으로 스크롤 시켜주는 코드를 작성해주었습니다.
그리고 이동할 때 걸리는 시간으로는 주입받은 moveDuration을 넣어줬습니다.
그리고 이동을 기다려주는 delay 코드를 넣어줬습니다.
+ ScrollEndNotification을 이용해서 scroll이 끝나면 다음 이동을 시켜주게 바꿔도 좋을 것 같아요! (참고)
Future<bool> _scroll() async {
double _moveDistance = 10.0;
_position += _moveDistance;
_scrollController.animateTo(_position, duration: widget.moveDuration, curve: Curves.linear);
await Future.delayed(widget.moveDuration);
return true;
}
'🤼♀️ > Flutter' 카테고리의 다른 글
[Flutter] 버전 제약 조건 (Version constraints) (0) | 2021.09.11 |
---|---|
[Flutter] pub.dev에 flutter package를 publish 하기 (2) | 2021.04.27 |
[Flutter] Marquee Widget 만들기 (1) - alternate (1) | 2021.04.23 |
[Flutter] 기기 정보, 앱 정보 구하기 (Device Info, App Info) (3) | 2021.03.02 |
[Flutter] 이메일 보내기 (문의하기) (1) | 2021.03.02 |
- Total
- Today
- Yesterday
- Dart Factory
- Sketch 누끼
- flutter 앱 출시
- Flutter Clipboard
- Flutter 로딩
- cocoapod
- 구글 Geocoding API
- drf custom error
- METAL
- 플러터 얼럿
- Python Type Hint
- DRF APIException
- Flutter Text Gradient
- SerializerMethodField
- ribs
- flutter dynamic link
- Flutter getter setter
- 플러터 싱글톤
- Django Heroku Scheduler
- github actions
- 장고 Custom Management Command
- Django Firebase Cloud Messaging
- flutter deep link
- Flutter Spacer
- Watch App for iOS App vs Watch App
- flutter build mode
- Django FCM
- 장고 URL querystring
- PencilKit
- ipad multitasking
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |