仿 手机QQ 登录、注册、找回密码、好友列表、QQ状态等功能的实现
全文 图 + 代码 。。。。
福利!!!(QQ登录背景,过度页面背景)
![]() | ![]() |
---|---|
登录背景 | 加载背景 |
1.加载过程中的背景
2.登录页面
- 点击“手机号登录”、“找回密码”、“新用户注册”后可以跳转到相应页面。
- 账号、密码不为空时,登录图标改变,程序可登录(数库库信息验证成功后)。如图:
- 点击 “ X ” 文本框内数据全部清除。
- 点击密码框时,密码框左侧出现 “ 小眼睛 ” 可以进行密码的显示。
- 点击文本框以外的区域,键盘自动收起来
1. 登录页面 布局代码
<?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:gravity="center_horizontal"
android:orientation="vertical"
android:background="@drawable/bg">
<ImageView
android:layout_width="120dp"
android:layout_height="wrap_content"
android:layout_marginTop="50dp"
android:layout_marginRight="60dp"
android:src="@drawable/qq" />
<FrameLayout
android:layout_width="310dp"
android:layout_height="55dp"
android:layout_marginTop="50dp" >
<EditText
android:id="@+id/qq_num"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/circle_shape_bg"
android:hint="QQ号/手机号/邮箱"
android:inputType="number"
android:maxLines="1"
android:singleLine="true"
android:textSize="20sp"
android:gravity="center"/>
<ImageView
android:id="@+id/qq_num_delete"
android:layout_width="18dp"
android:layout_height="18dp"
android:layout_gravity="right|center_vertical"
android:layout_marginRight="20dp"
android:background="@drawable/delete" />
</FrameLayout>
<FrameLayout
android:layout_width="310dp"
android:layout_height="55dp"
android:layout_marginTop="20dp" >
<EditText
android:id="@+id/qq_password"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/circle_shape_bg"
android:hint="输入密码"
android:inputType="textPassword"
android:maxLines="1"
android:singleLine="true"
android:textSize="20sp"
android:gravity="center"/>
<ImageView
android:id="@+id/qq_password_delete"
android:layout_width="18dp"
android:layout_height="18dp"
android:layout_gravity="right|center_vertical"
android:layout_marginRight="20dp"
android:background="@drawable/delete" />
<ImageView
android:id="@+id/password_see"
android:layout_width="25dp"
android:layout_height="wrap_content"
android:layout_gravity="left|center_vertical"
android:layout_marginLeft="20dp"
android:src="@drawable/password_no" />
</FrameLayout>
<ImageView
android:id="@+id/qq_login"
android:layout_width="50dp"
android:layout_height="wrap_content"
android:layout_marginTop="60dp"
android:src="@drawable/go_no" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_marginTop="220dp"
android:gravity="center"
android:orientation="horizontal">
<TextView
android:id="@+id/qq_phone"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="手机号登录"
android:textColor="@color/white" />
<View
android:layout_width="1dp"
android:layout_height="10dp"
android:layout_marginLeft="25dp"
android:layout_marginRight="25dp"
android:background="@color/white" />
<TextView
android:id="@+id/qq_forget_password"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="找回密码"
android:textColor="@color/white" />
<View
android:layout_width="1dp"
android:layout_height="10dp"
android:layout_marginLeft="25dp"
android:layout_marginRight="25dp"
android:background="@color/white" />
<TextView
android:id="@+id/qq_register"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="新用户注册"
android:textColor="@color/white" />
</LinearLayout>
</LinearLayout>
2.用户注册
1. 注册页面
2. 输入提示
3. 日期选择
4. 信息显示
![]() |
![]() |
- 点击 “ 注册 ” 数据写入数据库。“ 取消 ” 则不进行信息注册。
5. 《用户隐私协议》
- 这是QQ官方协议截图!!!。
2. 注册页面 布局代码
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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="@drawable/bg_3"
android:gravity="center_horizontal"
android:orientation="vertical">
<ImageView
android:layout_width="wrap_content"
android:layout_height="120dp"
android:layout_marginTop="50dp"
android:src="@drawable/zc" />
<TableRow
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:gravity="center_horizontal">
<TextView
android:layout_width="110dp"
android:layout_height="50dp"
android:gravity="center"
android:text="昵称"
android:textSize="20dp" />
<EditText
android:id="@+id/user_name"
android:layout_width="200dp"
android:layout_height="50dp"
android:layout_gravity="center"
android:layout_marginLeft="10dp"
android:background="@drawable/circle_shape_bg_2"
android:gravity="left|center"
android:maxLines="1"
android:singleLine="true"
android:paddingLeft="5dp"
android:textSize="20sp" />
</TableRow>
<TableRow
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:gravity="center_horizontal">
<TextView
android:layout_width="110dp"
android:layout_height="50dp"
android:gravity="center"
android:text="性别"
android:textSize="20dp" />
<RadioGroup
android:id="@+id/radioGroup"
android:layout_width="200dp"
android:layout_height="50dp"
android:layout_marginLeft="10dp"
android:background="@drawable/circle_shape_bg_2"
android:gravity="center|left"
android:orientation="horizontal"
android:paddingLeft="5dp">
<RadioButton
android:id="@+id/boy"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="true"
android:text="男"
android:textSize="20dp" />
<RadioButton
android:id="@+id/girl"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="女"
android:textSize="20dp" />
</RadioGroup>
</TableRow>
<TableRow
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:gravity="center_horizontal">
<TextView
android:layout_width="110dp"
android:layout_height="50dp"
android:gravity="center"
android:text="密码"
android:textSize="20dp" />
<EditText
android:id="@+id/pass_word"
android:layout_width="200dp"
android:layout_height="50dp"
android:layout_gravity="center"
android:layout_marginLeft="10dp"
android:background="@drawable/circle_shape_bg_2"
android:gravity="left|center"
android:inputType="textPassword"
android:maxLines="1"
android:singleLine="true"
android:paddingLeft="5dp"
android:textSize="20sp" />
</TableRow>
<TableRow
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:gravity="center_horizontal">
<TextView
android:layout_width="110dp"
android:layout_height="50dp"
android:gravity="center"
android:text="重复密码"
android:textSize="20dp" />
<EditText
android:id="@+id/re_pass_word"
android:layout_width="200dp"
android:layout_height="50dp"
android:layout_gravity="center"
android:layout_marginLeft="10dp"
android:background="@drawable/circle_shape_bg_2"
android:gravity="left|center"
android:inputType="textPassword"
android:maxLines="1"
android:singleLine="true"
android:paddingLeft="5dp"
android:textSize="20sp" />
</TableRow>
<TableRow
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:gravity="center_horizontal">
<TextView
android:layout_width="110dp"
android:layout_height="50dp"
android:gravity="center"
android:text="出生日期"
android:textSize="20dp" />
<LinearLayout
android:layout_width="200dp"
android:layout_height="50dp"
android:layout_gravity="center"
android:layout_marginLeft="10dp"
android:orientation="vertical">
<TextView
android:id="@+id/showDate"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/circle_shape_bg_2"
android:gravity="left|center"
android:paddingLeft="10dp"
android:textSize="20dp" />
</LinearLayout>
</TableRow>
<!-- <DatePicker-->
<!-- android:layout_width="wrap_content"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:layout_gravity="center"-->
<!-- android:calendarViewShown="false"-->
<!-- android:datePickerMode="spinner" />-->
<CheckBox
android:id="@+id/qq_space"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="70dp"
android:gravity="center"
android:text="同时开通QQ空间"
android:textColor="@color/gery_2"
android:textSize="18dp" />
<Button
android:id="@+id/button_ok"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="30dp"
android:background="@drawable/circle_shape_bg_blue"
android:drawableLeft="@drawable/qq_1"
android:paddingLeft="50dp"
android:paddingRight="50dp"
android:text="注册"
android:textSize="25dp" />
<TableRow
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="50dp"
android:gravity="center">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="注册即代表同意" />
<TextView
android:id="@+id/agreement"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="《用户隐私协议》"
android:textColor="@color/blue" />
</TableRow>
</LinearLayout>
3.找回密码
- 点击 验证码图片 自动更新,随机生成4位的验证码。
- 点击 “ 找回 ” 按钮后,会出现 “XXX不能为空”、“QQ账号不存在”(数据库没有该账号)、“两次密码不相同”、“验证码不正确” 等交互提示。
2. 密码找回页面 布局代码
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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="@drawable/bg_3"
android:gravity="center_horizontal"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="@color/gery_2"
android:paddingLeft="30dp"
android:paddingTop="50dp"
android:textSize="16dp"
android:text="忘记密码?--> 密码重置"/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="120dp"
android:src="@drawable/mmcz" />
<TableRow
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="30dp"
android:gravity="center_horizontal">
<TextView
android:layout_width="110dp"
android:layout_height="50dp"
android:gravity="center"
android:text="QQ账号"
android:textSize="20dp" />
<EditText
android:id="@+id/num"
android:layout_width="200dp"
android:layout_height="50dp"
android:layout_gravity="center"
android:layout_marginLeft="10dp"
android:background="@drawable/circle_shape_bg_2"
android:gravity="left|center"
android:maxLines="1"
android:singleLine="true"
android:paddingLeft="5dp"
android:textSize="20sp" />
</TableRow>
<TableRow
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:gravity="center_horizontal">
<TextView
android:layout_width="110dp"
android:layout_height="50dp"
android:gravity="center"
android:text="新密码"
android:textSize="20dp" />
<EditText
android:id="@+id/password"
android:layout_width="200dp"
android:layout_height="50dp"
android:layout_gravity="center"
android:layout_marginLeft="10dp"
android:background="@drawable/circle_shape_bg_2"
android:gravity="left|center"
android:inputType="textPassword"
android:maxLines="1"
android:singleLine="true"
android:paddingLeft="5dp"
android:textSize="20sp" />
</TableRow>
<TableRow
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:gravity="center_horizontal">
<TextView
android:layout_width="110dp"
android:layout_height="50dp"
android:gravity="center"
android:text="重复新密码"
android:textSize="20dp" />
<EditText
android:id="@+id/re_password"
android:layout_width="200dp"
android:layout_height="50dp"
android:layout_gravity="center"
android:layout_marginLeft="10dp"
android:background="@drawable/circle_shape_bg_2"
android:gravity="left|center"
android:inputType="textPassword"
android:maxLines="1"
android:singleLine="true"
android:paddingLeft="5dp"
android:textSize="20sp" />
</TableRow>
<TableRow
android:layout_width="310dp"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:gravity="center">
<TextView
android:layout_width="wrap_content"
android:layout_height="50dp"
android:paddingLeft="5dp"
android:text="验证码"
android:gravity="center_vertical"
android:textSize="20dp" />
<EditText
android:id="@+id/et_code_companyRe"
android:layout_width="wrap_content"
android:layout_height="50dp"
android:hint="请输入验证码"
android:maxLines="1"
android:singleLine="true"
android:textSize="20dp"
android:layout_weight="1"
android:gravity="center"
android:layout_marginLeft="15dp"
android:background="@null"/>
<ImageView
android:id="@+id/iv_code"
android:layout_width="100dp"
android:layout_height="50dp"
android:layout_alignParentRight="true"
android:layout_weight="1"
android:background="@drawable/yzm_bg"/>
</TableRow>
<Button
android:id="@+id/button_ok"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="150dp"
android:background="@drawable/circle_shape_bg_green"
android:drawableLeft="@drawable/qq_1"
android:paddingLeft="50dp"
android:paddingRight="50dp"
android:text="找回"
android:textSize="25dp" />
</LinearLayout>
4.部分交互
- 图一为 登录时,验证不成功的 错误提示。图二为 密码找回时,修改成功信息提示。
- 其他地方也多出用到。
5.登录后页面
1. 图为动态页面,与消息,联系人,看点均为Fragment。
2. 图为消息页面!!!
3. QQ状态效果。
4. 其他功能。
6.数据库
- 数据库,的用户表。
7.部分JAVA代码
1. 消息页面对应的JAVA代码:
package com.example.my_qq;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class NewsFragment extends Fragment {
ListView lvfriend;
//private TextView news_content;
String[] friend={"Moonlight","猴子","紫霞","赵子龙","唐伯虎"};
int[] head={R.drawable.head_5,
R.drawable.head_9,
R.drawable.head_10,
R.drawable.head_3,
R.drawable.head_8};
String[] news={"[ 特别关心 ] 我想你了","兄弟上号,晋级赛!!!",
"至尊宝是不是又喊你打游戏了?",
"“吾乃常山赵子龙”的意思就是爷爷是常山赵云。谦称赵云",
"出新诗了,要不要瞧瞧???"};
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.news_fragment, container,false);
return view;
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
//news_content = view.findViewById(R.id.news_content);
//news_content.setText("消息列表界面");
lvfriend= (ListView) view.findViewById(R.id.lvfriend);
SimpleAdapter listItemAdapter=new SimpleAdapter(
getActivity(), //这里要使用此,这样才不会报错。
getdata(),
R.layout.friend_item_layout,
new String[]{"friend","head","logo"},
new int[]{R.id.tvfriendname,R.id.ivhead,R.id.tvfriendlogo}
);
//控件与适配器绑定
lvfriend.setAdapter(listItemAdapter);
}
private List<Map<String,Object>> getdata() {
List<Map<String,Object>> list=new ArrayList<Map<String,Object>>();
for(int i=0;i<friend.length;i++)
{
Map<String,Object> map=new HashMap<String, Object>();
map.put("friend",friend[i]);
map.put("head",head[i]);
map.put("logo",news[i]);
list.add(map);
}
return list;
}
}
2. 数据库 的JAVA代码:
package com.example.my_qq;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import androidx.annotation.Nullable;
public class MyDatabase extends SQLiteOpenHelper {
static final String DBNAME="MY_QQ.db";//数据库名称
static final int VERSION=1;//版本号
static final String TBUSER="users";//用户表
static final String TBFRIEND="friends";//好友表
//修改构造函数
public MyDatabase(@Nullable Context context) {
super(context, DBNAME, null, VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
//创建用户表
db.execSQL("create table if not exists "+TBUSER+"(id integer not null primary key autoincrement," +
"num varchar(50)," +
"username varchar(50) not null," +
"sex varchar(2)," +
"password varchar(50), " +
"birthday varchar(60) " +
")");
//创建好友表
db.execSQL("create table if not exists "+TBFRIEND+"(id integer not null primary key autoincrement," +
"friendname varchar(50) not null," +
"logo varchar(50)," +
"head integer)");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
2. 数据库(操作) 的JAVA代码:
package com.example.my_qq;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
public class OperateDB {
MyDatabase myDatabase;
SQLiteDatabase db;
public OperateDB(Context context)
{
myDatabase=new MyDatabase(context);
db=myDatabase.getReadableDatabase();
}
//插入数据
public void insertDB(String insert)
{
db.execSQL(insert);
}
//删除数据
public void deleteDB(String delete)
{
db.execSQL(delete);
}
//修改数据
public void updateDB(String update)
{
db.execSQL(update);
}
//查询数据
public Cursor selectDB(String select)
{
return db.rawQuery(select,null);
}
//关闭数据库
public void closeDB()
{
if (db.isOpen())
{
db.close();
}
}
}
声明
- 部分功能的实现源于作者对网络视频的学习。
- 如过有问题可以留言,作者会及时同大家讨论、学习。
- 联系方式:。。。。。。。。(算了…)
8. BUG处理 及新功能更新
1. 修复
(1)登录后昵称无法显示
(2)注册时昵称、密码为空 。
代码片
//昵称不能为空
if(user_name.getText().toString().trim().equals("")) {
/*警告框*/
AlertDialog.Builder tips = new AlertDialog.Builder(RegisterActivity.this);
tips.setIcon(R.drawable.tips)
.setTitle("错误:")
.setMessage("昵称 不能为空")
.setPositiveButton("确定", null)
.show();
break;
}
//密码不能为空
if (pass_word.getText().toString().trim().equals("")) {
/*警告框*/
AlertDialog.Builder tips = new AlertDialog.Builder(RegisterActivity.this);
tips.setIcon(R.drawable.tips)
.setTitle("错误:")
.setMessage("密码 不能为空")
.setPositiveButton("确定", null)
.show();
break;
}
(3)同一账号,多次出现 。
代码片
//生成QQ账号
int num = (int) (Math.random() * 1000000000);
number = Integer.toString(num);
//生成查询语句 判断数据库是否已有该账号
String select_3 = "select num from " + MyDatabase.TBUSER +
" where num='" + number + "'";
Log.d("AAA", select_3);
// 创建数据库操作对象
OperateDB operateDB = new OperateDB(RegisterActivity.this);
Cursor cursor = operateDB.selectDB(select_3);//执行查询操作
if (!cursor.moveToNext()) {
num = (int) (Math.random() * 1000000000);
number = Integer.toString(num);
}
(4)部分机型无法适配。
代码片
使用 android:layout_weight="Integer" 进行布局
2. 新增
(1)注册时账号的重复判断。
(2)找回密码时旧密码验证功能。
(3)各页面状态栏进行了不同程度优化。
【为确保您能下载到最新资源 链接已经更新 请放心下载】
8. 源码下载
链接: https://download.csdn.net/download/qq_45711481/19406746.
9. 对应 .APK 文件下载
链接: https://download.csdn.net/download/qq_45711481/19406721.