Flutter聊天界面底部容器插件chat_bottom_container的使用
Flutter聊天界面底部容器插件 chat_bottom_container
的使用
chat_bottom_container
是一个用于管理聊天页面底部容器的 Flutter 插件,可以实现键盘与其他面板之间的平滑切换。以下是如何使用该插件的详细说明和示例代码。
安装
在 pubspec.yaml
文件中添加 chat_bottom_container
依赖:
dependencies:
chat_bottom_container: latest_version
导入 chat_bottom_container
包:
import 'package:chat_bottom_container/chat_bottom_container.dart';
对于 Android 项目,需要在项目的根 build.gradle
文件中添加 jitpack
仓库:
allprojects {
repositories {
...
maven { url 'https://jitpack.io' }
}
}
使用方法
页面布局
整体页面布局如下:
@override
Widget build(BuildContext context) {
return Scaffold(
// 需要设置为 false
resizeToAvoidBottomInset: false,
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Expanded(
child: ListView.builder(
// 这里是你的消息列表构建逻辑
),
),
// 输入框视图
_buildInputView(),
// 底部容器
_buildPanelContainer(),
],
),
);
}
底部容器
定义自定义面板类型:
enum PanelType {
none,
keyboard,
emoji,
tool,
}
final controller = ChatBottomPanelContainerController<PanelType>();
final FocusNode inputFocusNode = FocusNode();
PanelType currentPanelType = PanelType.none;
Widget _buildPanelContainer() {
return ChatBottomPanelContainer<PanelType>(
controller: controller,
inputFocusNode: inputFocusNode,
otherPanelWidget: (type) {
// 返回自定义面板视图
if (type == null) return const SizedBox.shrink();
switch (type) {
case PanelType.emoji:
return _buildEmojiPickerPanel();
case PanelType.tool:
return _buildToolPanel();
default:
return const SizedBox.shrink();
}
},
onPanelTypeChange: (panelType, data) {
// 记录当前面板类型
switch (panelType) {
case ChatBottomPanelType.none:
currentPanelType = PanelType.none;
break;
case ChatBottomPanelType.keyboard:
currentPanelType = PanelType.keyboard;
break;
case ChatBottomPanelType.other:
if (data == null) return;
switch (data) {
case PanelType.emoji:
currentPanelType = PanelType.emoji;
break;
case PanelType.tool:
currentPanelType = PanelType.tool;
break;
default:
currentPanelType = PanelType.none;
break;
}
break;
}
},
panelBgColor: panelBgColor,
);
}
切换底部面板类型
controller.updatePanelType(
// 设置当前底部面板类型
// 可以传递 ChatBottomPanelType.keyboard | ChatBottomPanelType.other | ChatBottomPanelType.none
ChatBottomPanelType.other,
// 回调开发者自定义的 PanelType 值,必须在 ChatBottomPanelType.other 时传递
data: PanelType.emoji, // PanelType.tool
);
隐藏面板
hidePanel() {
inputFocusNode.unfocus();
if (ChatBottomPanelType.none == controller.currentPanelType) return;
controller.updatePanelType(ChatBottomPanelType.none);
}
自定义底部安全区域高度
默认情况下,chat_bottom_container
会自动添加底部安全区域高度,但在某些场景下你可能不希望这样,可以通过设置 safeAreaBottom
为 0
来自定义此高度:
return ChatBottomPanelContainer<PanelType>(
...
safeAreaBottom: 0,
...
);
调整键盘面板高度
例如,在主页的聊天页面上,外层底部固定的 BottomNavigationBar
的高度需要减去:
return ChatBottomPanelContainer<PanelType>(
...
changeKeyboardPanelHeight: (keyboardHeight) {
final renderObj = bottomNavigationBarKey.currentContext?.findRenderObject();
if (renderObj is! RenderBox) return keyboardHeight;
return keyboardHeight - renderObj.size.height;
},
...
);
示例 Demo
以下是一个完整的示例 demo:
import 'package:chat_bottom_container/chat_bottom_container.dart';
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
class App {
static final routeObserver = RouteObserver<ModalRoute>();
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
navigatorObservers: [
App.routeObserver,
],
home: const HomePage(),
);
}
}
class HomePage extends StatefulWidget {
const HomePage({super.key});
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage>
with SingleTickerProviderStateMixin {
late TabController _tabController;
final bottomNavigationBarKey = GlobalKey();
ChatBottomPanelContainerController? controller;
@override
void initState() {
super.initState();
_tabController = TabController(
length: 3,
vsync: this,
);
}
@override
void dispose() {
_tabController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomInset: false,
appBar: AppBar(
title: const Text('Chat Bottom Container Example'),
),
bottomNavigationBar: _buildBottomNavBar(),
body: _buildBody(),
);
}
Widget _buildBody() {
Widget resultWidget = TabBarView(
controller: _tabController,
children: [
ChatPage(
safeAreaBottom: 0,
showAppBar: false,
changeKeyboardPanelHeight: (keyboardHeight) {
final renderObj =
bottomNavigationBarKey.currentContext?.findRenderObject();
if (renderObj is! RenderBox) return keyboardHeight;
return keyboardHeight - renderObj.size.height;
},
onControllerCreated: (controller) {
this.controller = controller;
},
),
Container(color: Colors.red),
Container(color: Colors.blue),
],
);
resultWidget = Stack(
children: [
resultWidget,
Positioned(right: 10, child: _buildFloatingView()),
],
);
return resultWidget;
}
Widget _buildBottomNavBar() {
return BottomNavigationBar(
key: bottomNavigationBarKey,
items: const [
BottomNavigationBarItem(
icon: Icon(Icons.chat),
label: 'Chat',
),
BottomNavigationBarItem(
icon: Icon(Icons.people),
label: 'People',
),
BottomNavigationBarItem(
icon: Icon(Icons.settings),
label: 'Settings',
),
],
);
}
Widget _buildFloatingView() {
Widget resultWidget = Column(
children: [
_buildFloatingBtn(
icon: Icons.chevron_right_sharp,
onPressed: () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) {
return const ChatPage();
},
),
);
},
),
const SizedBox(height: 10),
_buildFloatingBtn(
icon: Icons.keyboard_arrow_up_sharp,
onPressed: () {
showModalBottomSheet(
context: context,
isScrollControlled: true,
builder: (context) {
return const FractionallySizedBox(
heightFactor: 0.8,
child: ChatPage(),
);
},
);
},
),
],
);
return resultWidget;
}
Widget _buildFloatingBtn({
required void Function()? onPressed,
IconData? icon,
}) {
return ElevatedButton(
onPressed: onPressed,
style: ElevatedButton.styleFrom(
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 16),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
),
shadowColor: Colors.grey[50],
elevation: 2,
),
child: Icon(icon),
);
}
}
通过以上步骤和示例代码,您可以轻松地在 Flutter 应用中集成并使用 chat_bottom_container
插件来实现聊天界面的底部容器管理功能。
更多关于Flutter聊天界面底部容器插件chat_bottom_container的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter聊天界面底部容器插件chat_bottom_container的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,我可以为你提供一个关于如何使用 chat_bottom_container
插件来创建一个 Flutter 聊天界面底部容器的示例代码。这个插件通常用于在聊天应用中实现一个包含输入框和发送按钮的底部容器。
首先,你需要在你的 pubspec.yaml
文件中添加 chat_bottom_container
依赖:
dependencies:
flutter:
sdk: flutter
chat_bottom_container: ^最新版本号 # 请替换为最新的版本号
然后运行 flutter pub get
来获取依赖。
以下是一个简单的示例代码,展示了如何使用 chat_bottom_container
插件:
import 'package:flutter/material.dart';
import 'package:chat_bottom_container/chat_bottom_container.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: ChatScreen(),
);
}
}
class ChatScreen extends StatefulWidget {
@override
_ChatScreenState createState() => _ChatScreenState();
}
class _ChatScreenState extends State<ChatScreen> {
final TextEditingController _textController = TextEditingController();
void _sendMessage() {
String message = _textController.text;
if (message.isNotEmpty) {
// 在这里处理发送消息的逻辑,例如将消息添加到聊天列表中
print("Sending message: $message");
_textController.clear();
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Chat Screen'),
),
body: Padding(
padding: const EdgeInsets.symmetric(horizontal: 8.0, vertical: 16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
// 聊天消息列表(这里只是一个示例,你可以使用ListView.builder来动态加载消息)
Expanded(
child: Container(
child: Column(
children: <Widget>[
Text('Message 1 from User A'),
Text('Message 2 from User B'),
// ...更多消息
],
),
),
),
// 聊天底部容器
ChatBottomContainer(
child: Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(16),
),
child: Row(
children: <Widget>[
Expanded(
child: TextField(
controller: _textController,
decoration: InputDecoration(
border: InputBorder.none,
hintText: 'Type a message...',
),
),
),
IconButton(
icon: Icon(Icons.send),
color: Colors.blue,
onPressed: _sendMessage,
),
],
),
),
),
],
),
),
);
}
}
在这个示例中,我们创建了一个简单的聊天界面,其中包含一个 ChatBottomContainer
组件。这个组件内包含一个 TextField
用于输入消息和一个 IconButton
用于发送消息。当用户点击发送按钮时,会调用 _sendMessage
方法,该方法会打印消息内容并清空输入框。
请注意,这个示例只是一个简单的演示,实际的聊天应用可能需要处理更多的逻辑,例如将消息保存到数据库、显示消息时间戳、加载更多消息等。你可以根据需求进一步扩展这个示例。