前言
本篇文章主要使用Android Studio来进行微信聊天框架的开发,开发语言为Java。
通过学习本文内容,可以自己实现一个微信的聊天框架。并且后续还可以在此框架上增添自己需要的内容,完成自己的APP开发。
本文主要目的是为了实现最终的微信的框架,但为了便于理解以及能够学习到一定的Android和Java知识,会通过介绍必备的知识,引导读者一步一步地实现最终的框架。
一、实现效果图
主界面:
聊天:
联系人:
音乐:
设置:
聊天界面:
总聊天记录:
具体聊天记录:
联系人界面:
总联系人:
具体联系人:
音乐界面:
总界面:
播放:
切歌:
暂停 :
设置界面:
总界面:
具体设置:
二、功能说明
主界面:
设计一个类微信的主界面,按照以上实现效果图分别为四个界面:聊天、联系人、音乐、设置,并且实现点击下方进行界面跳转,并且在每一个界面会有显示列表效果。
聊天界面:
总聊天界面里有数条聊天记录,上面显示着头像,姓名,聊天时间。点击聊天记录即可进入聊天记录界面,里面包含对方的头像,姓名,聊天记录和自己的头像。
联系人界面:
总联系人界面里有数个联系人,上面显示着头像,姓名。点击联系人即可进入具体联系人界面,里面包含联系人的头像,姓名,电话号码,家庭地址,年龄,兴趣爱好和工作。
音乐界面:
总音乐界面里有数首歌曲,每首歌曲都有自己的名称。点击其中一首歌后 ,播放按钮上会显示这首歌的专辑图片,播放按钮也会变成暂停按钮。在一首歌曲播放时点击其他的歌曲即可进行切歌,可以直接转换成其他歌曲的播放,专辑图片也会发生改变。在歌曲播放时点击暂停按钮,歌曲会停止播放,专辑图片也会消失。
设置界面:
总设置界面里有数个设置,点击即可进入具体联系人界面,。
三、实现说明
1.主模块
①MainActivity.java
代码:
package com.example.myapplication;
// 导入所需的类
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
// MainActivity 继承自 AppCompatActivity
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 设置活动的布局文件
setContentView(R.layout.activity_main);
// 找到布局中的按钮
Button btnChat = findViewById(R.id.btn_chat); // 聊天按钮
Button btnContacts = findViewById(R.id.btn_contacts); // 联系人按钮
Button btnMusic = findViewById(R.id.btn_music); // 音乐按钮
Button btnSettings = findViewById(R.id.btn_settings); // 设置按钮
// 设置聊天按钮的点击事件
btnChat.setOnClickListener(v -> loadFragment(new ChatFragment()));
// 设置联系人按钮的点击事件
btnContacts.setOnClickListener(v -> loadFragment(new ContactsFragment()));
// 设置音乐按钮的点击事件
btnMusic.setOnClickListener(v -> loadFragment(new MusicFragment()));
// 设置设置按钮的点击事件
btnSettings.setOnClickListener(v -> loadFragment(new SettingsFragment()));
// 如果是第一次创建活动,加载默认的聊天 Fragment
if (savedInstanceState == null) {
loadFragment(new ChatFragment());
}
}
// 定义一个加载 Fragment 的方法
private void loadFragment(Fragment fragment) {
// 开始一个 Fragment 事务
getSupportFragmentManager().beginTransaction()
.replace(R.id.fragment_container, fragment) // 替换 fragment_container 中的内容为新的 Fragment
.commit(); // 提交事务
}
}
代码解析:
包声明:
package com.example.myapplication;:指定当前类所在的包。
导入语句:
导入 Android 和支持库中所需的类。
MainActivity 类:
public class MainActivity extends AppCompatActivity:定义了主活动类,它继承自AppCompatActivity,这是支持库中的一个活动基类,提供了向后兼容的特性。
onCreate 方法:
protected void onCreate(Bundle sav edInstanceState):活动创建时调用的方法。
setContentView(R.layout.activity_main):设置活动的布局为 activity_main.xml 文件。
按钮初始化:
使用 findViewById 找到布局中的按钮,并为每个按钮创建一个变量。
设置按钮点击事件:
使用 Lambda 表达式为每个按钮设置点击监听器,调用 loadFragment 方法加载相应的 Fragment。
加载默认 Fragment:
if (savedInstanceState == null)
:检查活动是否是第一次创建,如果是,则加载聊天 Fragment 作为默认视图。
loadFragment 方法:
private void loadFragment(Fragment fragment)
:定义了一个私有方法,用于加载指定的 Fragment。
getSupportFragmentManager().beginTransaction()
:开始一个 Fragment 事务。
replace(R.id.fragment_container, fragment)
:将指定的容器(fragment_container
)中的内容替换为新的 Fragment。
commit()
:提交事务,确保更改生效。
总结:
该代码的功能是通过按钮点击在同一个活动中切换不同的 Fragment,从而实现动态界面更新。每个按钮对应一个特定的 Fragment,用户的操作将影响显示的内容。
②activity_main.xml
布局界面:
代码:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent" <!-- 设置布局宽度为全屏 -->
android:layout_height="match_parent"> <!-- 设置布局高度为全屏 -->
<!-- Fragment 容器,用于动态加载不同的 Fragment -->
<FrameLayout
android:id="@+id/fragment_container" <!-- 容器的 ID,用于在活动中访问 -->
android:layout_width="match_parent" <!-- 容器宽度为全屏 -->
android:layout_height="match_parent" /> <!-- 容器高度为全屏 -->
<!-- 底部按钮布局,使用 LinearLayout 水平排列 -->
<android.widget.LinearLayout
android:layout_width="match_parent" <!-- 按钮布局宽度为全屏 -->
android:layout_height="wrap_content" <!-- 按钮布局高度根据内容自适应 -->
android:layout_alignParentBottom="true" <!-- 将按钮布局对齐到父布局底部 -->
android:orientation="horizontal"> <!-- 设置布局方向为水平 -->
<!-- 聊天按钮 -->
<Button
android:id="@+id/btn_chat" <!-- 聊天按钮的 ID -->
android:layout_width="0dp" <!-- 按钮宽度为0,配合权重使用 -->
android:layout_height="wrap_content" <!-- 按钮高度根据内容自适应 -->
android:layout_weight="1" <!-- 权重为1,均匀分配剩余空间 -->
android:text="聊天" /> <!-- 按钮文本 -->
<!-- 联系人按钮 -->
<Button
android:id="@+id/btn_contacts" <!-- 联系人按钮的 ID -->
android:layout_width="0dp" <!-- 按钮宽度为0,配合权重使用 -->
android:layout_height="wrap_content" <!-- 按钮高度根据内容自适应 -->
android:layout_weight="1" <!-- 权重为1,均匀分配剩余空间 -->
android:text="联系人" /> <!-- 按钮文本 -->
<!-- 音乐按钮 -->
<Button
android:id="@+id/btn_music" <!-- 音乐按钮的 ID -->
android:layout_width="0dp" <!-- 按钮宽度为0,配合权重使用 -->
android:layout_height="wrap_content" <!-- 按钮高度根据内容自适应 -->
android:layout_weight="1" <!-- 权重为1,均匀分配剩余空间 -->
android:text="音乐" /> <!-- 按钮文本 -->
<!-- 设置按钮 -->
<Button
android:id="@+id/btn_settings" <!-- 设置按钮的 ID -->
android:layout_width="0dp" <!-- 按钮宽度为0,配合权重使用 -->
android:layout_height="wrap_content" <!-- 按钮高度根据内容自适应 -->
android:layout_weight="1" <!-- 权重为1,均匀分配剩余空间 -->
android:text="设置" /> <!-- 按钮文本 -->
</android.widget.LinearLayout>
</RelativeLayout>
代码解析:
根布局:
使用 RelativeLayout 作为根布局,允许其子视图相对定位。
Fragment 容器:
FrameLayout
作为 fragment_container
,用于动态加载不同的 Fragment。它的宽度和高度都设置为匹配父布局,这样它可以占据整个屏幕。
底部按钮布局:
使用 LinearLayout
水平排列四个按钮。该布局的宽度设置为匹配父布局,确保其占据底部的整个宽度。
按钮设置:
每个按钮的 layout_width
设置为 0dp
,并与 layout_weight
属性结合使用,以确保它们均匀分配可用空间。所有按钮的 layout_weight
值都设置为 1
,这意味着它们将共享底部布局的可用空间。
总结:
此布局文件提供了一个基本的用户界面结构,允许用户在不同功能之间进行切换。通过点击底部的按钮,用户可以加载不同的 Fragment,从而实现动态内容切换。这样的设计在许多应用程序中都非常常见,有助于提升用户体验和界面的可用性。
2.聊天模块
Ⅰ 聊天界面
①ChatFragment.java
代码:
package com.example.myapplication;
import android.content.Intent; // 导入 Intent 类,用于启动新活动
import android.os.Bundle; // 导入 Bundle 类,用于传递数据
import android.view.LayoutInflater; // 导入 LayoutInflater 类,用于加载布局
import android.view.View; // 导入 View 类
import android.view.ViewGroup; // 导入 ViewGroup 类
import android.widget.AdapterView; // 导入 AdapterView 类,适用于列表项点击事件
import android.widget.ArrayAdapter; // 导入 ArrayAdapter 类,用于适配数据
import android.widget.ImageView; // 导入 ImageView 类,用于显示头像
import android.widget.ListView; // 导入 ListView 类,用于显示列表
import android.widget.TextView; // 导入 TextView 类,用于显示文本
import androidx.annotation.NonNull; // 导入注解类
import androidx.fragment.app.Fragment; // 导入 Fragment 类
public class ChatFragment extends Fragment {
// 定义联系人名称、时间和头像资源数组
private String[] people = {"王力宏", "周杰伦", "林俊杰", "陶喆"};
private String[] times = {"10:30 AM", "9:15 AM", "8:45 AM", "7:50 AM"}; // 添加时间数组
private int[] imageIds = {
R.drawable.wanglihong, // 王力宏头像资源
R.drawable.zhoujielun, // 周杰伦头像资源
R.drawable.linjunjie, // 林俊杰头像资源
R.drawable.taozhe // 陶喆头像资源
};
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// 加载 fragment_chat 布局
View view = inflater.inflate(R.layout.fragment_chat, container, false);
// 获取 ListView 并设置适配器
ListView listView = view.findViewById(R.id.list_view);
ChatAdapter adapter = new ChatAdapter();
listView.setAdapter(adapter);
// 设置列表项点击事件
listView.setOnItemClickListener((parent, view1, position, id) -> {
String selectedPerson = people[position]; // 获取被点击的联系人名称
Intent intent = new Intent(getActivity(), ChatHistoryActivity.class); // 创建 Intent 以启动 ChatHistoryActivity
intent.putExtra("person_name", selectedPerson); // 传递联系人名称
intent.putExtra("image_id", imageIds[position]); // 传递头像资源 ID
startActivity(intent); // 启动活动
});
return view; // 返回视图
}
// 自定义适配器类
private class ChatAdapter extends ArrayAdapter<String> {
ChatAdapter() {
super(getActivity(), R.layout.list_item_chat, people); // 使用联系人数组初始化父类
}
@NonNull
@Override
public View getView(int position, View convertView, @NonNull ViewGroup parent) {
// 重用视图,避免频繁创建新视图
if (convertView == null) {
convertView = LayoutInflater.from(getActivity()).inflate(R.layout.list_item_chat, parent, false);
}
// 获取视图中的组件
TextView nameTextView = convertView.findViewById(R.id.name_text_view); // 联系人名称 TextView
TextView timeTextView = convertView.findViewById(R.id.time_text_view); // 聊天时间 TextView
ImageView avatarImageView = convertView.findViewById(R.id.avatar_image_view); // 头像 ImageView
// 设置组件内容
nameTextView.setText(people[position]); // 设置姓名
timeTextView.setText(times[position]); // 设置时间文本
avatarImageView.setImageResource(imageIds[position]); // 设置头像
return convertView; // 返回视图
}
}
}
代码解析:
包声明:
package com.example.myapplication;:指定当前类所在的包。
导入语句:
导入了用于活动、布局、视图和适配器的相关类。
类定义:
public class ChatFragment extends Fragment
:定义了一个 Fragment
类,用于显示聊天界面。
数据定义:
people
数组存储联系人姓名。
times
数组存储对应的聊天时间。
imageIds
数组存储头像资源的 ID。
onCreateView 方法:
onCreateView 方法用于创建并返回 Fragment 的视图。
使用 LayoutInflater 加载布局文件 fragment_chat。
获取 ListView 并设置自定义适配器 ChatAdapter。
列表项点击事件:
使用 setOnItemClickListener
方法为列表项设置点击事件处理器。
创建 Intent
启动 ChatHistoryActivity
,并通过 putExtra
方法传递联系人名称和头像 ID。
自定义适配器 ChatAdapter
:
继承自 ArrayAdapter<String>
,用于适配联系人数组。
getView
方法用于为每个列表项创建视图,重用视图以提高性能。
在 getView
方法中,设置每个联系人的名称、时间和头像。
总结 :
该代码实现了一个聊天界面,用户可以查看联系人列表及其最近的聊天时间。通过点击列表项,用户能够进入聊天历史页面,查看与特定联系人的详细聊天记录。自定义适配器允许灵活地管理列表项的显示内容,提升用户体验。
②fragment_chat.xml
布局界面:
代码:
<?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="match_parent" <!-- 设置布局高度为全屏,即匹配父视图的高度 -->
android:orientation="vertical"> <!-- 设置布局方向为垂直排列 -->
<!-- ListView 用于显示一组可滚动的列表项 -