android 仿微信demo————注册功能实现(移动端)
android 仿微信demo————微信启动界面实现
android 仿微信demo————注册功能实现(移动端)
android 仿微信demo————注册功能实现(服务端)
android 仿微信demo————登录功能实现(移动端)
android 仿微信demo————登录功能实现(服务端)
android 仿微信demo————微信主界面实现
android 仿微信demo————微信消息界面实现(移动端)
android 仿微信demo————微信消息界面实现(服务端)
android 仿微信demo————微信通讯录界面功能实现(移动端,服务端)
android 仿微信demo————微信发现界面实现
android 仿微信demo————微信顶部操作栏界面实现
android 仿微信demo————微信顶部操作栏搜索按钮实现(查询通讯录好友功能)
android 仿微信demo————微信顶部操作栏加号按钮实现(弹出子菜单)
源码获取点我,记得给个start哦
上一篇文章实现了微信启动界面,下面继续完善功能,编写微信移动端的注册功能
移动端注册功能实现
微信的注册界面每一个文本段都有下划线且默认颜色都是灰色,当其中一个文本段获取焦点会将下划线的颜色变为绿色,而且文本输入框的光标也是绿色的,还有在文本输入框没有全部输入的情况下,按钮是不能点击的,只有当文本输入框全部输入的情况下才能点击且此时按钮会变成绿色。除了这些UI功能外,当点击注册按钮是还会把表单数据发送给服务器
创建activity Reigister.java
activity Reigister.java
package com.example.wxchatdemo;import android.annotation.SuppressLint;
import android.content.Intent;
import android.graphics.Color;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.annotation.Nullable;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.Toast;import com.example.wxchatdemo.tools.IEditTextChangeListener;
import com.example.wxchatdemo.tools.RandomUserName;
import com.example.wxchatdemo.tools.WorksSizeCheckUtil;import org.json.JSONObject;import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.regex.Matcher;
import java.util.regex.Pattern;public class Reigister extends AppCompatActivity {//声明组件private EditText username;private EditText phone;private EditText password;private Button button;//随机微信号private String randomNumber;//自定义一个UI修改机制private MyHander myhander = new MyHander();@Overrideprotected void onCreate(@Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.register); //设置布局/* 隐藏自带标题*/ActionBar actionBar = getSupportActionBar();if (actionBar != null) {actionBar.hide();}if (Build.VERSION.SDK_INT >= 21) {View decorView = getWindow().getDecorView();int option = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN //全屏显示| View.SYSTEM_UI_FLAG_LAYOUT_STABLE| View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR; //因为背景为浅色所以将状态栏字体设置为黑色decorView.setSystemUiVisibility(option);getWindow().setStatusBarColor(Color.TRANSPARENT);}initViews(); // 初始化布局元素// 设置注册按钮是否可点击if (username.getText() + "" == "" || phone.getText() + "" == "" || password.getText() + "" == "") {button.setEnabled(false);} else {button.setEnabled(true);}inputFocus(); //监听EditView变色buttonChangeColor(); //监听登录按钮变色//button的点击事件事件button.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {/*判断输入的手机号格式对不对,对的话开一个线程完成网络请求操作*/Pattern pattern = Pattern.compile("^(13[0-9]|15[0-9]|153|15[6-9]|180|18[23]|18[5-9])\\d{8}$");Matcher matcher = pattern.matcher(phone.getText());if (matcher.matches()) {// 开一个线程完成网络请求操作new Thread(new Runnable() {@Overridepublic void run() {httpUrlConnPost(Reigister.this.username.getText() + "",phone.getText() + "", password.getText() + "");}}).start();} else {Toast.makeText(getApplicationContext(), "手机格式错误", Toast.LENGTH_LONG).show();}}});}/*在这里面获取到每个需要用到的控件的实例*/@SuppressLint("NewApi")public void initViews() {// 得到所有的组件username = (EditText) this.findViewById(R.id.reg_name);phone = (EditText) this.findViewById(R.id.reg_phone);password = (EditText) this.findViewById(R.id.reg_passwd);button = (Button) this.findViewById(R.id.reg_button);}/*监听EditView变色*/public void inputFocus() {username.setOnFocusChangeListener(new View.OnFocusChangeListener() {@Overridepublic void onFocusChange(View v, boolean hasFocus) {if (hasFocus) {// 此处为得到焦点时的处理内容ImageView imageView = (ImageView) findViewById(R.id.reg_diver1);imageView.setBackgroundResource(R.color.input_dvier_focus);} else {// 此处为失去焦点时的处理内容ImageView imageView = (ImageView) findViewById(R.id.reg_diver1);imageView.setBackgroundResource(R.color.input_dvier);}}});phone.setOnFocusChangeListener(new View.OnFocusChangeListener() {@Overridepublic void onFocusChange(View v, boolean hasFocus) {if (hasFocus) {// 此处为得到焦点时的处理内容ImageView imageView = (ImageView) findViewById(R.id.reg_diver2);imageView.setBackgroundResource(R.color.input_dvier_focus);} else {// 此处为失去焦点时的处理内容ImageView imageView = (ImageView) findViewById(R.id.reg_diver2);imageView.setBackgroundResource(R.color.input_dvier);}}});password.setOnFocusChangeListener(new View.OnFocusChangeListener() {@Overridepublic void onFocusChange(View v, boolean hasFocus) {if (hasFocus) {// 此处为得到焦点时的处理内容ImageView imageView = (ImageView) findViewById(R.id.reg_diver3);imageView.setBackgroundResource(R.color.input_dvier_focus);} else {// 此处为失去焦点时的处理内容ImageView imageView = (ImageView) findViewById(R.id.reg_diver3);imageView.setBackgroundResource(R.color.input_dvier);}}});}/*监听登录按钮变色*/public void buttonChangeColor() {//创建工具类对象 把要改变颜色的Button先传过去WorksSizeCheckUtil.textChangeListener textChangeListener = new WorksSizeCheckUtil.textChangeListener(button);textChangeListener.addAllEditText(username, phone, password);//把所有要监听的EditText都添加进去//接口回调 在这里拿到boolean变量 根据isHasContent的值决定 Button应该设置什么颜色WorksSizeCheckUtil.setChangeListener(new IEditTextChangeListener() {@Overridepublic void textChange(boolean isHasContent) {if (isHasContent) {button.setBackgroundResource(R.drawable.login_button_focus);button.setTextColor(getResources().getColor(R.color.loginButtonTextFouse));} else {button.setBackgroundResource(R.drawable.login_button_shape);button.setTextColor(getResources().getColor(R.color.loginButtonText));}}});}/*发送请求的主要方法*/public void httpUrlConnPost(String name, String phone, String password) {/*使用工具类生成随机的微信号*/RandomUserName ran = new RandomUserName();randomNumber = ran.generate();HttpURLConnection urlConnection = null;URL url;try {// 请求的URL地地址url = new URL("http://100.2.178.10:8080/AndroidServer_war_exploded/Reigister");urlConnection = (HttpURLConnection) url.openConnection();// 打开http连接urlConnection.setConnectTimeout(3000);// 连接的超时时间urlConnection.setUseCaches(false);// 不使用缓存// urlConnection.setFollowRedirects(false);是static函数,作用于所有的URLConnection对象。urlConnection.setInstanceFollowRedirects(true);// 是成员函数,仅作用于当前函数,设置这个连接是否可以被重定向urlConnection.setReadTimeout(3000);// 响应的超时时间urlConnection.setDoInput(true);// 设置这个连接是否可以写入数据urlConnection.setDoOutput(true);// 设置这个连接是否可以输出数据urlConnection.setRequestMethod("POST");// 设置请求的方式urlConnection.setRequestProperty("Content-Type","application/json;charset=UTF-8");// 设置消息的类型urlConnection.connect();// 连接,从上述至此的配置必须要在connect之前完成,实际上它只是建立了一个与服务器的TCP连接JSONObject json = new JSONObject();// 创建json对象json.put("number", URLEncoder.encode(randomNumber, "UTF-8"));// 使用URLEncoder.encode对特殊和不可见字符进行编码json.put("name", URLEncoder.encode(name, "UTF-8"));json.put("phone", URLEncoder.encode(phone, "UTF-8"));json.put("password", URLEncoder.encode(password, "UTF-8"));// 把数据put进json对象中String jsonstr = json.toString();// 把JSON对象按JSON的编码格式转换为字符串// ------------字符流写入数据------------OutputStream out = urlConnection.getOutputStream();// 输出流,用来发送请求,http请求实际上直到这个函数里面才正式发送出去BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(out));// 创建字符流对象并用高效缓冲流包装它,便获得最高的效率,发送的是字符串推荐用字符流,其它数据就用字节流bw.write(jsonstr);// 把json字符串写入缓冲区中bw.flush();// 刷新缓冲区,把数据发送出去,这步很重要out.close();bw.close();// 使用完关闭Log.i("aa", urlConnection.getResponseCode() + "");//以下判斷是否訪問成功,如果返回的状态码是200则说明访问成功if (urlConnection.getResponseCode() == HttpURLConnection.HTTP_OK) {// 得到服务端的返回码是否连接成功// ------------字符流读取服务端返回的数据------------InputStream in = urlConnection.getInputStream();BufferedReader br = new BufferedReader(new InputStreamReader(in));String str = null;StringBuffer buffer = new StringBuffer();while ((str = br.readLine()) != null) {// BufferedReader特有功能,一次读取一行数据buffer.append(str);}in.close();br.close();JSONObject rjson = new JSONObject(buffer.toString());Log.i("aa", "rjson=" + rjson);// rjson={"json":true}boolean result = rjson.getBoolean("json");// 从rjson对象中得到key值为"json"的数据,这里服务端返回的是一个boolean类型的数据System.out.println("json:===" + result);//如果服务器端返回的是true,则说明注册成功,否则注册失败if (result) {// 判断结果是否正确//在Android中http请求,必须放到线程中去作请求,但是在线程中不可以直接修改UI,只能通过hander机制来完成对UI的操作myhander.sendEmptyMessage(1);Log.i("用户:", "注册成功");} else {myhander.sendEmptyMessage(2);Log.i("用户:", "手机号已被注册");}} else {myhander.sendEmptyMessage(2);}} catch (Exception e) {e.printStackTrace();Log.i("aa", e.toString());myhander.sendEmptyMessage(2);} finally {urlConnection.disconnect();// 使用完关闭TCP连接,释放资源}}// 在Android中不可以在线程中直接修改UI,只能借助Handler机制来完成对UI的操作class MyHander extends Handler {@Overridepublic void handleMessage(Message msg) {super.handleMessage(msg);//判断hander的内容是什么,如果是1则说明注册成功,如果是2说明注册失败switch (msg.what) {case 1:Log.i("aa", msg.what + "");Toast.makeText(getApplicationContext(), "注册成功",Toast.LENGTH_SHORT).show();/*跳转到登录页面并把微信号也传过去*/Intent intent = new Intent();intent.putExtra("weixin_number", randomNumber);intent.setClass(com.example.wxchatdemo.Reigister.this, LoginUser.class);startActivity(intent);com.example.wxchatdemo.Reigister.this.finish(); //结束当前activitybreak;case 2:Log.i("aa", msg.what + "");//這是一個提示消息Toast.makeText(getApplicationContext(), "手机号已被注册", Toast.LENGTH_LONG).show();}}}//返回按钮处理事件public void rigister_activity_back(View v) {/*跳转到微信启动页*/Intent intent = new Intent();intent.setClass(com.example.wxchatdemo.Reigister.this, Welcome.class);startActivity(intent);com.example.wxchatdemo.Reigister.this.finish(); //结束当前activity}
}
上面用到的两个工具类和一个接口,其中一个工具类是监听按钮变色的,是上面接口的实现类(用到面向接口编程思想,把接口作为自己的成员变量,实现接口回调)另一个工具类是随机生成微信号,代码就不全阐述了,注释都有说明,主要讲一下生成微信号的工具类
生成随机微信号工具类:
注册微信时系统会给我们随机生成一个微信号且不能重复的,所以上面用一个工具类RandomUserName(),通过调用generate()方法可以返回一个随机的微信号(封装的细节就不说了,等下后面附上工具类代码都有注释。这个功能应该是在服务端实现的,我懒,所以简单在移动端搞了),然后和注册表单一起发给服务器
在创建工具类接口之前,可以先创建一个存放工具类和接口的包,因为后面会继续完善微信功能时会创建很多工具类,方便管理
创建存放工具类和接口包
创建监听按钮变色工具类WorksSizeCheckUtil.java
WorksSizeCheckUtil.java
package com.example.wxchatdemo.tools;import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.widget.Button;
import android.widget.EditText;public class WorksSizeCheckUtil {static IEditTextChangeListener mChangeListener;public static void setChangeListener(IEditTextChangeListener changeListener) {mChangeListener = changeListener;}//检测输入框是否都输入了内容 从而改变按钮的是否可点击public static class textChangeListener {private Button button;private EditText[] editTexts;public textChangeListener(Button button) {this.button = button;}public textChangeListener addAllEditText(EditText... editTexts) {this.editTexts = editTexts;initEditListener();return this;}private void initEditListener() {//调用了遍历editext的方法for (EditText editText : editTexts) {editText.addTextChangedListener(new textChange());}}// edit输入的变化来改变按钮的是否点击private class textChange implements TextWatcher {@Overridepublic void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {}@Overridepublic void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {if (checkAllEdit()) {//所有EditText有值了mChangeListener.textChange(true);button.setEnabled(true);} else {//所有EditText值为空button.setEnabled(false);mChangeListener.textChange(false);}}@Overridepublic void afterTextChanged(Editable editable) {}}//检查所有的edit是否输入了数据private boolean checkAllEdit() {for (EditText editText : editTexts) {if (!TextUtils.isEmpty(editText.getText() + "")) {continue;} else {return false;}}return true;}}
}
创建对应的接口IEditTextChangeListener.java
IEditTextChangeListener.java
package com.example.wxchatdemo.tools;public interface IEditTextChangeListener {void textChange(boolean isHasContent);
}
创建随机生成微信号的工具类RandomUserName.java
RandomUserName.java
package com.example.wxchatdemo.tools;import java.util.Random;public class RandomUserName {private static final char[] eng_char = new char[]{'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};private static final String[] first_name = new String[]{"zhao","qian","sun","li","zhou","wang","wu","zheng","feng","chen","chu","wei","jiang","shen","yang","zhu","qin","you","xu","he","shi","zhan","kong","cao","xie","jin","shu","fang","yuan"};private static final String[] tel_head = new String[]{"13","18","15"};private static final String[] email_suffix = new String[]{"@gmail.com","@yahoo.com","@msn.com","@hotmail.com","@aol.com","@ask.com","@live.com","@qq.com","@0355.net","@163.com","@163.net","@263.net","@3721.net","@yeah.net","@googlemail.com","@126.com","@sina.com","@sohu.com","@yahoo.com.cn"};private Random random = new Random();public String generate(){StringBuilder uName = new StringBuilder();int randomType = random.nextInt(Integer.MAX_VALUE)%3;switch (randomType) {case 0: // firstName + randomSecName + birthdayuName.append(first_name[random.nextInt(Integer.MAX_VALUE)%first_name.length]).append(eng_char[random.nextInt(Integer.MAX_VALUE)%eng_char.length]);if(random.nextInt(Integer.MAX_VALUE)%2 == 0){uName.append(eng_char[random.nextInt(Integer.MAX_VALUE)%eng_char.length]);}// birthdayif(random.nextInt(Integer.MAX_VALUE)%2 == 0){uName.append(String.valueOf(2014 - (random.nextInt(Integer.MAX_VALUE)%(50-15) + 15))); // 大于15小于50岁}if(random.nextInt(Integer.MAX_VALUE)%2 == 0){int month = random.nextInt(Integer.MAX_VALUE)%11 + 1;int day = random.nextInt(Integer.MAX_VALUE)%29 + 1;if(month < 10)uName.append("0");uName.append(month);if(day < 10)uName.append("0");uName.append(day);}if(random.nextInt(Integer.MAX_VALUE%4) == 0){// add email suffix , 1/4 rateuName.append(email_suffix[random.nextInt(Integer.MAX_VALUE)%email_suffix.length]);}break;case 1: // teluName.append(tel_head[random.nextInt(Integer.MAX_VALUE)%tel_head.length]).append(random.nextInt(Integer.MAX_VALUE)%10).append(random.nextInt(Integer.MAX_VALUE)%10).append(random.nextInt(Integer.MAX_VALUE)%10).append(random.nextInt(Integer.MAX_VALUE)%10).append(random.nextInt(Integer.MAX_VALUE)%10).append(random.nextInt(Integer.MAX_VALUE)%10).append(random.nextInt(Integer.MAX_VALUE)%10).append(random.nextInt(Integer.MAX_VALUE)%10).append(random.nextInt(Integer.MAX_VALUE)%10);break;case 2: // qquName.append(random.nextInt(Integer.MAX_VALUE)%9+1).append(random.nextInt(Integer.MAX_VALUE)%10).append(random.nextInt(Integer.MAX_VALUE)%10).append(random.nextInt(Integer.MAX_VALUE)%10).append(random.nextInt(Integer.MAX_VALUE)%10);int lenth = 0;while(random.nextInt(Integer.MAX_VALUE)%2 == 0){if(lenth > 6)break;uName.append(random.nextInt(Integer.MAX_VALUE)%10);lenth ++;}break;default:break;}return uName.toString();}
}
创建两个shapre文件,自定义按钮形状,实现按钮在所有文本框获取输入时显示的背景和至少有一个没有输入情况下显示的背景
按钮在所以文本框获取输入时显示的shapre文件login_button_focus.xml
login_button_focus.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"><solid android:color="@color/loginButtonBackgroundFouse" /><!-- 填充的颜色 --><!-- 设置按钮的四个角为弧形 --><!-- android:radius 弧形的半径 --><cornersandroid:bottomLeftRadius="6dp"android:bottomRightRadius="6dp"android:topLeftRadius="6dp"android:topRightRadius="6dp" /><!-- 边框粗细及颜色 -->
</shape>
按钮在所以文本框至少有一个没有获取输入时显示的shapre文件login_button_shape.xml
login_button_shape.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"><solid android:color="@color/loginButtonBackgroundNotFouse" /><!-- 填充的颜色 --><!-- 设置按钮的四个角为弧形 --><!-- android:radius 弧形的半径 --><cornersandroid:bottomLeftRadius="6dp"android:bottomRightRadius="6dp"android:topLeftRadius="6dp"android:topRightRadius="6dp" /><!-- 边框粗细及颜色 -->
</shape>
创建activity Reigister.java对应的布局文件reigister.xml
reigister.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:background="@color/title"android:orientation="vertical"><ImageViewandroid:layout_width="17dp"android:layout_height="17dp"android:layout_marginLeft="20dp"android:layout_marginTop="45dp"android:onClick="rigister_activity_back"android:src="@drawable/backpay" /><TextViewandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginLeft="30dp"android:layout_marginTop="25dp"android:text="手机号注册"android:textColor="@color/loginText"android:textSize="25sp" /><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginTop="40dp"><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginLeft="30dp"android:text="昵称"android:textColor="@color/loginText"android:textSize="16sp" /><EditTextandroid:id="@+id/reg_name"android:layout_width="200dp"android:layout_height="wrap_content"android:layout_marginLeft="55dp"android:background="@null"android:hint="例如:陈晨"android:singleLine="true"android:textColorHint="@color/textColorHint"android:textCursorDrawable="@drawable/edit_cursor_color"android:textSize="16sp" /></LinearLayout><ImageViewandroid:id="@+id/reg_diver1"android:layout_width="320dp"android:layout_height="1dp"android:layout_gravity="center_horizontal"android:layout_marginTop="17dp"android:background="@color/input_dvier" /><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginTop="20dp"><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginLeft="30dp"android:text="手机号"android:textColor="@color/loginText"android:textSize="16sp" /><EditTextandroid:id="@+id/reg_phone"android:layout_width="200dp"android:layout_height="wrap_content"android:layout_marginLeft="36dp"android:background="@null"android:hint="请填写手机号"android:singleLine="true"android:textColorHint="@color/textColorHint"android:textCursorDrawable="@drawable/edit_cursor_color"android:textSize="16sp" /></LinearLayout><ImageViewandroid:id="@+id/reg_diver2"android:layout_width="320dp"android:layout_height="1dp"android:layout_gravity="center_horizontal"android:layout_marginTop="17dp"android:background="@color/input_dvier" /><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginTop="20dp"><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginLeft="30dp"android:text="密码"android:textColor="@color/loginText"android:textSize="16sp" /><EditTextandroid:id="@+id/reg_passwd"android:layout_width="200dp"android:layout_height="wrap_content"android:layout_marginLeft="55dp"android:background="@null"android:hint="请填写密码"android:password="false"android:singleLine="true"android:textColorHint="@color/textColorHint"android:textCursorDrawable="@drawable/edit_cursor_color"android:textSize="16sp" /></LinearLayout><ImageViewandroid:id="@+id/reg_diver3"android:layout_width="320dp"android:layout_height="1dp"android:layout_gravity="center_horizontal"android:layout_marginTop="17dp"android:background="@color/input_dvier" /><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginTop="40dp"android:gravity="center_horizontal"><Buttonandroid:id="@+id/reg_button"android:layout_width="321dp"android:layout_height="48dp"android:background="@drawable/login_button_shape"android:text="注册"android:textColor="@color/loginButtonText"android:textSize="16sp" /></LinearLayout></LinearLayout>
创建shape文件edit_cursor_color.xml,自定义光标颜色
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"android:shape="rectangle" ><size android:width="1dp" /><size android:height="10dp"/><solid android:color="@color/loginButtonBackgroundFouse" />
</shape>
在colors.xml文件中声明所用到颜色
colors.xml
<color name="input_dvier">#D8D8D8</color><color name="input_dvier_focus">#1BB879</color><color name="loginButtonText">#B5B2B2</color><color name="loginButtonTextFouse">#FFFFFF</color><color name="loginButtonBackgroundFouse">#07C160</color><color name="loginButtonBackgroundNotFouse">#D4D8D5</color><color name="title">#EDEDED</color><color name="loginText">#5A5959</color><color name="textColorHint">#DDDDDD</color>
在AndroidMainfest.xml中声明注册activity
测试
虽然服务器代码还没实现,但是还是可以测试相应功能,先把注册成功后跳转到登录页面的那段代码注释点
然后再上篇微信启动页实现文章中的activity Welcome.java注册按钮点击后跳转的activity代码注释取消掉
启动项目测试
虽然输入正确的手机号格式,但是服务器功能还没实现,所以不论怎样输入手机号都会出现手机号已被注册,因为把请求服务器出现错误时执行的代码段写了手机号已被注册的提示,这样做的原因是服务器出现错误就是手机号重复了。
android 仿微信demo————注册功能实现(移动端)相关推荐
- android 仿微信demo————注册功能实现(服务端)
android 仿微信demo----微信启动界面实现 android 仿微信demo----注册功能实现(移动端) android 仿微信demo----注册功能实现(服务端) android 仿微 ...
- android 仿微信demo————注册功能完善添加头像功能(服务端)
android 仿微信demo----微信启动界面实现 android 仿微信demo----注册功能实现(移动端) android 仿微信demo----注册功能实现(服务端) android 仿微 ...
- android 仿微信demo————注册功能完善添加头像功能(移动端)
android 仿微信demo----微信启动界面实现 android 仿微信demo----注册功能实现(移动端) android 仿微信demo----注册功能实现(服务端) android 仿微 ...
- android 仿微信demo————登录功能实现(服务端)
android 仿微信demo----微信启动界面实现 android 仿微信demo----注册功能实现(移动端) android 仿微信demo----注册功能实现(服务端) android 仿微 ...
- android 仿微信demo————登录功能实现(移动端)
android 仿微信demo----微信启动界面实现 android 仿微信demo----注册功能实现(移动端) android 仿微信demo----注册功能实现(服务端) android 仿微 ...
- android 仿微信demo————微信通讯录界面功能实现(移动端,服务端)
android 仿微信demo----微信启动界面实现 android 仿微信demo----注册功能实现(移动端) android 仿微信demo----注册功能实现(服务端) android 仿微 ...
- android 仿微信demo————微信主界面实现
android 仿微信demo----微信启动界面实现 android 仿微信demo----注册功能实现(移动端) android 仿微信demo----注册功能实现(服务端) android 仿微 ...
- android 仿微信demo————微信发现界面实现
android 仿微信demo----微信启动界面实现 android 仿微信demo----注册功能实现(移动端) android 仿微信demo----注册功能实现(服务端) android 仿微 ...
- android 仿微信demo————微信消息界面实现(移动端)
android 仿微信demo----微信启动界面实现 android 仿微信demo----注册功能实现(移动端) android 仿微信demo----注册功能实现(服务端) android 仿微 ...
- android 仿微信demo————微信消息界面实现(服务端)
android 仿微信demo----微信启动界面实现 android 仿微信demo----注册功能实现(移动端) android 仿微信demo----注册功能实现(服务端) android 仿微 ...
最新文章
- ADO与ADO.NET的区别与介绍
- gis怎么通过水库划分子流域_到底是谁在革GIS的命?
- PHP、C#、通用的DES加密
- 随想录(从开源的宝库中学习)
- Spring3 MVC注解Hello World
- C++:STL之vector,deque对比
- android实现Materia Design风格APP(六):结束,实现APP
- [转] 如何快速掌握一门新技术/语言/框架
- 移动安全初探:窃取微信聊天记录、Hacking Android with Metasploit
- oracle中的中文排序,Oracle下的中文排序
- 蚂蚁金服是如何提高移动端体验的?
- 升级mac系统正在计算机,苹果笔记本系统升级_苹果电脑Mac系统怎么升级
- Cadence OrCAD Capture CIS 输出带属性的PDF原理图
- LOJ #10008. 「一本通 1.1 练习 4」家庭作业
- Debian如何更换apt源
- 电子作业票系统:消除安全管理漏洞,科技赋能企业业务洞察
- 【深度学习小常识】什么是mAP?
- JavaCV依赖精简
- VSCode 的安装与配置
- 支付宝、微信小程序高频知识(汇总VS对比)
热门文章
- HTML表格循环中合并单元格,table循环实现表格相同列合并
- 【JAVA】JSON随机值生成工具类
- python编写收入支出明细程序_PHP编程之收入支出明细表实现技术
- Java实现通过证书访问Https请求
- Caused by: java.security.NoSuchAlgorithmException: SunTlsRsaPremasterSecret KeyGenerator not availab
- python 排列 组合_python实现排列和组合
- 5 款非常好用的AI在线图片处理工具
- 用计算机和电视机组成家庭影院,用电脑组建家庭影院: 最方便最实惠的玩法...
- 电脑ping,电脑ping如何打开 电脑ping打开教程
- 装机必备的浏览器推荐,干净好用,选这4款不会出错