写一个自己的MyGPT app

news2025/1/16 21:15:12

chatGPT大火之后,国内外一众玩家撸起袖子热火朝天干了起来。

借助开源的GPT可以轻松的拥有自己的专属GPT,装装逼还是很好用的,也算赶一下chatGPT的风口。

这里使用ANYGPT,打造自已的GPT,AnyGPT API 开发者文档 · 语雀

AnyGPT服务器代码开源,他们也提供自己的API开放给大家使用,有服务器的朋友可以自己布署使用,没服务器的可以使用他们的API,需要更高级服务的可以买他们的会员。

有了个GPT开,做一个APP界面就可以了。这里使用

implementation 'me.himanshusoni.chatmessageview:chat-message-view:1.0.2'

来创建微信聊天窗口,自己写可以呀,有框架用着很快速。简单的布局,一个list用于显示消息,一个按钮录音,提供声音聊天,一个输入框用于输入聊天内容,一个发送按钮发送:

<RelativeLayout
                android:id="@+id/widget_layout_meihua"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:orientation="vertical">

                <androidx.recyclerview.widget.RecyclerView
                    android:id="@+id/recyclerView"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:layout_above="@+id/send_message_layout"
                    android:layout_marginStart="10dp"
                    android:layout_marginLeft="10dp"
                    android:layout_marginTop="10dp"
                    android:layout_marginEnd="10dp"
                    android:layout_marginRight="10dp"
                    android:layout_marginBottom="10dp"
                    android:clipToPadding="false"
                    android:divider="@null"
                    android:paddingTop="8dp" />

                <LinearLayout
                    android:id="@+id/send_message_layout"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_alignParentBottom="true"
                    android:background="#ffdddddd"
                    android:gravity="center_vertical"
                    android:orientation="horizontal">

                    <ImageView
                        android:id="@+id/iv_image"
                        android:layout_width="40dp"
                        android:layout_height="40dp"
                        android:alpha=".5"
                        android:background="?selectableItemBackground"
                        android:contentDescription="@string/app_name"
                        android:padding="2dp"
                        android:src="@android:drawable/presence_audio_online" />

                    <EditText
                        android:id="@+id/et_message"
                        android:layout_width="0dp"
                        android:layout_height="wrap_content"
                        android:layout_weight="1"
                        android:inputType="text" />

                    <Button
                        android:id="@+id/btn_send"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:background="@android:drawable/editbox_background_normal"
                        android:text="发送" />
                </LinearLayout>

            </RelativeLayout>

布局显示大概如下,GPT有时会发脾气,飙外语,不知道哪国语言,显示不出来,哈哈:

 

两个重要的类用来显示消息,一个是消息结构,一个是adapter:

public class ChatMessageAdapter extends RecyclerView.Adapter<ChatMessageAdapter.MessageHolder> {
    private final String TAG = "ChatMessageAdapter";
    private static final int MY_MESSAGE = 0, OTHER_MESSAGE = 1;

    private List<ChatMessage> mMessages;
    private Context mContext;

    public interface OnClickListener {
        void onClick(int position, String message);
    }

    public interface OnLongClickListener {
        void onLongClick(int position, String message);
    }

    private OnClickListener clickListener;
    private OnLongClickListener longClickListener;


    public ChatMessageAdapter(Context context, List<ChatMessage> data) {
        mContext = context;
        mMessages = data;
    }
    public ChatMessageAdapter(Context context, List<ChatMessage> data, OnClickListener onClickListener, OnLongClickListener onLongClickListener) {
        mContext = context;
        mMessages = data;
        clickListener = onClickListener;
        longClickListener = onLongClickListener;
    }

    @Override
    public int getItemCount() {
        return mMessages == null ? 0 : mMessages.size();
    }

    @Override
    public int getItemViewType(int position) {
        ChatMessage item = mMessages.get(position);

        if (item.isMine()) return MY_MESSAGE;
        else return OTHER_MESSAGE;
    }

