MOTIVATION
한 화면에서 사용자에게 제공하는 정보가 2가지인데(월 정보와 일 정보), 일 정보만 바로 볼 수 있도록 특정 위젯의 위치로 스크롤시키고 싶음
접근 방법1. 내가 이동하기 원하는 특정 위젯의 위치(OffSet)을 알아낸 뒤 ScrollController의 animateTo를 이용
접근방법2. scrollable_positioned_list 패키지 사용
둘 다 해본 결과, 패키지 사용이 더 자연스럽다.
IMPLEMENT 접근방법1
1. 특정 위젯의 위치를 알아내기
class _MyHomePageState extends State<MyHomePage> {
ScrollController pageScrollController = ScrollController();
Size? _getSize() {
if (_containerKey.currentContext != null) {
final RenderBox renderBox =
_containerKey.currentContext!.findRenderObject() as RenderBox;
Size size = renderBox.size;
return size;
}
Offset? _getOffset() {
if (_containerKey.currentContext != null) {
final RenderBox renderBox =
_containerKey.currentContext!.findRenderObject() as RenderBox;
Offset offset = renderBox.localToGlobal(Offset.zero);
return offset;
}
}
final GlobalKey _containerKey = GlobalKey();
Size? size;
Offset? offset;
@override
void initState() {
super.initState();
// 위젯의 크기나 위치는 위젯이 렌더링된 후 알 수 있음. 위젯이 바인딩 된 후에 호출하는 함수로 해당 함수 내에서 위젯의 크기 및 위치를 받는 함수를 호출
WidgetsBinding.instance!.addPostFrameCallback((_) {
setState(() {
size = _getSize();
offset = _getOffset();
});
});
}
// 그다음 위치를 알고싶은 위젯에서
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
key: _containerKey, //키를 지정
child: const Text("텍스트."),
),
),
],
),
);
}
}
2. 사용자의 행동에 따라 scrollController 활용
onTap: () {
pageScrollController.animateTo(pageScrollController.position.minScrollExtent,
duration: Duration(milliseconds: 700), curve: Curves.ease);
},
IMPLEMENT 접근방법2
scrollable_positioned_list 패키지 사용
1. 사용할 위젯들을 담은 리스트 준비
final ItemScrollController itemScrollController = ItemScrollController();
final ItemPositionsListener itemPositionsListener = ItemPositionsListener.create();
@override
Widget build(BuildContext context) {
List<Widget> widgetList = [
_buildTableCalendar(),
showCalendarButtonWidget(),
separateLineWidget(),
_buildFarmWorkWidgets(),
const SizedBox(height: 20)
];
return Scaffold(
appBar: farmingDiaryAppBar(),
body: ScrollablePositionedList.builder(
itemCount: widgetList.length,
itemBuilder: (context, index) => widgetList[index],
itemScrollController: itemScrollController,
itemPositionsListener: itemPositionsListener,
),
);
}
2. 특정 위젯을 눌렀을때 원하는 인덱스의 위젯으로 스크롤
bool _isScrolled = false;
InkWell(
// 한 번 누르면 원하는 위치로, 한 번 더 누르면 최상위 위치로
onTap: () {
if (_showCalendar) {
if (!_isScrolled) {
itemScrollController.scrollTo(index: 3, duration: Duration(seconds: 1), curve: Curves.easeInOutCubic);
}
if (_isScrolled) {
itemScrollController.scrollTo(
index: 0, duration: const Duration(milliseconds: 700), curve: Curves.easeInOutCubic);
}
setState(() {
_isScrolled = !_isScrolled;
});
}
},
child: Text(
'텍스트',
style: TextStyle(
color: Color(0xff111111),
fontFamily: 'NotoSansCJKKR',
fontWeight: FontWeight.w700,
),
),
),
참고
https://petabyte.studio/posts/flutter-get-size-of-widget/
[Flutter] 위젯의 크기 / 위치 값을 가져오는 법
Before Start.
petabyte.studio
https://pub.dev/packages/scrollable_positioned_list/versions/0.2.3/example
scrollable_positioned_list 0.2.3 | Flutter Package
A list with helper methods to programmatically scroll to an item.
pub.dev
728x90
'Flutter' 카테고리의 다른 글
[Flutter] ListView의 이미지 확대, gallery 기능 / image enlarge and swipe (0) | 2023.02.08 |
---|---|
[Flutter] setstate not working on get.bottomSheet (0) | 2023.02.07 |
[Flutter] Setting the height of the AppBar (0) | 2023.02.01 |
[Flutter] How to go back and request API to refresh the previous page : 이전페이지 이동 후 API 호출 (0) | 2023.01.31 |
[Flutter] Connecting flutter simulator to localhost api (0) | 2023.01.27 |