
import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:tiktok_clone/constants/sizes.dart';
import 'package:tiktok_clone/features/inbox/chat_detail_screen.dart';
class ChatsScreen extends StatefulWidget {
const ChatsScreen({super.key});
State<ChatsScreen> createState() => _ChatsScreenState();
}
class _ChatsScreenState extends State<ChatsScreen> {
final GlobalKey<AnimatedListState> _key = GlobalKey<AnimatedListState>();
final List<int> _items = [];
final Duration _duration = const Duration(milliseconds: 300);
void _addItem() {
if (_key.currentState != null) {
_key.currentState!.insertItem(
_items.length,
duration: _duration,
);
_items.add(_items.length);
}
}
void _deleteItem(int index) {
if (_key.currentState != null) {
_key.currentState!.removeItem(
index,
(context, animation) => SizeTransition(
sizeFactor: animation,
child: Container(
color: Colors.red,
child: _makeTile(index),
),
),
duration: _duration,
);
_items.removeAt(index);
}
}
void _onChatTap() {
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => const ChatDetailScreen(),
),
);
}
Widget _makeTile(int index) {
return ListTile(
onLongPress: () => _deleteItem(index),
onTap: _onChatTap,
leading: const CircleAvatar(
radius: 30,
foregroundImage: NetworkImage(
"https://avatars.githubusercontent.com/u/3612017",
),
child: Text('니꼬'),
),
title: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Text(
"Lynn ($index)",
style: const TextStyle(fontWeight: FontWeight.w600),
),
Text(
"2:16 PM",
style: TextStyle(
color: Colors.grey.shade500,
fontSize: Sizes.size12,
),
),
],
),
subtitle: const Text("Don't forget to make video"),
);
}
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
elevation: 1,
title: const Text('Direct messages'),
actions: [
IconButton(
onPressed: _addItem,
icon: const FaIcon(FontAwesomeIcons.plus),
),
],
),
body: AnimatedList(
key: _key,
padding: const EdgeInsets.symmetric(vertical: Sizes.size10),
itemBuilder: (context, index, animation) {
return FadeTransition(
key: Key('$index'),
opacity: animation,
child: SizeTransition(
sizeFactor: animation,
child: _makeTile(index),
),
);
},
),
);
}
}
GlobalKey<AnimatedListState>는 AnimatedList 위젯의 상태를 직접적으로 제어하는 데 필수적입니다. 만약 _key 변수가 없다면, AnimatedList의 항목을 프로그래밍 방식으로 추가하거나 제거하는 것이 어려워집니다.
항목 추가 및 제거 불가: AnimatedList에서 항목을 추가하거나 제거하려면 해당 리스트의 상태에 접근할 필요가 있습니다. GlobalKey를 사용하면 이 상태에 직접 접근하여 insertItem 및 removeItem과 같은 메서드를 호출할 수 있습니다. GlobalKey가 없으면 이러한 직접적인 제어가 불가능합니다.
애니메이션 복잡성: AnimatedList의 주요 장점 중 하나는 항목 추가 및 제거 시 자연스러운 애니메이션을 제공하는 것입니다. GlobalKey를 사용하지 않으면 이러한 애니메이션을 구현하는 것이 더 복잡하거나 불가능할 수 있습니다.
상태 관리 어려움: GlobalKey 없이 AnimatedList의 상태를 관리하려면 다른 방법을 찾아야 합니다. 예를 들어, 부모 위젯에서 상태를 관리하고 전체 리스트를 다시 빌드하는 방식을 사용할 수 있지만, 이는 성능에 영향을 줄 수 있고, 애니메이션 효과를 잃을 수 있습니다.
GlobalKey<AnimatedListState>는 AnimatedList 위젯의 항목을 동적으로 제어하고, 부드러운 애니메이션 효과를 유지하는 데 중요합니다. 이 키 없이 AnimatedList를 사용하는 것은 가능하지만, 상태 관리와 애니메이션 구현이 더 복잡해질 수 있습니다. 따라서, AnimatedList를 사용할 때는 GlobalKey를 사용하는 것이 일반적으로 권장됩니다.
AnimatedList 위젯에서 key가 필수(required)가 아닌 이유는 모든 Flutter 위젯에서 key가 필수적으로 요구되지 않기 때문입니다. key는 특정 위젯의 인스턴스를 고유하게 식별하기 위해 사용되는 선택적 매개변수입니다. 대부분의 위젯에서 key는 필요하지 않으며, 특정 상황에서만 사용됩니다.
key가 필요한 상황:위젯 식별: 여러 개의 같은 타입의 위젯이 있을 때, 각각을 구별하기 위해 key를 사용합니다. 이는 특히 동적인 목록이나 컬렉션에서 위젯의 상태를 올바르게 관리하는 데 중요합니다.
상태 유지: 위젯 트리에서 위젯의 위치가 변경될 때, 상태를 유지하려면 key가 필요할 수 있습니다. key는 Flutter 프레임워크에게 같은 위젯이 새 위치로 이동했음을 알려주어, 해당 상태를 유지하게 합니다.
성능 최적화: 특정 상황에서 key를 사용하면 위젯 트리의 재구성을 최적화하고 성능을 향상시킬 수 있습니다.
AnimatedList와 key:AnimatedList에서 key는 주로 위젯의 상태를 관리하기 위해 사용됩니다. 예를 들어, 목록 항목을 동적으로 추가하거나 제거할 때 GlobalKey<AnimatedListState>를 사용하여 AnimatedList의 상태에 직접 접근할 수 있습니다.AnimatedList 사용 사례에서 이런 방식의 상태 관리가 필요한 것은 아닙니다. 때문에 key는 required가 아니며, 상황에 따라 선택적으로 사용됩니다.key는 Flutter에서 위젯을 보다 정밀하게 제어하고 관리하기 위한 선택적 도구입니다. AnimatedList와 같은 일부 위젯에서 key는 특정 기능을 구현하기 위해 필요할 수 있지만, 모든 경우에 필수적인 것은 아닙니다. 개발자는 앱의 요구사항과 위젯의 사용 방법에 따라 key의 사용 여부를 결정해야 합니다.
_key 변수가 없이도 프로그램이 돌아가나요?
_key 변수가 없으면 AnimatedList 위젯이 제대로 작동하지 않습니다. AnimatedList 위젯은 GlobalKey를 사용하여 애니메이션을 제어하기 때문입니다. 따라서 _key 변수가 없으면 애니메이션이 제대로 적용되지 않고, 아이템 추가 및 삭제 시 예기치 않은 동작이 발생할 수 있습니다.
GlobalKey가 없다면 어떤 상황이 생겨요?
GlobalKey가 없으면 AnimatedList 위젯이 애니메이션을 제어할 수 없습니다. 따라서 애니메이션이 제대로 적용되지 않고, 아이템 추가 및 삭제 시 예기치 않은 동작이 발생할 수 있습니다.
구체적으로, 다음과 같은 상황이 발생할 수 있습니다.
따라서 AnimatedList 위젯을 사용할 때는 반드시 GlobalKey를 사용해야 합니다.
AnimatedList 위젯의 key가 required가 아닌 이유는 다음과 같습니다.
AnimatedList 위젯은 GlobalKey를 사용하여 애니메이션을 제어하지만, GlobalKey는 선택 사항입니다.GlobalKey를 사용하지 않으면 AnimatedList 위젯은 애니메이션을 제어할 수 없지만, 기본적으로 아이템 추가 및 삭제는 정상적으로 작동합니다.AnimatedList 위젯을 사용하는 개발자는 필요에 따라 GlobalKey를 사용할 수 있습니다.다만, AnimatedList 위젯을 사용할 때는 GlobalKey를 사용하는 것이 좋습니다. GlobalKey를 사용하면 애니메이션이 제대로 적용되고, 아이템 추가 및 삭제 시 예기치 않은 동작이 발생할 가능성을 줄일 수 있습니다.
따라서 일반적으로 AnimatedList 위젯을 사용할 때는 key 속성에 GlobalKey를 지정하는 것이 좋습니다.