    @Override
    public MessageHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        if (viewType == MY_MESSAGE) {
            return new MessageHolder(LayoutInflater.from(mContext).inflate(R.layout.item_mine_message, parent, false));
        } else {
            return new MessageHolder(LayoutInflater.from(mContext).inflate(R.layout.item_other_message, parent, false));
        }
    }

    public void add(ChatMessage message) {
        mMessages.add(message);
        notifyItemInserted(mMessages.size() - 1);
    }

    @Override
    public void onBindViewHolder(final MessageHolder holder, final int position) {
        ChatMessage chatMessage = mMessages.get(position);
        if (chatMessage.isImage()) {
            holder.ivImage.setVisibility(View.VISIBLE);
            holder.tvMessage.setVisibility(View.GONE);

            holder.ivImage.setImageResource(R.drawable.ic_launcher_background);
        } else {
            holder.ivImage.setVisibility(View.GONE);
            holder.tvMessage.setVisibility(View.VISIBLE);

            holder.tvMessage.setText(chatMessage.getContent());
        }

        String date = new SimpleDateFormat("hh:mm aa", Locale.getDefault()).format(new Date());
        holder.tvTime.setText("[单击复制]"+date);

        int index = position;
        if (clickListener != null){
            holder.chatMessageView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    clickListener.onClick(index, chatMessage.getContent());

                }
            });
        }

        if (longClickListener != null){
            holder.chatMessageView.setOnLongClickListener(new View.OnLongClickListener() {

                @Override
                public boolean onLongClick(View view) {
                    longClickListener.onLongClick(index, chatMessage.getContent());
                    return false;
                }
            });
        }
    }

    class MessageHolder extends RecyclerView.ViewHolder {
        TextView tvMessage, tvTime;
        ImageView ivImage;
        ChatMessageView chatMessageView;

        MessageHolder(View itemView) {
            super(itemView);
            chatMessageView = (ChatMessageView) itemView.findViewById(R.id.chatMessageView);
            tvMessage = (TextView) itemView.findViewById(R.id.tv_message);
            tvTime = (TextView) itemView.findViewById(R.id.tv_time);
            ivImage = (ImageView) itemView.findViewById(R.id.iv_image);
        }
    }
}
public class ChatMessage {
    private boolean isImage, isMine;
    private String content;

