当前位置: 首页 > news >正文

APP聊天项目介绍

项目结构说明

res/layout目录:存放布局相关的 XML 文件,用于定义界面的外观,包含activity_main.xml(主界面布局)和message_item.xml(聊天消息项布局)。

res/drawable目录:存放一些自定义的图形资源相关的 XML 文件以及图片资源(如果有),用于界面样式设置,如背景、按钮样式等,包含edittext_rounded_bg.xmlbutton_send_bg.xmlleft_message_bg.xmlright_message_bg.xml等文件(代码中只是简单示意,这部分并没有整理很清楚,接下来打算可根据实际需求替换和完善图片资源等)。

java(对应项目包名的目录下):存放业务逻辑代码等,包含如MainActivity.java(主 Activity 类,处理界面交互、消息发送接收展示等核心逻辑)、ChatAdapter.java(聊天消息列表适配器类,用于将消息数据绑定到RecyclerView的每一项上展示)、Message.java(消息实体类,表示一条聊天消息)、DBHelper.java(数据库帮助类,用于管理 SQLite 数据库的创建、操作等)。

代码展示

布局文件代码

activity_main.xml(存放在res/layout目录下)

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:background="#EFEFF4"tools:context=".MainActivity"><!-- 聊天消息列表RecyclerView --><androidx.recyclerview.widget.RecyclerViewandroid:id="@+id/recyclerView_chat"android:layout_width="match_parent"android:layout_height="match_parent"android:layout_above="@+id/layout_chat_input"android:clipToPadding="false"android:padding="8dp"android:scrollbars="vertical" /><!-- 输入框及发送按钮所在的底部布局 --><LinearLayoutandroid:id="@+id/layout_chat_input"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_alignParentBottom="true"android:background="@android:color/white"android:orientation="horizontal"android:padding="8dp"><!-- 表情按钮(这里先简单占位,可后续添加点击事件及表情选择功能等) --><ImageButtonandroid:id="@+id/button_emoji"android:layout_width="wrap_content"android:layout_height="wrap_content"android:src="@drawable/ic_emoji"android:contentDescription="表情" /><!-- 输入文本的EditText,设置了一些样式属性 --><EditTextandroid:id="@+id/editText_message"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:background="@drawable/edittext_rounded_bg"android:hint="输入消息"android:padding="8dp"android:textColor="#000"android:textColorHint="#999" /><!-- 发送按钮 --><Buttonandroid:id="@+id/button_send"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="发送"android:textColor="@android:color/white"android:background="@drawable/button_send_bg" /></LinearLayout></RelativeLayout>

message_item.xml(存放在res/layout目录下)

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"android:padding="4dp"><!-- 显示发送者头像(这里先简单用一个ImageView占位,实际可根据用户信息加载对应的头像资源) --><ImageViewandroid:id="@+id/imageView_sender_avatar"android:layout_width="40dp"android:layout_height="40dp"android:src="@drawable/default_avatar"android:scaleType="centerCrop" /><!-- 用于包裹消息内容的布局,根据消息是自己发送还是别人发送设置不同的对齐方式 --><LinearLayoutandroid:id="@+id/layout_message_content"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:orientation="vertical"android:padding="8dp"><!-- 显示发送者昵称(实际中可根据用户信息动态设置) --><TextViewandroid:id="@+id/textView_sender_name"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="发送者昵称"android:textColor="#000"android:textSize="14sp" /><!-- 根据消息类型展示不同内容,这里先以文本消息为例,用TextView展示 --><TextViewandroid:id="@+id/textView_message_content"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="消息内容"android:textColor="#333"android:textSize="16sp"android:layout_marginTop="4dp" /></LinearLayout></LinearLayout>

res/drawable目录下样式资源相关 XML 文件代码

edittext_rounded_bg.xml(存放在res/drawable目录下)

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"android:shape="rectangle"><solid android:color="@android:color/white" /><corners android:radius="16dp" /></shape>

button_send_bg.xml(存放在res/drawable目录下)

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android"><item android:state_pressed="true"><shape android:shape="rectangle"><solid android:color="#007AFF" /><corners android:radius="16dp" /></shape></item><item><shape android:shape="rectangle"><solid android:color="#0085FF" /><corners android:radius="16dp" /></shape></item></selector>

