디자인 1차 초안 완성
This commit is contained in:
Binary file not shown.
|
Before Width: | Height: | Size: 958 KiB After Width: | Height: | Size: 548 KiB |
BIN
assets/images/chat_img.png
Normal file
BIN
assets/images/chat_img.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 88 KiB |
BIN
assets/images/layer_img.png
Normal file
BIN
assets/images/layer_img.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 174 KiB |
BIN
assets/images/layer_img1.png
Normal file
BIN
assets/images/layer_img1.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 98 KiB |
BIN
assets/images/layer_img2.png
Normal file
BIN
assets/images/layer_img2.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.2 MiB |
274
lib/main.dart
274
lib/main.dart
@@ -137,7 +137,9 @@ class _SmartGardenScreenState extends State<SmartGardenScreen> {
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
backgroundColor: Colors.transparent,
|
||||
body: Container(
|
||||
body: Stack(
|
||||
children: [
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
image: DecorationImage(
|
||||
image: AssetImage('assets/images/background1.png'),
|
||||
@@ -146,10 +148,10 @@ class _SmartGardenScreenState extends State<SmartGardenScreen> {
|
||||
),
|
||||
child: Center(
|
||||
child: Container(
|
||||
margin: const EdgeInsets.all(40),
|
||||
margin: const EdgeInsets.all(40), // 메인 컨테이너 여백 조정
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
color: Colors.white.withOpacity(0.8), // 투명도 넣기
|
||||
borderRadius: BorderRadius.circular(16), // 모서리 둥글게
|
||||
border: Border.all(color: Color(0xFFE0E0E0), width: 1),
|
||||
),
|
||||
child: Row(
|
||||
@@ -162,7 +164,10 @@ class _SmartGardenScreenState extends State<SmartGardenScreen> {
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
border: Border.all(color: Color(0xFFE0E0E0), width: 1),
|
||||
border: Border.all(
|
||||
color: Color(0xFFE0E0E0),
|
||||
width: 1,
|
||||
),
|
||||
),
|
||||
child: Column(
|
||||
children: [
|
||||
@@ -187,7 +192,8 @@ class _SmartGardenScreenState extends State<SmartGardenScreen> {
|
||||
),
|
||||
const SizedBox(width: 16),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.start,
|
||||
children: [
|
||||
const Text(
|
||||
'Smart Garden',
|
||||
@@ -212,7 +218,9 @@ class _SmartGardenScreenState extends State<SmartGardenScreen> {
|
||||
// 캐릭터 영역
|
||||
Expanded(
|
||||
child: Container(
|
||||
margin: const EdgeInsets.symmetric(horizontal: 20),
|
||||
margin: const EdgeInsets.symmetric(
|
||||
horizontal: 20,
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
color: Color(0xFFF5F5F5),
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
@@ -221,22 +229,23 @@ class _SmartGardenScreenState extends State<SmartGardenScreen> {
|
||||
? ClipRRect(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
child: AspectRatio(
|
||||
aspectRatio:
|
||||
_videoController.value.aspectRatio,
|
||||
aspectRatio: _videoController
|
||||
.value
|
||||
.aspectRatio,
|
||||
child: VideoPlayer(_videoController),
|
||||
),
|
||||
)
|
||||
: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.center,
|
||||
children: [
|
||||
Container(
|
||||
width: 180,
|
||||
height: 180,
|
||||
decoration: BoxDecoration(
|
||||
color: Color(0xFFF1F8E9),
|
||||
borderRadius: BorderRadius.circular(
|
||||
12,
|
||||
),
|
||||
borderRadius:
|
||||
BorderRadius.circular(12),
|
||||
border: Border.all(
|
||||
color: Color(0xFFC8E6C9),
|
||||
width: 1,
|
||||
@@ -286,10 +295,14 @@ class _SmartGardenScreenState extends State<SmartGardenScreen> {
|
||||
decoration: BoxDecoration(
|
||||
color: Color(0xFFC8E6C9),
|
||||
// ← 연한 초록 배경 추가
|
||||
borderRadius: BorderRadius.circular(24),
|
||||
borderRadius: BorderRadius.circular(
|
||||
24,
|
||||
),
|
||||
),
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.circular(24),
|
||||
borderRadius: BorderRadius.circular(
|
||||
24,
|
||||
),
|
||||
child: Image.asset(
|
||||
'assets/images/profile.png',
|
||||
fit: BoxFit.cover,
|
||||
@@ -357,42 +370,58 @@ class _SmartGardenScreenState extends State<SmartGardenScreen> {
|
||||
decoration: BoxDecoration(
|
||||
color: Color(0xFFFAFAFA),
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
border: Border.all(color: Color(0xFFE0E0E0), width: 1),
|
||||
),
|
||||
child: Column(
|
||||
children: [
|
||||
// 헤더 (왼쪽정렬)
|
||||
Container(
|
||||
padding: const EdgeInsets.all(20),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: const BorderRadius.only(
|
||||
topLeft: Radius.circular(16),
|
||||
topRight: Radius.circular(16),
|
||||
),
|
||||
border: Border(
|
||||
bottom: BorderSide(
|
||||
border: Border.all(
|
||||
color: Color(0xFFE0E0E0),
|
||||
width: 1,
|
||||
),
|
||||
),
|
||||
child: Column(
|
||||
children: [
|
||||
// 헤더
|
||||
Container(
|
||||
padding: const EdgeInsets.all(20),
|
||||
decoration: BoxDecoration(),
|
||||
child: Row(
|
||||
children: [
|
||||
const Icon(
|
||||
Icons.eco,
|
||||
color: Color(0xFF81C784),
|
||||
size: 24,
|
||||
),
|
||||
child: const Text(
|
||||
'푸미와 대화하기',
|
||||
const SizedBox(width: 12),
|
||||
const Text(
|
||||
'푸미 일지',
|
||||
style: TextStyle(
|
||||
fontSize: 22,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF212121),
|
||||
),
|
||||
textAlign: TextAlign.left, // ← 왼쪽정렬
|
||||
textAlign: TextAlign.left,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
// 채팅 메시지 영역
|
||||
Expanded(
|
||||
child: Container(
|
||||
margin: const EdgeInsets.symmetric(horizontal: 16),
|
||||
margin: const EdgeInsets.symmetric(
|
||||
horizontal: 16,
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
image: DecorationImage(
|
||||
image: AssetImage(
|
||||
'assets/images/chat_img.png',
|
||||
),
|
||||
// ← 배경 이미지 추가
|
||||
fit: BoxFit.cover,
|
||||
colorFilter: ColorFilter.mode(
|
||||
Colors.white.withOpacity(0.9),
|
||||
// 채팅 배경 이미지 투명도 조정
|
||||
BlendMode.lighten,
|
||||
),
|
||||
),
|
||||
color: Colors.white.withOpacity(0.5),
|
||||
// 채팅창 투명도
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
border: Border.all(
|
||||
color: Color(0xFFE0E0E0),
|
||||
@@ -410,19 +439,26 @@ class _SmartGardenScreenState extends State<SmartGardenScreen> {
|
||||
),
|
||||
),
|
||||
),
|
||||
// 자주하는 질문 버튼들 (채팅 아래, 입력창 위)
|
||||
Padding(
|
||||
padding: const EdgeInsets.fromLTRB(16, 8, 16, 8),
|
||||
// 자주하는 질문 버튼들을 감싸는 컨테이너
|
||||
Container(
|
||||
margin: const EdgeInsets.fromLTRB(16, 12, 16, 12),
|
||||
padding: const EdgeInsets.all(12),
|
||||
decoration: BoxDecoration(
|
||||
color: Color(0xFFC8E6C9).withOpacity(0.3), // 배경
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
// 온도 정보
|
||||
Expanded(
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Color(0xFFBBDEFB),
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
color: Colors.white, // ← 흰색
|
||||
borderRadius: BorderRadius.circular(25),
|
||||
border: Border.all(
|
||||
color: Color(0xFF1976D2).withOpacity(0.2),
|
||||
color: Color(
|
||||
0xFF1976D2,
|
||||
).withOpacity(0.2),
|
||||
width: 0.5,
|
||||
),
|
||||
),
|
||||
@@ -431,7 +467,9 @@ class _SmartGardenScreenState extends State<SmartGardenScreen> {
|
||||
child: InkWell(
|
||||
onTap: () =>
|
||||
_sendQuickQuestion('현재 온도는?'),
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
borderRadius: BorderRadius.circular(
|
||||
25,
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 12,
|
||||
@@ -441,9 +479,22 @@ class _SmartGardenScreenState extends State<SmartGardenScreen> {
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.center,
|
||||
children: [
|
||||
const Text(
|
||||
'🌡️',
|
||||
style: TextStyle(fontSize: 20),
|
||||
Container(
|
||||
width: 32,
|
||||
height: 32,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius:
|
||||
BorderRadius.circular(
|
||||
6,
|
||||
),
|
||||
),
|
||||
child: const Center(
|
||||
child: Icon(
|
||||
Icons.thermostat,
|
||||
color: Color(0xFF4CAF50),
|
||||
size: 25,
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
Text(
|
||||
@@ -451,7 +502,7 @@ class _SmartGardenScreenState extends State<SmartGardenScreen> {
|
||||
style: TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF1976D2),
|
||||
color: Color(0xFF000000),
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -466,10 +517,12 @@ class _SmartGardenScreenState extends State<SmartGardenScreen> {
|
||||
Expanded(
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Color(0xFFC8E6C9),
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
color: Colors.white, // ← 흰색
|
||||
borderRadius: BorderRadius.circular(25),
|
||||
border: Border.all(
|
||||
color: Color(0xFF388E3C).withOpacity(0.2),
|
||||
color: Color(
|
||||
0xFF388E3C,
|
||||
).withOpacity(0.2),
|
||||
width: 0.5,
|
||||
),
|
||||
),
|
||||
@@ -478,7 +531,9 @@ class _SmartGardenScreenState extends State<SmartGardenScreen> {
|
||||
child: InkWell(
|
||||
onTap: () =>
|
||||
_sendQuickQuestion('현재 습도는?'),
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
borderRadius: BorderRadius.circular(
|
||||
25,
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 12,
|
||||
@@ -488,9 +543,22 @@ class _SmartGardenScreenState extends State<SmartGardenScreen> {
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.center,
|
||||
children: [
|
||||
const Text(
|
||||
'💧',
|
||||
style: TextStyle(fontSize: 20),
|
||||
Container(
|
||||
width: 32,
|
||||
height: 32,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius:
|
||||
BorderRadius.circular(
|
||||
6,
|
||||
),
|
||||
),
|
||||
child: const Center(
|
||||
child: Icon(
|
||||
Icons.water_drop,
|
||||
color: Color(0xFF4CAF50),
|
||||
size: 25,
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
Text(
|
||||
@@ -498,7 +566,7 @@ class _SmartGardenScreenState extends State<SmartGardenScreen> {
|
||||
style: TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF388E3C),
|
||||
color: Color(0xFF000000),
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -513,18 +581,23 @@ class _SmartGardenScreenState extends State<SmartGardenScreen> {
|
||||
Expanded(
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Color(0xFFFFE0B2),
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
color: Colors.white, // ← 흰색
|
||||
borderRadius: BorderRadius.circular(25),
|
||||
border: Border.all(
|
||||
color: Color(0xFFFFA000).withOpacity(0.2),
|
||||
color: Color(
|
||||
0xFFFFA000,
|
||||
).withOpacity(0.2),
|
||||
width: 0.5,
|
||||
),
|
||||
),
|
||||
child: Material(
|
||||
color: Colors.transparent,
|
||||
child: InkWell(
|
||||
onTap: () => _sendQuickQuestion('물을 주세요'),
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
onTap: () =>
|
||||
_sendQuickQuestion('물을 주세요'),
|
||||
borderRadius: BorderRadius.circular(
|
||||
25,
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 12,
|
||||
@@ -534,9 +607,22 @@ class _SmartGardenScreenState extends State<SmartGardenScreen> {
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.center,
|
||||
children: [
|
||||
const Text(
|
||||
'💦',
|
||||
style: TextStyle(fontSize: 20),
|
||||
Container(
|
||||
width: 32,
|
||||
height: 32,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius:
|
||||
BorderRadius.circular(
|
||||
6,
|
||||
),
|
||||
),
|
||||
child: const Center(
|
||||
child: Icon(
|
||||
Icons.waves,
|
||||
color: Color(0xFF4CAF50),
|
||||
size: 25,
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
Text(
|
||||
@@ -544,7 +630,7 @@ class _SmartGardenScreenState extends State<SmartGardenScreen> {
|
||||
style: TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFFFFA000),
|
||||
color: Color(0xFF000000),
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -610,7 +696,9 @@ class _SmartGardenScreenState extends State<SmartGardenScreen> {
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: Color(0xFF81C784),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
borderRadius: BorderRadius.circular(
|
||||
8,
|
||||
),
|
||||
),
|
||||
padding: EdgeInsets.zero,
|
||||
),
|
||||
@@ -636,6 +724,17 @@ class _SmartGardenScreenState extends State<SmartGardenScreen> {
|
||||
),
|
||||
),
|
||||
),
|
||||
// Layer 이미지 (화면 전체, 클릭 불가)
|
||||
IgnorePointer(
|
||||
child: Image.asset(
|
||||
'assets/images/layer_img1.png',
|
||||
fit: BoxFit.cover,
|
||||
width: double.infinity,
|
||||
height: double.infinity,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -645,10 +744,19 @@ class _ChatBubble extends StatelessWidget {
|
||||
|
||||
const _ChatBubble({required this.message});
|
||||
|
||||
String _formatTime(DateTime dateTime) {
|
||||
final hour = dateTime.hour;
|
||||
final minute = dateTime.minute;
|
||||
final period = hour >= 12 ? '오후' : '오전';
|
||||
final displayHour = hour > 12 ? hour - 12 : (hour == 0 ? 12 : hour);
|
||||
|
||||
return '$period ${displayHour.toString().padLeft(2, '0')}:${minute.toString().padLeft(2, '0')}';
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(bottom: 12),
|
||||
padding: const EdgeInsets.only(bottom: 30), // 채팅창 사이 간격 여백 주기
|
||||
child: Row(
|
||||
mainAxisAlignment: message.isUser
|
||||
? MainAxisAlignment.end
|
||||
@@ -672,17 +780,31 @@ class _ChatBubble extends StatelessWidget {
|
||||
),
|
||||
const SizedBox(width: 10),
|
||||
],
|
||||
Flexible(
|
||||
child: Row(
|
||||
mainAxisAlignment: message.isUser
|
||||
? MainAxisAlignment.end
|
||||
: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: [
|
||||
if (message.isUser)
|
||||
Text(
|
||||
_formatTime(message.timestamp),
|
||||
style: TextStyle(fontSize: 12, color: Color(0xFF9E9E9E)),
|
||||
),
|
||||
if (message.isUser) const SizedBox(width: 8),
|
||||
Flexible(
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 10),
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 16,
|
||||
vertical: 10,
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
color: message.isUser
|
||||
? Color(0xFFE8F5E9) // ← 연한 녹색
|
||||
: Colors.white, // ← 하얀색
|
||||
color: message.isUser ? Color(0xFFE8F5E9) : Colors.white,
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.black.withOpacity(0.1), // ← 연한 그림자
|
||||
color: Colors.black.withOpacity(0.1),
|
||||
blurRadius: 4,
|
||||
offset: const Offset(0, 2),
|
||||
),
|
||||
@@ -693,14 +815,22 @@ class _ChatBubble extends StatelessWidget {
|
||||
style: TextStyle(
|
||||
fontSize: 20,
|
||||
color: message.isUser
|
||||
? Color(0xFF000000) // ← 진한 초록 텍스트
|
||||
? Color(0xFF000000)
|
||||
: Color(0xFF424242),
|
||||
height: 1.4,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
if (message.isUser) const SizedBox(width: 8),
|
||||
if (!message.isUser) const SizedBox(width: 8),
|
||||
if (!message.isUser)
|
||||
Text(
|
||||
_formatTime(message.timestamp),
|
||||
style: TextStyle(fontSize: 12, color: Color(0xFF9E9E9E)),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
||||
@@ -82,6 +82,12 @@ flutter:
|
||||
- assets/images/background2.png
|
||||
- assets/images/background3.png
|
||||
|
||||
- assets/images/layer_img.png
|
||||
- assets/images/layer_img1.png
|
||||
- assets/images/layer_img2.png
|
||||
|
||||
- assets/images/chat_img.png
|
||||
|
||||
# To add assets to your application, add an assets section, like this:
|
||||
# assets:
|
||||
# - images/a_dot_burr.jpeg
|
||||
|
||||
Reference in New Issue
Block a user