Flutter聊天界面UI插件code_chat_ui的使用

Flutter聊天界面UI插件code_chat_ui的使用

Features

  • 支持任何聊天API
  • 可自定义聊天气泡
  • 可自定义发送按钮和输入框
  • 支持头部请求
  • 支持加载指示器
  • 支持失败处理

Getting Started

在你的Flutter项目的pubspec.yaml文件中添加以下依赖:

dependencies:
  code_chat_ui: ^0.1.0

在你的库中添加以下导入:

import 'package:code_chat_ui/code_chat_ui.dart';

Usage

CodeChatUI<String>(
  url: 'https://your-chat-api-url.com',
  requestBuilder: (String input) => {'text': input},
  onResponseSuccess: (dynamic response, String input) => print(response['text']),
  onFailure: (dynamic error, dynamic response, String input) => print('Error: $error'),
  chatsValueListenable: ValueNotifier<List<String>>([]),
  chatBuilder: (BuildContext context, String chat) => ChatBubble(text: chat),
)

API

CodeChatUI

一个用于构建聊天界面的Widget,可以消费任何聊天API。

Properties

名称 类型 描述
url String 聊天API端点的URL。
requestBuilder Map<String, dynamic> Function(String input) 从用户输入构建请求主体的函数。
onResponseSuccess T Function(dynamic response, String input) 提取API响应中的聊天消息的函数。
onFailure void Function(dynamic error, dynamic response, String input)? 处理API错误的函数。
chatsValueListenable ValueNotifier<List<T>> 持有聊天消息列表的值监听器。
chatBuilder Widget Function(BuildContext context, T chat) 构建聊天气泡Widget的函数。
headerRequest Map<String, String>? 包含在API请求中的头部映射。
appBar PreferredSizeWidget? 构建AppBar的Widget。
sendButtonBuilder Widget Function(BuildContext context, void Function() onSend)? 构建发送按钮Widget的函数。
textFormFieldBuilder Widget Function(BuildContext context, TextEditingController controller, FocusNode focusNode, void Function() onFieldSubmitted)? 构建文本表单字段Widget的函数。

Example CodeChatUi

import 'package:flutter/material.dart';

import 'package:code_chat_ui/code_chat_ui.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'OpenAI Chat Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'OpenAI Chat Demo'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key, required this.title}) : super(key: key);

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  final _chats = <String>[];
  final _chatsValueNotifier = ValueNotifier<List<String>>([]);

  Map<String, dynamic> _requestBuilder(String input) => {
        "model": "gpt-3.5-turbo",
        "messages": [
          {
            "role": "user",
            "content": input,
          }
        ],
      };

  final _headerRequest = {
    'Content-Type': 'application/json',
    'Authorization': 'Bearer YOUR_OPENAI_API_KEY_HERE',
  };

  final _url = 'https://api.openai.com/v1/chat/completions';

  void _onResponseSuccess(dynamic response, String input) {
    final completions = response['choices'][0]['message']['content'];
    print(response);
    print(completions);
    setState(() {
      _chats.add(input);
      _chats.add(completions);
      _chatsValueNotifier.value = _chats;
    });
  }

  void _onFailure(dynamic error, dynamic response, String input) {
    print(error);
    print(response);
    setState(() {
      _chats.add('Error: $error');
      _chatsValueNotifier.value = _chats;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: CodeChatUI<String>(
        url: _url,
        requestBuilder: _requestBuilder,
        onResponseSuccess: _onResponseSuccess,
        headerRequest: _headerRequest,
        onFailure: _onFailure,
        chatsValueListenable: _chatsValueNotifier,
        chatBuilder: (context, chat) => ChatBubble(
          text: chat,
          isUser: _chats.indexOf(chat) % 2 == 0,
        ),
      ),
    );
  }
}

class ChatBubble extends StatelessWidget {
  final String text;
  final bool isUser;

  const ChatBubble({Key? key, required this.text, required this.isUser}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Container(
      margin: const EdgeInsets.symmetric(vertical: 10),
      alignment: isUser ? Alignment.centerRight : Alignment.centerLeft,
      child: Container(
        padding: const EdgeInsets.symmetric(horizontal: 15, vertical: 10),
        decoration: BoxDecoration(
          color: isUser ? Colors.blue : Colors.grey[300],
          borderRadius: BorderRadius.only(
            bottomLeft: const Radius.circular(20),
            bottomRight: const Radius.circular(20),
            topLeft: isUser ? const Radius.circular(20) : const Radius.circular(0),
            topRight: isUser ? const Radius.circular(0) : const Radius.circular(20),
          )
        ),
        child: Text(
          text,
          style: TextStyle(
            color: isUser ? Colors.white : Colors.black,
          ),
        ),
      ),
    );
  }
}

Example CodeChatOpenai (code.id implementation)