    public ChatMessage(String message, boolean mine, boolean image) {
        content = message;
        isMine = mine;
        isImage = image;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    public boolean isMine() {
        return isMine;
    }

    public void setIsMine(boolean isMine) {
        this.isMine = isMine;
    }

    public boolean isImage() {
        return isImage;
    }

    public void setIsImage(boolean isImage) {
        this.isImage = isImage;
    }
}

主要代码完了,使用神器retrofit接上api就上愉快的装逼了

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/557180.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【STM32】基础知识 第十六课 窗口看门狗 WWDG 深入浅出

【STM32】基础知识 第十六课 窗口看门狗 WWDG 深入浅出 概述窗口看门狗 (WWDG)WWDG_SR 状态寄存器WWDG 配置与使用使用 WWDG 进行故障检测案例 概述 在嵌入式开发中, 可靠性和稳定性是至关重要的. 这就是为什么许多单片机, 比如 STM32, 提供了窗口看门狗 (Window Watchdog, WW…

redis 源码记录

正好最近时间富裕&#xff0c;看一看redis源码&#xff0c;简单的记录一下。也有可能说的是不全面的&#xff0c;自行斟酌&#xff0c;只能通过debug来简单的梳理本次测试流程&#xff0c;而不是全量的覆盖的所有测试用例&#xff0c;时不时更新&#xff0c;争取一天学一点点。…

基于Web的水果蔬菜销售系统的设计与实现(论文+源码)_kaic

摘 要 随着互联网经济与技术进程的不断推进&#xff0c;网上购物方式受到公众的普遍关注和欢迎。传统的樱桃线下销售模式缺陷不断暴露&#xff0c;难以满足公众不断加快的生活节奏和生活方式的需求。本文根据目前大众的实际需要&#xff0c;根据网上商城的特点、现状以及主要功…

Java 与排序算法(3):插入排序

一、插入排序 插入排序&#xff08;Insertion Sort&#xff09;是一种简单直观的排序算法&#xff0c;它的基本思想是将待排序序列分为已排序区间和未排序区间&#xff0c;然后每次从未排序区间取出一个元素&#xff0c;将其插入到已排序区间的合适位置中&#xff0c;使得插入…

【SpringBoot】八:Web服务---WebMvcConfigurer

文章目录 1.WebMvcConfigurer简介2. 页面跳转控制器3. 数据格式化4. 拦截器4.1 一个拦截器4.2 多个拦截器 1.WebMvcConfigurer简介 WebMvcConfigurer是SpringMVC xml配置文件的JavaConfig实现方式。 2. 页面跳转控制器 创建 SpringMVC 配置类: 3. 数据格式化 Formatter&…

计算机组成原理-存储系统-主存储器(芯片)和CPU连接

目录 一、SRAM和DRAM芯片 DRAM&#xff1a;栅极电容存储信息 SRAM&#xff1a;双稳态触发器存储信息 区别​编辑 二、ROM芯片 三、主存于CPU的连接 位扩展法 字扩展法 字位同时扩展法 译码器 四、双端口RAM和多模块存储器 4.1双端口RAM 4.2多模块存储器 4.2.1单体多字…

pthread多线程: 创建最简单的线程

文章目录 1. 目的1.1 不使用 Pthread 的情况1.2 使用 Pthread 的情况1.3 使用 Pthread 的好处 2. Pthread 创建线程的 API2.1 环境2.2 pthread_create()2.3pthread_join() 3. 创建最简单的线程3.1 要点3.2 代码 4. 创建多个子线程4.1 要点4.2 代码 5. 总结 1. 目的 Pthread 提…

计算机组成原理-存储系统-基本概论及组成

目录 一、存储器的层次化结构 二、存储器分类 存储介质 存取方式 信息可改性 三、性能指标 四、主存储器基本组成 基本的的半导体元件及原理 存储芯片的基本原理 一、存储器的层次化结构 二、存储器分类 存储介质 半导体存储器(主存&#xff0c;cache)、磁表面存储器(…

基于SpringBoot的SSMP的整合案例

基于SpringBoot的SSMP的整合案例 简单介绍模块创建创建实体类导入Mybatis-plus和druid的配置文件使用junit测试查询方法MP分页查询按照条件进行查询业务层Service开发业务层Service快速开发表现层开发表现层 实现分页查询表现层消息一致性的处理查询所有书本信息添加书本删除操…

TensorFlow巨浪中的巨人:大数据领域的引领者 TensorFlow实战【上进小菜猪大数据系列】

上进小菜猪&#xff0c;沈工大软件工程专业&#xff0c;爱好敲代码&#xff0c;持续输出干货。欢迎订阅本专栏&#xff01; 大数据时代的到来带来了海量数据的处理和分析需求。在这个背景下&#xff0c;TensorFlow作为一种强大的深度学习框架&#xff0c;展现了其在大数据领域…

fastreport使用教程(fastreport报表编辑器)

除了库本身&#xff0c;FastReport.Net还包括单独的程序 – Designer和Viewer。 如您所知&#xff0c;第一个用于创建和编辑报表模板。它具有报表预览模式&#xff0c;您可以从中查看报表&#xff0c;将其导出为所需的数据格式并将其发送到打印。 Viewer用于以fpx预览格式查看报…

清华p-tuning | GPT也能做NLU?清华推出p-tuning方法解决GPT系列模型fine-tuning效果比BERT差问题

一、概述 title&#xff1a;GPT Understands, Too 论文地址&#xff1a;https://arxiv.org/abs/2103.10385 代码&#xff1a;https://github.com/THUDM/P-tuning 1.1 Motivation GPTs模型利用传统的fine-tuning技术在NLU任务上效果比较差&#xff0c;比同等量级的BERT效果…

2023/5/22总结

继承 继承是面向对象三大特征之一。可以使得子类具有父类的属性和方法&#xff0c;还可以在子类中重新定义&#xff0c;追加属性和方法。 如图&#xff1a; 在上面的图片中&#xff0c;dog和cat都继承了Animal类&#xff0c;所以dog和cat都可以称为Animal的子类或者派生类&…

chatgpt赋能Python-python_dng

Python DNG&#xff1a;开启更高效的数据处理之路 什么是Python DNG&#xff1f; Python DNG&#xff08;Data NumPy Generator&#xff09;是一种基于Python的高效数据生成器&#xff0c;可以加速数据处理和分析的过程。它基于Numpy数组操作和并行计算思想&#xff0c;可以快…

C++详解NOI题:[NOIP2021] 报数

文章目录 前言一、题目二、暴力解题步骤&#xff08;50分&#xff09;三、打表防坑解题&#xff08;100分&#xff09;总结 前言 受不了CSDN每日一练的在线竞赛系统了&#xff0c;bug多就算了&#xff0c;勉强能用&#xff0c;可那些题目的神描述&#xff0c;到处是错。所以找…

前端面试知识点总结

前言&#xff1a; 博主突击两个月八股拿到美团&#xff08;基础研发&#xff09;&#xff0c;腾讯&#xff08;IEG&#xff09;&#xff0c;百度&#xff08;搜索部门&#xff09;暑期实习offer call&#xff0c;这是我学习过程中整理的前端知识点&#xff0c;内容有些多&#…

【13900k】i9 核显升级驱动

这里写自定义目录标题 官方的助手不能用显卡控制中心提示最新的更新搜索显卡 intel uhd graphics 770 手动下载安装自定义音频为啥也要卸载&#xff1f;新的改变功能快捷键合理的创建标题&#xff0c;有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片…

网络编程——嵌入式(驱动)软开基础(六)

1、简述TCP三次握手的过程。 (1)第一次握手:客户端创建传输控制块,然后向服务器发出连接请求报文(将标志位SYN置1,随机产生一个序列号seq=x),接着进入SYN-SENT状态。 (2)第二次握手:服务器收到请求报文后由SYN=1得到客户端请求建立连接,回复一个确认报文(将标志…

进程启动后到加载Activity的流程源码解析(基于安卓版本28)

文章目录 源码解析总体时序图关键类解析ActivityThreadApplicationThreadInstrumentationClientTransactionActivityStackSupervisorActivityRecord梳理概述源码流程梳理 源码解析 总体时序图 关键类解析 只针对流程中用到的关键类进行解析。 ActivityThread 注意其父类是&…

ES6升级之路:探究模板字符串、startsWith()方法和endsWith()方法、repeat()等新特性。

模版字符串 ES6新增的创建字符串的方式,使用反引号定义 示例 <script>// 1.模板字符串可以解析变量 ${}显示变量的值let name 张三;let sayHello HEllo,我的名字叫${name};console.log(name);console.log(sayHello);let result {name: "zhangsan",age: 20…