import 'package:flutter/material.dart'; import 'app_actions.dart' show isCompact; /// 환경 설정의 한 줄 (ListTile 과 같은 쓰임새). /// 좁은 화면 (접은 폴드 · 휴대폰 세로) 에서는 오른쪽의 넓은 조절 (고르기 상자 · 입력 칸 · 버튼) 을 설명 아래로 내려 /// 제목 · 설명이 한두 글자 폭으로 눌리지 않게 한다. 스위치 · 체크 상자 · 아이콘 버튼은 그대로 오른쪽에. class SettingTile extends StatelessWidget { final Widget? leading; final Widget? title; final Widget? subtitle; final Widget? trailing; final bool isThreeLine; final bool enabled; final bool? dense; final VoidCallback? onTap; final EdgeInsetsGeometry? contentPadding; const SettingTile({ super.key, this.leading, this.title, this.subtitle, this.trailing, this.isThreeLine = false, this.enabled = true, this.dense, this.onTap, this.contentPadding, }); static bool _small(Widget w) => w is Switch || w is Checkbox || w is Icon || w is IconButton || w is Radio; @override Widget build(BuildContext context) { final tile = _tile(context); // 241: 오른쪽 스위치 · 고르기 상자가 제목을 이름으로 읽히게 (TalkBack 이 이름 없는 "켜짐" 만 읽었다). // 줄 자체를 누르는 타일 ([onTap]) 은 누르는 곳이 둘이 되므로 합치지 않는다 return trailing != null && onTap == null ? MergeSemantics(child: tile) : tile; } Widget _tile(BuildContext context) { final t = trailing; // 253: 글자를 크게 (1.2배 넘게) 하면 넓은 화면에서도 고르기 상자를 설명 아래로 (오른쪽에 두면 넘쳤다) final large = MediaQuery.textScalerOf(context).scale(10) > 12; if (t == null || _small(t) || (!isCompact(context) && !large)) { return ListTile( leading: leading, title: title, subtitle: subtitle, trailing: t, isThreeLine: isThreeLine, enabled: enabled, dense: dense, onTap: onTap, contentPadding: contentPadding, ); } return ListTile( leading: leading, title: title, subtitle: Column(crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: [ ?subtitle, const SizedBox(height: 6), // 253: 그래도 화면보다 넓으면 (긴 항목 · 큰 글자) 줄여서 다 보이게 Align(alignment: Alignment.centerLeft, child: FittedBox(fit: BoxFit.scaleDown, alignment: Alignment.centerLeft, child: t)), ]), enabled: enabled, dense: dense, onTap: onTap, contentPadding: contentPadding, ); } }