# 仿QQ安卓APP
**Repository Path**: appreturn/imitation-qq-android-app
## Basic Information
- **Project Name**: 仿QQ安卓APP
- **Description**: 实训时做的仿QQ原生安卓项目,后续会更新
- **Primary Language**: Java
- **License**: Apache-2.0
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 4
- **Created**: 2024-04-06
- **Last Updated**: 2024-04-06
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# 仿QQ安卓APP
写在前面
**由于本人初学阶段,写这篇博客是总结所学的知识点,为后面的进阶打好基础**
**有任何关于代码和表述问题,欢迎评论区指出**
楼主近期在学习关于安卓中`Fragment`和`ListView`中的知识,按照老师的要求模仿一下QQ界面 要求功能
- 有登录界面
- 密码不对提示密码不对
- 账号密码任一为空提示用户不能为空
- 登录成功提示登录成功
- 可以实现账号密码记住功能
- 有三个界面可以点击底部按钮实现页面的切换
- 实现按钮选中状态和未选中状态不一样
- 联系人界面
- 信息界面
- 状态界面
- 发送信息功能
- 点击信息界面中的任意消息可以进入发消息界面
- 可以实现点击发送按钮将所输入的文字显示在屏幕中
**提示:**本人用的**IDE开发环境**是`Android Studio` **API**是`30`
**目录结构一览**
[](https://imgtu.com/i/2MmRG6)
**res中的文件**
[](https://imgtu.com/i/2MmfxO)
## 1. 登录界面
- 登录界面的布局文件
**activity_main.xml**
所用图标都可以在阿里巴巴图标网找到[iconfont-阿里巴巴矢量图标库](https://www.iconfont.cn/)
```xml
```
所对应的`MainActivity`
- 其中的判断通过if语句判断用户是否输入和输入正确
- 提示 通过`Toast`的方式提示
```java
package com.czie.qq;
import androidx.appcompat.app.AppCompatActivity;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
private Context context;
private EditText userNameEditText, passwordEditText;
private ImageButton loginButton;
private ShareHelper shareHelper;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
context=this;
shareHelper=new ShareHelper(context);
initview();
}
private void initview() {
userNameEditText = findViewById(R.id.userNameEditText);
passwordEditText = findViewById(R.id.passwordEditText);
loginButton = findViewById(R.id.loginButton);
loginButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//进行登录页面的处理
String username = userNameEditText.getText().toString();
String password = passwordEditText.getText().toString();
if (username.length() > 0) {
if (username.equals("zk")) {
if (password.length() > 0) {
if (password.equals("123")) {
// 对账号和密码进行保存
shareHelper.save("username",username);
shareHelper.save("password",password);
startActivity(new Intent(MainActivity.this, HomeActivity.class));
Toast.makeText(MainActivity.this, "登录成功", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(MainActivity.this, "密码不正确", Toast.LENGTH_LONG).show();
}
} else {
Toast.makeText(MainActivity.this,"请填写密码",Toast.LENGTH_LONG).show();
}
} else {
Toast.makeText(MainActivity.this,"用户名不正确",Toast.LENGTH_LONG).show();
}
} else {
Toast.makeText(MainActivity.this,"请填写用户名",Toast.LENGTH_LONG).show();
}
}
});
}
@Override
protected void onStart() {
super.onStart();
userNameEditText.setText(shareHelper.read("username"));
passwordEditText.setText(shareHelper.read("password"));
}
}
```
## 2. 记住密码功能
- 实现第一次登录成功后,再次登录会记住账号和密码的功能
这个功能我们用`SharedPreferences`
简单了解下什么是SharedPreferences
- SharedPreferences是Android平台上一个轻量级的存储辅助类,用来保存应用的一些常用配置,它提供了string,set,int,long,float,boolean六种数据类型。最终数据是以xml形式进行存储。在应用中通常做一些简单数据的持久化缓存。
```java
package com.czie.qq;
import android.content.Context;
import android.content.SharedPreferences;
public class ShareHelper {
//两个功能 保存,读取
Context context;
public ShareHelper() {
}
public ShareHelper(Context context) {
this.context = context;
}
//保存
public void save(String key, String value) {
SharedPreferences sharedPreferences = context.getSharedPreferences("iot1921", Context.MODE_PRIVATE);
//创建一个输入值
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putString(key, value);
editor.commit();
}
//读取数据
public String read(String key) {
SharedPreferences sharedPreferences = context.getSharedPreferences("iot1921", Context.MODE_PRIVATE);
return sharedPreferences.getString(key, "");
}
}
```
注意事项:
- 输入值记得提交,editor.commit();
- 在`MainACtivity`中记得在OnStart方法中使用ShareHelper.read传入需要记住的值!
预览一下成果!

## 3. Fragment界面跳转
这里有三个Fragment,所对应需要三个fragment布局界面
- 首先要创建3个按钮的切换xml
**message.xml**
```xml
```
**people.xml**
```xml
```
**statue.xml**
```xml
```
然后在布局界面中使用
**activity_home.xml**
这个界面的布局可以随意发挥,本人做的比较简单,见谅
- 3个`ImageView`和1个`FrameLayout`
- `ImageView`分别绑定点击事件
```xml
```
### 3.1 Fragement的界面编写
**item_listview.xml**
```xml
```
**fragment_message.xml**
```xml
```
**fragment_people.xml**
```xml
```
**fragment_statue.xml**
```xml
```
Fragment布局写完就是重点如何在`FrameLayout`中加载
我们还需要创建布局所对应的Fragment
**每个Fragment要指定加载的布局和调用的方法**
> **onCreateView()**:每次创建、绘制该Fragment的View组件时回调该方法,Fragment将会显示该方法返回的View组件。
> **onActivityCreated()**:当Fragment所在的Activity被启动完成后回调该方法。
在这个文件中需要实现
- 点击进入聊天界面
- 可以发送消息显示在屏幕上
我们通过`List`集合中存放`Map`
`Map`中所存放的Key就是所创建的`Names`数组,Value就是`Images`数组
通过创建SimpleAdapter对象来加载`fragment_message`
**讲下这三行关键的代码**
```java
//加载在哪个布局界面
messagelistView= getActivity().findViewById(R.id.messagelistView);
//适配器中的参数
/**
context 上下文
dataList 集合中存放的值
R.layout.item_listview 加载的布局界面
new String[]{"Name","Image"} String数组
new int[]{R.id.NameTextView,R.id.ImageView} int数组 获取id
*/
simpleAdapter=new SimpleAdapter(context,dataList,R.layout.item_listview,
new String[]{"Name","Image"},
new int[]{R.id.NameTextView,R.id.ImageView});
//加载适配器
messagelistView.setAdapter(simpleAdapter);
```
一个获取数据的方法`getData()`
```java
//list获取数据
public void getData(){
//遍历数组中的数据 添加到list中
for (int i = 0; i < Names.length; i++) {
//新建map 存放数组中的数据 最后存放在list中
HashMap map = new HashMap();
map.put("Name",Names[i]);
map.put("Image",Images[i]);
dataList.add(map);
}
}
```
**MessageFragment**
```java
package com.czie.qq;
import android.app.Fragment;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.Toast;
import androidx.annotation.Nullable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class MessageFragment extends Fragment {
private Context context;
private ListView messagelistView;
List