1. 규칙
접힌 시트에서 날짜+건수를 눌러 최대 높이(0.9)까지 올렸는데도 아래에 안 보이는 항목이 더 있으면, 목록 바로 아래에 아래 화살표를 붙인다. 더 있다는 표시다. 화살표를 눌러 스크롤하지는 않는다.
| 상태 | 화살표 |
|---|---|
| 시트 높이가 최대(0.9, 여유 0.02)이고, 목록을 8px보다 더 내릴 수 있다 | 보인다 |
| 최대가 아니다(기본 0.6, 내용에 맞춘 중간 높이, 접힘) | 안 보인다 |
| 최대인데 항목이 화면에 다 들어간다 | 안 보인다 |
| 최대에서 맨 아래까지 스크롤했다 | 사라진다 |
판정:
최대인가 = sheetSize >= 0.9 - 0.02
아래에 남음 = maxScrollExtent - scrollOffset > 8
화살표 = 최대인가 그리고 아래에 남음
2. 먼저 들어가 있어야 하는 것
아이폰 day_plan_appl_app 에는 2026-09-23에 반영됨.
안드로이드에 아래 두 문서가 이미 들어가 있어야 이 화살표를 붙일 수 있다.
20260923_1050_바텀시트_안드로이드웹이식.html— 목록 스크롤(_listCtl)과 시트 높이가 분리되어 있다. 날짜칸은 내용 높이에 맞추고, 기본 0.6 미만으로 내리지 않으며, 최대 0.9에서도 잘릴 때만 0.9다.20260923_1213_날짜건수_올라온시트접기.html— 날짜+건수는 올라가 있으면 접고, 접혀 있으면 0.9로 올린다.
화살표는 그 0.9 상태에서만 나온다.
목록 컨트롤러 이름이 _listCtl, 시트 컨트롤러가 _sheetCtl인 1050 구조를 기준으로 한다.
3. 넣을 코드
파일: 안드로이드 lib/screens/calendar_tab.dart. 핫 리로드 대신 앱을 완전히 다시 실행한다.
3.1 톱레벨 함수
calendarSheetSizeOnCountTap 바로 아래에 둔다. 클래스 밖이어야 테스트에서 부를 수 있다.
/// 최대 높이인데 목록 아래에 아직 안 보이는 항목이 있으면 아래 화살표를 보인다.
bool calendarSheetShowsMoreBelow({
required double sheetSize,
required double scrollOffset,
required double maxScrollExtent,
}) {
final atMax = sheetSize >= kCalendarSheetMax - 0.02;
if (!atMax) return false;
return maxScrollExtent - scrollOffset > 8;
}
3.2 파일 맨 끝 위젯
CalendarTab 클래스가 끝난 다음, 파일 끝에 붙인다. 시트와 같은 배경 #F7F9FC라 글자와 한 덩어리로 보이지 않고, 목록 밖에 있다.
/// 최대 높이 시트의 맨 아래. 스크롤하면 더 보이는 항목이 있을 때만 화살표.
class _SheetMoreHint extends StatefulWidget {
const _SheetMoreHint({
required this.sheet,
required this.list,
});
final DraggableScrollableController sheet;
final ScrollController list;
@override
State<_SheetMoreHint> createState() => _SheetMoreHintState();
}
class _SheetMoreHintState extends State<_SheetMoreHint> {
@override
void initState() {
super.initState();
widget.sheet.addListener(_onChange);
widget.list.addListener(_onChange);
WidgetsBinding.instance.addPostFrameCallback((_) => _onChange());
}
@override
void didUpdateWidget(covariant _SheetMoreHint oldWidget) {
super.didUpdateWidget(oldWidget);
if (oldWidget.sheet != widget.sheet) {
oldWidget.sheet.removeListener(_onChange);
widget.sheet.addListener(_onChange);
}
if (oldWidget.list != widget.list) {
oldWidget.list.removeListener(_onChange);
widget.list.addListener(_onChange);
}
}
@override
void dispose() {
widget.sheet.removeListener(_onChange);
widget.list.removeListener(_onChange);
super.dispose();
}
void _onChange() {
if (mounted) setState(() {});
}
bool get _visible {
if (!widget.sheet.isAttached || !widget.list.hasClients) return false;
final pos = widget.list.position;
if (!pos.hasContentDimensions) return false;
return calendarSheetShowsMoreBelow(
sheetSize: widget.sheet.size,
scrollOffset: pos.pixels,
maxScrollExtent: pos.maxScrollExtent,
);
}
@override
Widget build(BuildContext context) {
if (!_visible) return const SizedBox.shrink();
return const ColoredBox(
color: Color(0xFFF7F9FC),
child: SizedBox(
width: double.infinity,
child: Padding(
padding: EdgeInsets.only(bottom: 4),
child: Icon(
Icons.keyboard_arrow_down,
size: 22,
color: Color(0xFF3F6FB0),
),
),
),
);
}
}
4. 시트 안에 넣는 자리
Stack 위에 Positioned로 올리지 않는다.
Column 안에서 목록 Expanded의 다음 자식으로 둔다.
안 보일 때는 높이가 0이라 목록이 그 자리를 쓴다.
보일 때는 목록이 한 줄 줄고, 화살표는 그 아래 빈 줄에만 있다.
목록 아래 여백은 28이 아니라 8로 줄인다. 화살표 줄이 아래 여백을 대신한다.
Expanded(
child: ListView(
controller: _listCtl,
primary: false,
padding: const EdgeInsets.fromLTRB(16, 4, 16, 8),
children: [
// 기존 목록: 공휴일, 구글, 일정, 기록, 할일. 건드리지 않는다.
],
),
),
_SheetMoreHint(sheet: _sheetCtl, list: _listCtl),
Column의 자식 순서는 핸들, 날짜+건수, Expanded(목록), 화살표다.
닫기(X)와 1px 시트 컨트롤러는 Stack의 Positioned로 그대로 둔다.
5. 테스트
test/calendar_sheet_test.dart에 추가한다. 패키지 이름은 안드로이드 앱의 이름을 쓴다.
test('최대 높이인데 아래가 남으면 화살표, 맨 아래면 숨김', () {
expect(
calendarSheetShowsMoreBelow(
sheetSize: 0.9,
scrollOffset: 0,
maxScrollExtent: 200,
),
isTrue,
);
expect(
calendarSheetShowsMoreBelow(
sheetSize: 0.6,
scrollOffset: 0,
maxScrollExtent: 200,
),
isFalse,
);
expect(
calendarSheetShowsMoreBelow(
sheetSize: 0.9,
scrollOffset: 200,
maxScrollExtent: 200,
),
isFalse,
);
});
실행: flutter test test/calendar_sheet_test.dart
6. 확인
- 항목이 많아 최대 높이로도 아래가 남는 날에서, 접힌 시트의 날짜+건수를 누른다. 시트가 0.9까지 올라가고, 목록 맨 아래 글자 밑에 아래 화살표가 있다. 글자 위에 겹치지 않는다.
- 목록을 맨 아래까지 내리면 화살표가 사라진다. 다시 올리면 나타난다.
- 항목이 최대 높이에 다 들어가면 화살표가 없다.
- 날짜칸만 눌러 0.6이나 중간 높이로 열린 상태에서는 화살표가 없다.