CodeChatOpenai(
  url: getIt<Endpoints>().urlChatOpenai,
  appBar: AppBar(
    backgroundColor: Colors.white,
    leading: IconButton(
      icon: const Icon(
        Icons.arrow_back,
        color: Colors.black,
      ),
      onPressed: () {
        Get.back();
      },
    ),
    title: Row(
      children: [
        Image.asset(
          'assets/sgb_header.png',
          fit: BoxFit.fitWidth,
          height: 30,
          width: 30,
        ),
        const SizedBox(
          width: 10,
        ),
        Expanded(
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Text("SGB",
                  style: heeboBold.copyWith(
                    fontSize: 16.sp,
                    color: mainColor,
                  )),
              Text(
                "Online",
                style: heeboRegular.copyWith(
                  fontSize: 16.sp,
                  color: Colors.green,
                ),
              ),
            ],
          ),
        ),
      ],
    ),
  ),
  onFailure: (error, response, input) {
    debugPrint(error.toString());
    debugPrint(response.toString());
    debugPrint(input);
  },
  onResponseSuccess: (response, input) {
    debugPrint(response.toString());
    debugPrint(input);
  },
  sendButtonBuilder: (context, onSend) => FloatingActionButton(
    onPressed: onSend,
    backgroundColor: mainColor,
    child: SvgPicture.asset('assets/icon_send.svg'),
  ),
  botIcon: Image.asset(
    'assets/sgb_header.png',
    fit: BoxFit.fitWidth,
    height: 30,
    width: 30,
  ),
),

更多关于Flutter聊天界面UI插件code_chat_ui的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter聊天界面UI插件code_chat_ui的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,下面是一个关于如何使用 code_chat_ui 插件来创建一个简单的 Flutter 聊天界面的示例代码。这个示例假定你已经有一个 Flutter 开发环境,并且已经添加了 code_chat_ui 依赖到你的 pubspec.yaml 文件中。

首先,确保你的 pubspec.yaml 文件中包含以下依赖:

dependencies:
  flutter:
    sdk: flutter
  code_chat_ui: ^最新版本号  # 请替换为实际的最新版本号

然后,运行 flutter pub get 来获取依赖。

接下来,创建一个简单的 Flutter 应用,并在其中使用 code_chat_ui 插件来构建聊天界面。以下是一个完整的示例代码:

import 'package:flutter/material.dart';
import 'package:code_chat_ui/code_chat_ui.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Chat App',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: ChatScreen(),
    );
  }
}

class ChatScreen extends StatefulWidget {
  @override
  _ChatScreenState createState() => _ChatScreenState();
}

class _ChatScreenState extends State<ChatScreen> {
  final List<ChatMessage> messages = [
    ChatMessage(
      id: '1',
      sender: 'User A',
      text: 'Hello, how are you?',
      timestamp: DateTime.now().subtract(Duration(minutes: 5)),
      isMe: true,
    ),
    ChatMessage(
      id: '2',
      sender: 'User B',
      text: 'I am good, thanks. How about you?',
      timestamp: DateTime.now().subtract(Duration(minutes: 3)),
      isMe: false,
    ),
    // 可以添加更多消息
  ];

  final TextEditingController _textController = TextEditingController();

  void _sendMessage() {
    if (_textController.text.isNotEmpty) {
      setState(() {
        messages.add(ChatMessage(
          id: '${messages.length + 1}',
          sender: 'User A', // 假设当前用户是 User A
          text: _textController.text,
          timestamp: DateTime.now(),
          isMe: true,
        ));
        _textController.clear();
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Chat'),
      ),
      body: Column(
        children: [
          Expanded(
            child: ChatList(
              messages: messages,
            ),
          ),
          Container(
            decoration: BoxDecoration(
              color: Colors.white,
              border: Border(
                top: BorderSide(color: Colors.grey[200]!, width: 0.5),
              ),
            ),
            padding: EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0),
            child: Row(
              crossAxisAlignment: CrossAxisAlignment.center,
              children: [
                Expanded(
                  child: TextField(
                    controller: _textController,
                    decoration: InputDecoration(
                      border: InputBorder.none,
                      hintText: 'Type a message...',
                    ),
                  ),
                ),
                IconButton(
                  icon: Icon(Icons.send),
                  onPressed: _sendMessage,
                ),
              ],
            ),
          ),
        ],
      ),
    );
  }
}

class ChatMessage {
  final String id;
  final String sender;
  final String text;
  final DateTime timestamp;
  final bool isMe;

  ChatMessage({
    required this.id,
    required this.sender,
    required this.text,
    required this.timestamp,
    required this.isMe,
  });
}

在这个示例中,我们定义了一个简单的 ChatMessage 类来表示聊天消息,并在 ChatScreen 中创建了一个包含消息列表和输入框的聊天界面。ChatList 组件(假设这是 code_chat_ui 插件提供的一个组件,但具体名称可能有所不同,请参考插件的文档)用于显示消息列表。

请注意,由于 code_chat_ui 插件的具体 API 和组件名称可能有所不同,因此上述代码中的 ChatList 组件可能需要根据实际的插件文档进行调整。如果插件提供了不同的组件或方法来显示消息列表,请按照插件的文档进行相应的修改。

此外,为了完整性,你可能还需要添加一些错误处理和样式调整,以确保应用在不同设备和屏幕尺寸上都能正常工作。

回到顶部