left_message_bg.xml(存放在res/drawable目录下)

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"android:shape="rectangle"><solid android:color="#DCF8C6" /><corners android:topLeftRadius="16dp"android:bottomLeftRadius="16dp"android:bottomRightRadius="16dp" /></shape>

right_message_bg.xml(存放在res/drawable目录下,样式与left_message_bg.xml类似,可做区分,这里简单示意)

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"android:shape="rectangle"><solid android:color="#87CEEB" /><corners android:topRightRadius="16dp"android:bottomLeftRadius="16dp"android:bottomRightRadius="16dp" /></shape>

业务逻辑代码

import java.util.Date;public class Message {private String sender;private String content;private String messageType;private long timestamp; // 添加时间戳属性,记录消息发送时间public Message(String sender, String content, String messageType) {this(sender, content, messageType, new Date().getTime()); // 默认使用当前时间作为时间戳}public Message(String sender, String content, String messageType, long timestamp) {this.sender = sender;this.content = content;this.messageType = messageType;this.timestamp = timestamp;}public String getSender() {return sender;}public String getContent() {return content;}public String getMessageType() {return messageType;}public long getTimestamp() {return timestamp;}
}

ChatAdapter.java(存放在 java 对应包名目录下)

import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;import java.util.ArrayList;
import java.util.List;public class ChatAdapter extends RecyclerView.Adapter<ChatAdapter.ChatViewHolder> {private List<Message> messageList;public ChatAdapter() {messageList = new ArrayList<>();}public void addMessage(Message message) {messageList.add(message);notifyItemInserted(messageList.size() - 1);}@NonNull@Overridepublic ChatViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {// 使用新的消息项布局文件来加载视图View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.message_item, parent, false);return new ChatViewHolder(view);}@Overridepublic void onBindViewHolder(@NonNull ChatViewHolder holder, int position) {Message message = messageList.get(position);holder.bind(message);}@Overridepublic int getItemCount() {return messageList.size();}class ChatViewHolder extends RecyclerView.ViewHolder {private ImageView imageViewSenderAvatar;private TextView textViewSenderName;private TextView textViewMessageContent;public ChatViewHolder(@NonNull View itemView) {super(itemView);imageViewSenderAvatar = itemView.findViewById(R.id.imageView_sender_avatar);textViewSenderName = itemView.findViewById(R.id.textView_sender_name);textViewMessageContent = itemView.findViewById(R.id.textView_message_content);}public void bind(Message message) {if ("text".equals(message.getMessageType())) {// 根据消息发送者等信息设置对应的显示内容和样式(这里简单示例,可根据实际完善)textViewSenderName.setText(message.getSender());textViewMessageContent.setText(message.getContent());if (message.getSender().equals("自己的用户名")) {// 假设自己发送的消息居右对齐等样式设置(这里只是简单示意,可通过布局属性等详细设置样式)// 比如设置背景颜色、文本对齐方式等与对方消息区分开textViewMessageContent.setBackgroundResource(R.drawable.right_message_bg);} else {textViewMessageContent.setBackgroundResource(R.drawable.left_message_bg);}}// 后续添加对图片消息等其他类型消息的展示逻辑}}
}

DBHelper.java(存放在 java 对应包名目录下)

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;public class DBHelper extends SQLiteOpenHelper {// 数据库名称private static final String DATABASE_NAME = "chat.db";// 数据库版本号,每次数据库结构变更时需要递增这个版本号private static final int DATABASE_VERSION = 1;// 聊天记录表名称public static final String TABLE_CHAT = "chat_messages";// 聊天记录各字段名称及类型定义public static final String COLUMN_ID = "_id";public static final String COLUMN_SENDER = "sender";public static final String COLUMN_CONTENT = "content";public static final String COLUMN_MESSAGE_TYPE = "message_type";public static final String COLUMN_TIMESTAMP = "timestamp";public DBHelper(Context context) {super(context, DATABASE_NAME, null, DATABASE_VERSION);}@Overridepublic void onCreate(SQLiteDatabase db) {// 创建聊天记录表的SQL语句String createTableSql = "CREATE TABLE " + TABLE_CHAT + "("+ COLUMN_ID + " INTEGER PRIMARY KEY AUTOINCREMENT,"+ COLUMN_SENDER + " TEXT,"+ COLUMN_CONTENT + " TEXT,"+ COLUMN_MESSAGE_TYPE + " TEXT,"+ COLUMN_TIMESTAMP + " INTEGER"+ ")";db.execSQL(createTableSql);}@Overridepublic void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {// 这里简单示例,如果版本升级,先删除旧表再创建新表,实际应用中可能需要更复杂的迁移逻辑db.execSQL("DROP TABLE IF EXISTS " + TABLE_CHAT);onCreate(db);}
}

MainActivity.java(存放在 java 对应包名目录下)

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;import java.util.ArrayList;
import java.util.List;public class MainActivity extends AppCompatActivity {private RecyclerView recyclerViewChat;private EditText editTextMessage;private Button buttonSend;private ChatAdapter chatAdapter;private DatabaseReference databaseReference;private ValueEventListener valueEventListener;private DBHelper dbHelper;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);recyclerViewChat = findViewById(R.id.recyclerView_chat);editTextMessage = findViewById(R.id.editText_message);buttonSend = findViewById(R.id.button_send);// 初始化数据库帮助类dbHelper = new DBHelper(this);// 设置RecyclerView的布局管理器LinearLayoutManager layoutManager = new LinearLayoutManager(this);layoutManager.setStackFromEnd(true); // 让新消息显示在底部recyclerViewChat.setLayoutManager(layoutManager);chatAdapter = new ChatAdapter();recyclerViewChat.setAdapter(chatAdapter);// 初始化Firebase数据库引用databaseReference = FirebaseDatabase.getInstance().getReference("messages");// 监听数据库消息变化,实时更新聊天界面(这里可以结合本地数据库做优化,比如先展示本地已有的,再实时更新增量部分等)valueEventListener = new ValueEventListener() {@Overridepublic void onDataChange(@NonNull DataSnapshot dataSnapshot) {List<Message> messages = new ArrayList<>();for (DataSnapshot snapshot : dataSnapshot.getChildren()) {Message message = snapshot.getValue(Message.class);messages.add(message);}chatAdapter = new ChatAdapter();for (Message msg : messages) {chatAdapter.addMessage(msg);}recyclerViewChat.setAdapter(chatAdapter);}@Overridepublic void onCancelled(@NonNull DatabaseError databaseError) {Toast.makeText(MainActivity.this, "读取消息失败", Toast.LENGTH_SHORT).show();}};databaseReference.addValueEventListener(valueEventListener);// 从本地数据库读取历史聊天记录并展示loadChatHistoryFromDB();buttonSend.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {String messageText = editTextMessage.getText().toString().trim();if (!messageText.isEmpty()) {// 这里简单假设当前用户名为固定的,实际要做登录获取等逻辑String sender = "user1";Message message = new Message(sender, messageText, "text");// 将消息保存到Firebase数据库(网络存储,用于实时同步等)databaseReference.push().setValue(message);// 同时将消息插入到本地SQLite数据库insertMessageToDB(message);editTextMessage.setText("");}}});}// 从本地数据库加载聊天历史记录的方法private void loadChatHistoryFromDB() {List<Message> historyMessages = new ArrayList<>();SQLiteDatabase db = dbHelper.getReadableDatabase();String[] columns

软件架构介绍

数据绑定与展示
获取消息数据
消息数据处理与传递
网络存储与同步
数据库操作
网络通信
表现层 - MainActivity
ChatAdapter
业务逻辑层 - Message
数据访问层 - DBHelper
数据访问层 - Firebase相关操作
SQLite数据库
Firebase数据库
  1. 表现层(Presentation Layer):
    主要由MainActivity和相关的布局文件(activity_main.xmlmessage_item.xml等)构成。MainActivity负责处理用户界面的交互逻辑,例如用户输入消息后点击发送按钮的事件响应、接收消息并展示在RecyclerView列表中等操作。布局文件则定义了聊天界面的外观,包括聊天消息展示区域、输入框、发送按钮等各部分的视觉呈现。
    借助ChatAdapter来将消息数据适配并绑定到RecyclerView的每一项上,实现聊天消息列表的展示,它也是表现层与数据层进行交互的一个中间桥梁,负责把从数据层获取到的数据以合适的形式展示在界面上。

  2. 业务逻辑层(Business Logic Layer):
    消息实体类Message属于此层,它定义了聊天消息的结构,包含发送者、消息内容、消息类型以及时间戳等属性,用于在整个应用中对消息进行统一的抽象表示,方便各层之间传递和处理消息相关的数据。
    虽然示例中没有非常复杂的业务逻辑,但像判断消息类型(文本或图片等)来进行不同展示逻辑处理、处理聊天记录的一些简单排序或者筛选等功能都可以在这一层进行扩展和实现,目前简单地体现在ChatAdapterbind方法中对文本消息根据发送者不同设置不同展示样式等逻辑上。

  3. 数据访问层(Data Access Layer):
    包含DBHelper类,用于管理本地 SQLite 数据库的创建、打开、升级以及数据的增删改查操作。它封装了与数据库直接交互的细节,例如创建聊天记录表的 SQL 语句执行、消息数据插入到数据库(insertMessageToDB方法)以及从数据库查询加载聊天历史记录(loadChatHistoryFromDB方法)等操作,为业务逻辑层提供了统一的数据存储和读取接口。
    另外还有与 Firebase 相关的部分(DatabaseReference以及相关的数据库监听逻辑),用于实现网络存储和实时同步聊天记录的功能,通过将消息数据推送到 Firebase 数据库以及监听数据库变化来实时更新界面展示的消息内容,实现多人之间聊天记录的同步。

技术亮点及其实现原理

类似微信聊天界面的布局展示

亮点:打造了一个视觉效果和交互体验较为接近微信聊天界面的布局,能够清晰区分不同用户发送的消息,并且包含了常见的输入框、发送按钮以及表情按钮(预留功能位)等元素,整体界面简洁美观且符合用户使用习惯。

实现原理:

  1. 布局嵌套与组件使用:在主布局文件(activity_main.xml)中,采用RelativeLayout作为根布局,方便对各子布局进行相对位置的定位。内部嵌套RecyclerView用于展示聊天消息列表,通过设置其布局属性使其占满除底部输入框区域之外的空间,并允许垂直滚动来显示多条消息。底部的输入框区域则使用LinearLayout进行水平排列,依次放置表情按钮(ImageButton)、文本输入框(EditText)和发送按钮(Button),各组件设置合适的宽度、高度、背景、文本样式等属性来达到美观的效果。

  2. 消息项布局定制:对于聊天消息列表中的每一项(message_item.xml),使用LinearLayout来整体布局,左边放置显示发送者头像的ImageView,右边再嵌套一个LinearLayout来放置发送者昵称(TextView)和消息内容(TextView)。通过代码逻辑根据消息发送者判断来为消息内容的TextView设置不同的背景样式(如自己发送的居右对齐、背景颜色不同,对方发送的居左对齐、对应背景颜色等),以此区分不同用户的消息,营造类似微信聊天界面的视觉感受。

  3. 样式资源引用:在res/drawable目录下定义了多个 XML 样式资源文件,如用于设置EditText圆角背景的edittext_rounded_bg.xml、发送按钮不同状态下背景样式的button_send_bg.xml以及区分左右消息背景的left_message_bg.xmlright_message_bg.xml等,通过在布局文件中引用这些样式资源,进一步增强了界面的美观性和专业性。

支持多人聊天及实时消息同步

亮点:实现了多人之间进行文本聊天(图片聊天可后续进一步完善扩展),并且聊天记录能够实时同步,所有参与聊天的用户可以及时看到新发送的消息,提升了聊天的交互性和即时性。

实现原理:

  1. Firebase 实时数据库的使用:利用 Firebase 提供的实时数据库服务,在应用中初始化DatabaseReference来指向存储聊天消息的数据库节点(示例中为"messages"节点)。当用户点击发送按钮发送一条消息时(在MainActivity中处理发送按钮点击事件),将构造好的Message对象(包含发送者、消息内容、消息类型等信息)通过push().setValue(message)方法推送到 Firebase 数据库中,Firebase 会自动为每条消息生成一个唯一的键值,并按照设定的结构存储消息数据。

  2. 数据库监听机制:通过添加ValueEventListenerFirebase 数据库指定节点进行监听,在onDataChange回调方法中,一旦数据库中的消息数据发生变化(有新消息插入或者已有消息修改等情况),就会获取到最新的消息数据快照(DataSnapshot),然后解析这些数据创建对应的Message对象列表,并更新到ChatAdapter中,从而实现RecyclerView展示的聊天消息列表实时更新,让所有连接到该数据库的用户都能看到最新的聊天内容。

本地数据库存储聊天记录

亮点:除了使用网络数据库(Firebase 实时数据库)进行实时同步外,还借助本地的 SQLite 数据库来存储聊天记录,既保障了在网络不佳等情况下聊天记录的本地保存,又便于后续查询历史聊天内容、实现离线查看等功能,提升了数据的可靠性和用户体验。

实现原理:

  1. 数据库创建与表结构定义:创建DBHelper类继承自SQLiteOpenHelper,在其onCreate方法中执行创建聊天记录表(名为chat_messages)的 SQL 语句,定义了包含消息唯一标识(_id)、发送者(sender)、消息内容(content)、消息类型(message_type)以及时间戳(timestamp)等字段的表结构,用于存储聊天消息的详细信息。

  2. 数据插入操作:当用户发送消息时,在将消息推送到 Firebase 数据库的同时,会调用insertMessageToDB方法,该方法获取到可写的 SQLite 数据库实例(通过dbHelper.getWritableDatabase()),然后使用ContentValues来封装要插入的消息数据,再通过db.insert方法将消息数据插入到对应的聊天记录表中,实现本地数据库的消息存储。

  3. 历史记录查询与加载:在MainActivityloadChatHistoryFromDB方法中,首先获取可读的 SQLite 数据库实例,然后通过指定查询的列、排序方式等条件,使用db.query方法从聊天记录表中查询出历史聊天记录数据,将获取到的数据游标(Cursor)进行解析,创建Message对象并添加到消息列表中,最后更新到ChatAdapter来展示在聊天界面上,实现了聊天历史记录的加载展示功能。

性能优化与资源管理相关亮点

亮点:注重了一些基本的性能优化和资源管理措施,保障聊天界面滑动流畅不卡顿,并且避免了因不当的资源使用(如数据库监听未及时移除等)导致的内存泄露问题,提升了应用的稳定性和性能表现。

实现原理:

  1. RecyclerView 优化:在ChatAdapter的onBindViewHolder方法中,尽量保持简洁高效的操作逻辑,避免复杂耗时的计算或频繁创建新的视图对象等浪费资源的行为。例如对于图片消息展示虽然示例中未完整实现,但后续可以采用异步加载图片库(如 Glide 等)结合合适的缓存策略(内存缓存和磁盘缓存)来高效加载图片,减少因图片加载导致的卡顿。同时,利用RecyclerView本身的复用ViewHolder机制,正确实现onCreateViewHolderonBindViewHolder方法,确保视图的高效复用,提升列表滚动时的性能表现。

  2. 资源释放与管理:在MainActivityonDestroy方法中,添加了对 Firebase 数据库监听的移除操作(通过databaseReference.removeEventListener(valueEventListener)),当 Activity 销毁时(比如用户退出聊天界面或者切换到其他应用等情况),及时移除数据库监听,避免因持续监听数据库变化导致的内存泄露以及不必要的网络资源占用等问题。对于本地 SQLite 数据库操作,在每次数据库插入或查询等操作完成后,及时关闭数据库连接(如在insertMessageToDB方法结尾处db.close()),防止数据库连接资源的浪费和潜在的资源泄露风险。

自我总结

我是主攻C++方向的,所以在这进两个月的时间里我花了大半个月来学习JAVA、Android 开发和数据库等相关主要知识,包括RecyclerView 使用以及界面布局等知识,也学习了计算机四大件的基础知识。加之学校在大二上学期的学业问题,过量的知识整合对于我来说仍是一个巨大的挑战,我最终的代码调试,程序架构设计以及界面布局仍有很多不足,各个模块之间的耦合也没有很好完成,项目可以说是一塌糊涂,接下来我会继续优化我的项目,知道它是一个完美的APP也不必正在这里阐述自己的总结。

文章链接

在这里向老师表达我最真切的感谢,首先让我来学习到了如此多的只是,也令我深刻反省了自己在计算机领域的不足,单鞋老师!!!

相关文章:

APP聊天项目介绍

项目结构说明 res/layout目录&#xff1a;存放布局相关的 XML 文件&#xff0c;用于定义界面的外观&#xff0c;包含activity_main.xml&#xff08;主界面布局&#xff09;和message_item.xml&#xff08;聊天消息项布局&#xff09;。 res/drawable目录&#xff1a;存放一些…...

android user版本默认usb模式为充电模式

android插入usb时会切换至默认设置的模式&#xff0c;debug版本为adb&#xff0c;user版本为mtp protected long getChargingFunctions() {// if ADB is enabled, reset functions to ADB// else enable MTP as usual.if (isAdbEnabled()) {return UsbManager.FUNCTION_ADB;} e…...

常见问题QA的前端代码

这个的后端代码参见此文 使用语言向量建立常见问题的模糊搜索-CSDN博客https://blog.csdn.net/chenchihwen/article/details/144207262?spm1001.2014.3001.5501 这段代码实现了一个简单的问答页面&#xff0c;页面分为左右两部分&#xff0c;左侧用于展示对话记录&#xff0c…...

float globalMapVIsualizationLeafSize; 的中文意思是什么

1.在visual studio 中新建文件 没有包含#include <string>头文件&#xff0c;也可以使用 str2.append(", C");吗&#xff1f; 在 Visual Studio 或任何其他 C 开发环境中&#xff0c;即使新建的文件中没有显式包含 #include <string> 头文件&#xff0c…...

基于Java Springboot诗词学习APP且微信小程序

一、作品包含 源码数据库设计文档万字PPT全套环境和工具资源部署教程 二、项目技术 前端技术&#xff1a;Html、Css、Js、Vue、Element-ui 数据库&#xff1a;MySQL 后端技术&#xff1a;Java、Spring Boot、MyBatis 三、运行环境 开发工具&#xff1a;IDEA/eclipse微信开…...

CSS学习记录02

CSS颜色 指定颜色是通过使用预定义的颜色名称&#xff0c;或RGB&#xff0c;HEX&#xff0c;HSL&#xff0c;RGBA&#xff0c;HSLA值。 CSS颜色名 在CSS中&#xff0c;可以使用颜色名称来指定颜色&#xff1a; CSS背景色 您可以为HTML元素设置背景色&#xff1a; <h1 s…...

6.1 innoDb逻辑存储结构和架构-简介

InnoDB 是 MySQL 默认的存储引擎&#xff0c;以其强大的事务支持、崩溃恢复能力和高效的数据处理能力广受欢迎。本文从逻辑存储结构、内存架构、磁盘结构到后台线程&#xff0c;逐步剖析 InnoDB 的关键概念&#xff0c;帮助您更好地理解和应用。 1. 逻辑存储结构 InnoDB 的数据…...

C++看懂并使用-----回调函数

一&#xff09;回调函数的定义 在 C 中&#xff0c;回调函数是一段作为参数传递给其他函数的可执行代码。它允许在一个函数内部的特定点调用外部定义的函数&#xff0c;以实现更灵活的功能。 回调函数&#xff08;Callback Function&#xff09;是一种通过函数指针或函数对象&a…...

构建短视频矩阵生态体系开发分享

短视频矩阵系统模型的技术开发是一个综合性强、复杂度高的工程项目&#xff0c;它涵盖了广泛的技术选择与架构规划。以下是该项目开发过程中的关键步骤和核心考虑因素&#xff1a; 需求分析阶段&#xff1a; 明确目标用户群体及其需求&#xff0c;以确保系统设计的针对性和实…...

qt QGraphicsScale详解

1、概述 QGraphicsScale是Qt框架中提供的一个类&#xff0c;它提供了一种简单而灵活的方式在QGraphicsView框架中实现缩放变换。通过设置水平和垂直缩放因子、缩放中心点&#xff0c;可以创建各种缩放效果&#xff0c;提升用户界面的交互性和视觉吸引力。结合QPropertyAnimati…...

CAD 文件 批量转为PDF或批量打印

CAD 文件 批量转为PDF或批量打印&#xff0c;还是比较稳定的 1.需要本地安装CAD软件 2.通过 Everything 搜索工具搜索&#xff0c;DWG To PDF.pc3 &#xff0c;获取到文件目录 &#xff0c;替换到代码中&#xff0c; originalValue ACADPref.PrinterConfigPath \ r"C:…...

Java基础面试题16:简述Servlet的体系结构

Servlet 是 JavaEE 技术中的一大核心组件&#xff0c;它运行在服务器端&#xff0c;用于处理客户端的请求并生成响应。如果你想深入了解它的体系结构&#xff0c;下面会用通俗的语言带你一步步搞懂。 1. Servlet API&#xff1a;开发者和容器沟通的桥梁 Servlet API 是开发 S…...

Web开发基础学习——理解React组件中的根节点

Web开发基础学习系列文章目录 第一章 基础知识学习之理解React组件中的根节点 文章目录 Web开发基础学习系列文章目录前言一、根节点的概念二、示例解释总结 前言 在 React 应用中&#xff0c;根节点&#xff08;Root Node&#xff09;是指 React 组件树的起始点&#xff0c;…...

【人工智能】探索自然语言生成(NLG):用GPT生成文本

《Python OpenCV从菜鸟到高手》带你进入图像处理与计算机视觉的大门! 自然语言生成(Natural Language Generation, NLG)是自然语言处理(NLP)领域的重要分支,旨在生成符合语法和语义的自然语言文本。近年来,基于深度学习的生成式预训练模型(GPT)在NLG任务中取得了巨大…...

挑战用React封装100个组件【004】

项目地址 https://github.com/hismeyy/react-component-100 组件描述 组件适用于展示图片的地方&#xff0c;提供了small&#xff0c;medium&#xff0c;large三种大小。可以删除图片&#xff0c;也可以全屏预览图片。 样式展示 前置依赖 今天我们的这个挑战需要用用到了…...

vue elementui layout布局组件实现规则的弹性布局

背景&#xff1a;遇到在一个容器里&#xff0c;采用弹性盒布局的时候&#xff0c;如果元素个数改变&#xff0c;元素的排列会错乱。 解决方式 方式一&#xff1a;之前遇到的时候&#xff0c;是采用计算元素个数的方式&#xff0c;采用透明元素补齐的方式&#xff08;比如一个有…...

SpringBoot Web 开发请求参数

SpringBoot Web 开发请求参数 简单的 web 请求: @RestController public class HelloController {@RequestMapping("sayHello")public String sayHello(){System.out.println("Hello World");return "hello world";} }获取请求参数 简单参数…...

python7学习笔记-循环、迭代、pass

九九乘法表-while循环 right 1 while right < 9:left 1while left < right:print(f{left}x{right}{left * right},end\t)left 1print()right 1 # #效果&#xff1a; #1x11 #1x22 2x24 #1x33 2x36 3x39 #1x44 2x48 3x412 4x416 #1x55 2x510 3x515 4x520 5x525 #…...

LeetCode78:子集

链接&#xff1a;78. 子集 假设我们要求[1, 2, 3]的子集&#xff1a; 我们知道[1, 2]的子集是A&#xff1a; 而[1, 2, 3]就是比[1, 2]多了一个元素3&#xff1b;所以将3加入到上述A中的每个集合中&#xff0c;得到一个新集合B&#xff1a; 结论&#xff1a;[1, 2, 3]的子集就…...

Linux 安装scala

文章目录 Linux 安装scala下载环境变量配置 Linux 安装scala 前提linux需要已经安装好JDK&#xff08;JDK安装&#xff09;&#xff0c;Scala对JDK版本有明确的要求。通常&#xff0c;Scala的稳定版本要求JDK版本不低于1.8。例如&#xff0c;Scala 2.11.8和2.12.7版本都要求JD…...

Vue3 + Element Plus + TypeScript中el-transfer穿梭框组件使用详解及示例

使用详解 Element Plus 的 el-transfer 组件是一个强大的穿梭框组件&#xff0c;常用于在两个集合之间进行数据转移&#xff0c;如权限分配、数据选择等场景。下面我将详细介绍其用法并提供一个完整示例。 核心特性与用法 基本属性 v-model&#xff1a;绑定右侧列表的值&…...

基于Flask实现的医疗保险欺诈识别监测模型

基于Flask实现的医疗保险欺诈识别监测模型 项目截图 项目简介 社会医疗保险是国家通过立法形式强制实施&#xff0c;由雇主和个人按一定比例缴纳保险费&#xff0c;建立社会医疗保险基金&#xff0c;支付雇员医疗费用的一种医疗保险制度&#xff0c; 它是促进社会文明和进步的…...

【Go语言基础【12】】指针:声明、取地址、解引用

文章目录 零、概述&#xff1a;指针 vs. 引用&#xff08;类比其他语言&#xff09;一、指针基础概念二、指针声明与初始化三、指针操作符1. &&#xff1a;取地址&#xff08;拿到内存地址&#xff09;2. *&#xff1a;解引用&#xff08;拿到值&#xff09; 四、空指针&am…...

纯 Java 项目(非 SpringBoot)集成 Mybatis-Plus 和 Mybatis-Plus-Join

纯 Java 项目&#xff08;非 SpringBoot&#xff09;集成 Mybatis-Plus 和 Mybatis-Plus-Join 1、依赖1.1、依赖版本1.2、pom.xml 2、代码2.1、SqlSession 构造器2.2、MybatisPlus代码生成器2.3、获取 config.yml 配置2.3.1、config.yml2.3.2、项目配置类 2.4、ftl 模板2.4.1、…...

【网络安全】开源系统getshell漏洞挖掘

审计过程&#xff1a; 在入口文件admin/index.php中&#xff1a; 用户可以通过m,c,a等参数控制加载的文件和方法&#xff0c;在app/system/entrance.php中存在重点代码&#xff1a; 当M_TYPE system并且M_MODULE include时&#xff0c;会设置常量PATH_OWN_FILE为PATH_APP.M_T…...

探索Selenium:自动化测试的神奇钥匙

目录 一、Selenium 是什么1.1 定义与概念1.2 发展历程1.3 功能概述 二、Selenium 工作原理剖析2.1 架构组成2.2 工作流程2.3 通信机制 三、Selenium 的优势3.1 跨浏览器与平台支持3.2 丰富的语言支持3.3 强大的社区支持 四、Selenium 的应用场景4.1 Web 应用自动化测试4.2 数据…...

二维FDTD算法仿真

二维FDTD算法仿真&#xff0c;并带完全匹配层&#xff0c;输入波形为高斯波、平面波 FDTD_二维/FDTD.zip , 6075 FDTD_二维/FDTD_31.m , 1029 FDTD_二维/FDTD_32.m , 2806 FDTD_二维/FDTD_33.m , 3782 FDTD_二维/FDTD_34.m , 4182 FDTD_二维/FDTD_35.m , 4793...

前端工具库lodash与lodash-es区别详解

lodash 和 lodash-es 是同一工具库的两个不同版本&#xff0c;核心功能完全一致&#xff0c;主要区别在于模块化格式和优化方式&#xff0c;适合不同的开发环境。以下是详细对比&#xff1a; 1. 模块化格式 lodash 使用 CommonJS 模块格式&#xff08;require/module.exports&a…...

npm安装electron下载太慢,导致报错

npm安装electron下载太慢&#xff0c;导致报错 背景 想学习electron框架做个桌面应用&#xff0c;卡在了安装依赖&#xff08;无语了&#xff09;。。。一开始以为node版本或者npm版本太低问题&#xff0c;调整版本后还是报错。偶尔执行install命令后&#xff0c;可以开始下载…...

十二、【ESP32全栈开发指南: IDF开发环境下cJSON使用】

一、JSON简介 JSON&#xff08;JavaScript Object Notation&#xff09;是一种轻量级的数据交换格式&#xff0c;具有以下核心特性&#xff1a; 完全独立于编程语言的文本格式易于人阅读和编写易于机器解析和生成基于ECMAScript标准子集 1.1 JSON语法规则 {"name"…...