Android实现登录、注册、数据库操作---才想起来,忘了吃中午饭了

       写在最前面的话:有同学直接复制我的代码,可是需要复制的太多,觉得Gradle那些文件和自己的都差不多,就不复制了,结果运行报错,来找我,我能说啥?这些代码都是我挨个写注释,挨个复制到CSDN的,你想运行出来效果,就不要怕费力气,把我让你复制的都复制一下,我是个实用主义的人,不需要复制的我是不会给你的。尽管这篇文章很长,但是我觉得这是学习开发必走的路。我之所以没有上传一个压缩包,是想让你们通过挨个复制,来了解一下Android开发的结构,你如果耐不住性子,那么,不好意思,请找个空气新鲜的地方深呼吸,然后回来强迫自己耐住性子。

                                                                                                记于2018/6/24 23:45

--------------------------------------------------------------------------------------------------------------------------------

         忙着敲代码,忙着忙着就忘了吃中午饭了,两点半了才想起来,下不为例!

        这一篇我写的是用Android实现登录、注册、数据库操作的相关内容。

先放最终效果图:





如果你不想看我胡扯只要代码,请直接跳到文字下面,先声明一下我的AndroidStudio的版本是:

扫描二维码关注公众号,回复: 2231327 查看本文章


          是时候写正文了!

          首先,当我们用AndroidStudio运行写好的Android程序的时候,也就是说,当按下那个绿色的小三角,启动小手机的时候,整个AndroidStudio会发生什么事情?这件事重要到,不搞清楚就学不会Android编程的地步。

                                                                 

  


        没错,就是你看到的这两个图标,折磨你到半死不活的两个玩意。

        当你熬到深夜两点,拖着疲惫的身躯敲完最后一行代码,颤颤巍巍的右手握着鼠标,眯瞪着双眼瞄准绿色的小三角,用尽平生最后一丝力气狠狠地单击一下鼠标左键 ,然后整个人葛优瘫在键盘上等待着它的运行,它到底发生了什么事情?这一切的背后,是人性的扭曲还是道德的沦丧?啊呸,重来。这一切的背后,是怎样的逻辑结构和运行原理?

        注:本文中的“它”指代“AndroidStudio”

        我尽我最大的努力来阐释一下我对此过程的拙见。

        首先看一下我这个Android程序的三级目录


        我已经标注好顺序了 0 → 1 → 2 → 3 → 4 总共5步

        步骤 0 :编译,具体Gradle是个啥,我也不清楚,我只知道Android是用Gradle进行编译的,编译的过程它会

                    一、检查Gradle自身程序是否可用或版本是否最新

                   二、启动各种我们桌面上看不见的程序,如果我没猜错的话,Gradle和Java、Python都差不多,大概就是一些java.exe、javac.exe之类的

                     三、匹配各种依赖项,存在的检查完整性,不存在的去指定网站下载

        步骤 1 :解析注册XML,AndroidManifest.xml在Android中的作用和Windows中的注册表类似,每个Activity.java都需要去注册,而且里面有MAIN和LAUNCH设置,MAIN是:主要、入口的意思;LAUNCH是:启动、加载的意思。也就是说,AndroidManifest.xml是个导游,告诉AndroidStudio从哪开始运行,都有什么大致内容。

        步骤 2 :运行Activity,所谓Activity 翻译为 :活动、界面  一个Activity就是一个运行界面,AndroidStudio会启动在AndroidManifest.xml中被设置为 MAIN和LAUNCH 的Activity。首页启动之后,就是各个Activity之间的跳转通信了。

         步骤 3 :解析布局XML,在每个Activity创建(onCreate)时都会加载自己的xml布局文件,这些xml布局文件定义了对应Activity长什么样子。

         步骤 4: 解析完布局XML后,每个Activity的模样就确定了,然后就会返回Activity中执行类似响应点击、滑动之类的操作的代码

        

          GameOver ! ! Talk is cheap,Show me your code.我把代码按照我上面发的目录树的顺序粘贴一下。

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.justloginregistertest">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".loginActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name=".RegisterActivity"></activity>
        <activity android:name=".MainActivity"></activity>
    </application>

</manifest>

Code.java

package com.example.justloginregistertest;

import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;

import java.util.Random;

/**
 * Created by littlecurl 2018/6/24
 */

public class Code {
    /**
     * 随机数数组
     * 去除了易混淆的 数字 0 和 字母 o O
     *                数字 1 和 字母 i I l L
     *                数字 6 和 字母 b
     *                数字 9 和 字母 q
     *                字母 c C 和 G
     *                字母 t (经常和随机线混在一起看不清)
     */
    private static final char[] CHARS = {
            '2', '3', '4', '5',  '7', '8',
            'a',  'd', 'e', 'f', 'g', 'h', 'j', 'k', 'm',
            'n', 'p',  'r', 's',  'u', 'v', 'w', 'x', 'y', 'z',
            'A', 'B',  'D', 'E', 'F',  'H',  'J', 'K', 'M',
            'N', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'
    };

    private static Code bmpCode;

    public static Code getInstance() {
        if(bmpCode == null)
            bmpCode = new Code();
        return bmpCode;
    }

    //default settings
    //验证码默认随机数的个数
    private static final int DEFAULT_CODE_LENGTH = 4;
    //默认字体大小
    private static final int DEFAULT_FONT_SIZE = 25;
    //默认线条的条数
    private static final int DEFAULT_LINE_NUMBER = 5;
    //padding值
    private static final int BASE_PADDING_LEFT = 10, RANGE_PADDING_LEFT = 15, BASE_PADDING_TOP = 15, RANGE_PADDING_TOP = 20;
    //验证码的默认宽高
    private static final int DEFAULT_WIDTH = 100, DEFAULT_HEIGHT = 40;

    //settings decided by the layout xml
    //canvas width and height
    private int width = DEFAULT_WIDTH, height = DEFAULT_HEIGHT;

    //random word space and pading_top
    private int base_padding_left = BASE_PADDING_LEFT, range_padding_left = RANGE_PADDING_LEFT,
            base_padding_top = BASE_PADDING_TOP, range_padding_top = RANGE_PADDING_TOP;

    //number of chars, lines; font size
    private int codeLength = DEFAULT_CODE_LENGTH, line_number = DEFAULT_LINE_NUMBER, font_size = DEFAULT_FONT_SIZE;

    //variables
    private String code;
    private int padding_left, padding_top;
    private Random random = new Random();
    //验证码图片
    public Bitmap createBitmap() {
        padding_left = 0;

        Bitmap bp = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
        Canvas c = new Canvas(bp);

        code = createCode();

        c.drawColor(Color.WHITE);
        Paint paint = new Paint();
        paint.setAntiAlias(true);
        paint.setTextSize(font_size);
        //画验证码
        for (int i = 0; i < code.length(); i++) {
            randomTextStyle(paint);
            randomPadding();
            c.drawText(code.charAt(i) + "", padding_left, padding_top, paint);
        }
        //画线条
        for (int i = 0; i < line_number; i++) {
            drawLine(c, paint);
        }

        c.save( Canvas.ALL_SAVE_FLAG );//保存
        c.restore();//
        return bp;
    }

    public String getCode() {
        return code;
    }

    //生成验证码
    private String createCode() {
        StringBuilder buffer = new StringBuilder();
        for (int i = 0; i < codeLength; i++) {
            buffer.append(CHARS[random.nextInt(CHARS.length)]);
        }
        return buffer.toString();
    }
    //画干扰线
    private void drawLine(Canvas canvas, Paint paint) {
        int color = randomColor();
        int startX = random.nextInt(width);
        int startY = random.nextInt(height);
        int stopX = random.nextInt(width);
        int stopY = random.nextInt(height);
        paint.setStrokeWidth(1);
        paint.setColor(color);
        canvas.drawLine(startX, startY, stopX, stopY, paint);
    }
    //生成随机颜色
    private int randomColor() {
        return randomColor(1);
    }

    private int randomColor(int rate) {
        int red = random.nextInt(256) / rate;
        int green = random.nextInt(256) / rate;
        int blue = random.nextInt(256) / rate;
        return Color.rgb(red, green, blue);
    }
    //随机生成文字样式,颜色,粗细,倾斜度
    private void randomTextStyle(Paint paint) {
        int color = randomColor();
        paint.setColor(color);
        paint.setFakeBoldText(random.nextBoolean());  //true为粗体,false为非粗体
        float skewX = random.nextInt(11) / 10;
        skewX = random.nextBoolean() ? skewX : -skewX;
        paint.setTextSkewX(skewX); //float类型参数,负数表示右斜,整数左斜
        //paint.setUnderlineText(true); //true为下划线,false为非下划线
        //paint.setStrikeThruText(true); //true为删除线,false为非删除线
    }
    //随机生成padding值
    private void randomPadding() {
        padding_left += base_padding_left + random.nextInt(range_padding_left);
        padding_top = base_padding_top + random.nextInt(range_padding_top);
    }
}

DBOpenHelper.java

package com.example.justloginregistertest;

import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

import java.util.ArrayList;
/**
 * Created by littlecurl 2018/6/24
 */

public class DBOpenHelper extends SQLiteOpenHelper {
    /**
     * 声明一个AndroidSDK自带的数据库变量db
     */
    private SQLiteDatabase db;

    /**
     * 写一个这个类的构造函数,参数为上下文context,所谓上下文就是这个类所在包的路径
     * 指明上下文,数据库名,工厂默认空值,版本号默认从1开始
     * super(context,"db_test",null,1);
     * 把数据库设置成可写入状态,除非内存已满,那时候会自动设置为只读模式
     * 不过,以现如今的内存容量,估计一辈子也见不到几次内存占满的状态
     * db = getReadableDatabase();
     */
    public DBOpenHelper(Context context){
        super(context,"db_test",null,1);
        db = getReadableDatabase();
    }

    /**
     * 重写两个必须要重写的方法,因为class DBOpenHelper extends SQLiteOpenHelper
     * 而这两个方法是 abstract 类 SQLiteOpenHelper 中声明的 abstract 方法
     * 所以必须在子类 DBOpenHelper 中重写 abstract 方法
     * 想想也是,为啥规定这么死必须重写?
     * 因为,一个数据库表,首先是要被创建的,然后免不了是要进行增删改操作的
     * 所以就有onCreate()、onUpgrade()两个方法
     * @param db
     */
    @Override
    public void onCreate(SQLiteDatabase db){
        db.execSQL("CREATE TABLE IF NOT EXISTS user(" +
                "_id INTEGER PRIMARY KEY AUTOINCREMENT," +
                "name TEXT," +
                "password TEXT)");
    }
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion){
        db.execSQL("DROP TABLE IF EXISTS user");
        onCreate(db);
    }
    /**
     * 接下来写自定义的增删改查方法
     * 这些方法,写在这里归写在这里,以后不一定都用
     * add()
     * delete()
     * update()
     * getAllData()
     */
    public void add(String name,String password){
        db.execSQL("INSERT INTO user (name,password) VALUES(?,?)",new Object[]{name,password});
    }
    public void delete(String name,String password){
        db.execSQL("DELETE FROM user WHERE name = AND password ="+name+password);
    }
    public void updata(String password){
        db.execSQL("UPDATE user SET password = ?",new Object[]{password});
    }

    /**
     * 前三个没啥说的,都是一套的看懂一个其他的都能懂了
     * 下面重点说一下查询表user全部内容的方法
     * 我们查询出来的内容,需要有个容器存放,以供使用,
     * 所以定义了一个ArrayList类的list
     * 有了容器,接下来就该从表中查询数据了,
     * 这里使用游标Cursor,这就是数据库的功底了,
     * 在Android中我就不细说了,因为我数据库功底也不是很厚,
     * 但我知道,如果需要用Cursor的话,第一个参数:"表名",中间5个:null,
     *                                                     最后是查询出来内容的排序方式:"name DESC"
     * 游标定义好了,接下来写一个while循环,让游标从表头游到表尾
     * 在游的过程中把游出来的数据存放到list容器中
     * @return
     */
    public ArrayList<User> getAllData(){

        ArrayList<User> list = new ArrayList<User>();
        Cursor cursor = db.query("user",null,null,null,null,null,"name DESC");
        while(cursor.moveToNext()){
            String name = cursor.getString(cursor.getColumnIndex("name"));
            String password = cursor.getString(cursor.getColumnIndex("password"));
            list.add(new User(name,password));
        }
        return list;
    }
}

loginActivity.java

package com.example.justloginregistertest;
/**
 * 纯粹实现登录注册功能,其它功能都被注释掉了
 * 起作用的代码(连带着packag、import算上) 共 73 行
 * 不多吧?
 */

import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.text.TextUtils;
import android.view.View;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
import java.util.ArrayList;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
/**
 * Created by littlecurl 2018/6/24
 */
public class loginActivity extends AppCompatActivity {
    /**
     * 声明自己写的 DBOpenHelper 对象
     *  DBOpenHelper(extends SQLiteOpenHelper) 主要用来
     * 创建数据表
     * 然后再进行数据表的增、删、改、查操作
     */
    private DBOpenHelper mDBOpenHelper;
    /**
     *创建 Activity 时先来重写 onCreate() 方法
     * 保存实例状态
     * super.onCreate(savedInstanceState);
     * 设置视图内容的配置文件
     * setContentView(R.layout.activity_login);
     * 上面这行代码真正实现了把视图层 View 也就是 layout 的内容放到 Activity 中进行显示
     * 将开源库ButterKnife应用到此上下文,这个开源库的规定用法
     * ButterKnife.bind(this);
     * 实例化 DBOpenHelper,待会进行登录验证的时候要用来进行数据查询
     * mDBOpenHelper = new DBOpenHelper(this);
     */
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);
        ButterKnife.bind(this);
        mDBOpenHelper = new DBOpenHelper(this);
    }
    /**
     * onCreae()中大的布局已经摆放好了,接下来就该把layout里的东西
     * 声明、实例化对象然后有行为的赋予其行为
     * 这样就可以把视图层View也就是layout 与 控制层 Java 结合起来了
     * <p>
     * 这里使用注解的方式注入View,可以不再写findViewById了
     * 我认为这样的方式比以前的方式好理解
     * 比如说,以前声明并实例化一个 Button 是这样的代码:
     * Button button1 = (Button)findViewById(R.id.button1);
     * <p>
     * 用注解的方式是这样的代码(两行代码):
     * @BindView(R.id.button1)
     * Button button1;
     * <p>
     * 这个Button的例子代码有点短,还不能说明问题,
     * 我直接上个长代码吧:
     * ImageView mIvLoginactivityBack = (ImageView)findViewById(R.id.iv_loginactivity_back);
     * <p>
     * 这样的长代码看的很费劲,可以用注解的方式等价代换成短代码的格式(两行代码):
     * @BindView(R.id.iv_loginactivity_back)
     * ImageView mIvLoginactivityBack;
     * <p>
     * 直接按着句子读就能理解了
     * 绑定视图(资源id号是iv_loginactivity_back)
     * 实例化ImageView 为 mIvLoginactivityBack
     * <p>
     * 成功声明并实例化一个对象,是不是注解的方式更简单易懂明了?
     * 是不是?是不是?
     * 当然,这么好的方法不是让你说用就用的
     * 你需要拥抱一下开源库,阅读这两篇文章:
     * https://www.sogou.com/link?url=DOb0bgH2eKh1ibpaMGjuy6YnbQPc3cuKC5mI2Qw8RgpomuBEhdSpHkUUZED5fr2Oc1DxBW0w__gl8OT6rYpPtg..
     * https://github.com/JakeWharton/butterknife
     * 读完你就会用了
     * 怎么样?和我一起拥抱开源吧。
     * 接下来敲代码
     */
//   @BindView(R.id.iv_loginactivity_back)
//   ImageView mIvLoginactivityBack;
    @BindView(R.id.tv_loginactivity_register)
    TextView mTvLoginactivityRegister;
    @BindView(R.id.rl_loginactivity_top)
    RelativeLayout mRlLoginactivityTop;
    @BindView(R.id.et_loginactivity_username)
    EditText mEtLoginactivityUsername;
    @BindView(R.id.et_loginactivity_password)
    EditText mEtLoginactivityPassword;
    @BindView(R.id.ll_loginactivity_two)
    LinearLayout mLlLoginactivityTwo;
//    @BindView(R.id.tv_loginactivity_forget)
//    TextView mTvLoginactivityForget;
//    @BindView(R.id.tv_loginactivity_check)
//    TextView mTvLoginactivityCheck;
//    @BindView(R.id.tv_loginactivity_else)
//    TextView mBtLoginactivityElse;
    /**
     * 都声明并实例化之后
     * 需要为实例化的这些对象设置行为
     * 在写 activity_login.xml 的时候
     * 有些控件 Button、ImageView、TextView 都有一个属性:
     * android:onClick="onClick"
     * 其实这也是开源库ButterKnife中的东西
     * 人家不仅解决了findViewById代码过长的问题,
     * 还解决了setOnClickListener(new View.OnClickListener() {}代码过长的问题
     * 让你不再写findViewById、setOnClickListener
     * 所以人家叫 ButterKnife 黄油刀
     * 就是专门管切割长代码的
     * Talk is cheap, show me your code.
     */
    @OnClick({
           // R.id.iv_loginactivity_back,
            R.id.tv_loginactivity_register,
            //R.id.tv_loginactivity_forget,
            //R.id.tv_loginactivity_check,
            R.id.bt_loginactivity_login,
            //R.id.tv_loginactivity_else
    })

    public void onClick(View view) {
        switch (view.getId()) {
            //case R.id.iv_loginactivity_back:
                //TODO 返回箭头功能
            //    finish();//销毁此Activity
            //    break;
            case R.id.tv_loginactivity_register:
                //TODO 注册界面跳转
                startActivity(new Intent(this, RegisterActivity.class));
                finish();
                break;
            //case R.id.tv_loginactivity_forget:   //忘记密码
                //TODO 忘记密码操作界面跳转
            //    startActivity(new Intent(this, FindPasswordActivity.class));
            //    break;
            //case R.id.tv_loginactivity_check:    //短信验证码登录
                // TODO 短信验证码登录界面跳转
            //    startActivity(new Intent(this, MessageLoginActivity.class));
            //    finish();
            //    break;
            /**
             * 登录验证:
             *
             * 从EditText的对象上获取文本编辑框输入的数据,并把左右两边的空格去掉
             *  String name = mEtLoginactivityUsername.getText().toString().trim();
             *  String password = mEtLoginactivityPassword.getText().toString().trim();
             *  进行匹配验证,先判断一下用户名密码是否为空,
             *  if (!TextUtils.isEmpty(name) && !TextUtils.isEmpty(password))
             *  再进而for循环判断是否与数据库中的数据相匹配
             *  if (name.equals(user.getName()) && password.equals(user.getPassword()))
             *  一旦匹配,立即将match = true;break;
             *  否则 一直匹配到结束 match = false;
             *
             *  登录成功之后,进行页面跳转:
             *
             *  Intent intent = new Intent(this, MainActivity.class);
             *  startActivity(intent);
             *  finish();//销毁此Activity
             */
            case R.id.bt_loginactivity_login:
                String name = mEtLoginactivityUsername.getText().toString().trim();
                String password = mEtLoginactivityPassword.getText().toString().trim();
                if (!TextUtils.isEmpty(name) && !TextUtils.isEmpty(password)) {
                    ArrayList<User> data = mDBOpenHelper.getAllData();
                    boolean match = false;
                    for(int i=0;i<data.size();i++) {
                        User user = data.get(i);
                        if (name.equals(user.getName()) && password.equals(user.getPassword())){
                            match = true;
                            break;
                        }else{
                            match = false;
                        }
                    }
                    if (match) {
                        Toast.makeText(this, "登录成功", Toast.LENGTH_SHORT).show();
                        Intent intent = new Intent(this, MainActivity.class);
                        startActivity(intent);
                        finish();//销毁此Activity
                    }else {
                        Toast.makeText(this, "用户名或密码不正确,请重新输入", Toast.LENGTH_SHORT).show();
                    }
                } else {
                    Toast.makeText(this, "请输入你的用户名或密码", Toast.LENGTH_SHORT).show();
                }
                break;
            //case R.id.tv_loginactivity_else:
                //TODO 第三方登录,时间有限,未实现
            //    break;
        }
    }
}



MainActivity.java

package com.example.justloginregistertest;

import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
/**
 * Created by littlecurl 2018/6/24
 */
public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        /**
         * 一定 一定 一定记得加这句,而且是固定位置,在setContentView()之下
         * 否则无论写的什么逻辑  都不会在Activity中起作用
         */
        ButterKnife.bind(this);
    }

    @BindView(R.id.bt_main_logout)
    Button mBtMainLogout;

    @OnClick({
            R.id.bt_main_logout
    })
    public void onClick(View view){
        switch (view.getId()) {
            case R.id.bt_main_logout:
                Intent intent = new Intent(this, loginActivity.class);
                startActivity(intent);
                finish();
                break;
        }
    }
}

RegisterAcitvity.java

package com.example.justloginregistertest;

import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.text.TextUtils;
import android.view.View;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.Toast;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
/**
 * Created by littlecurl 2018/6/24
 */
public class RegisterActivity extends AppCompatActivity{

    private String realCode;
    private DBOpenHelper mDBOpenHelper;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_register);
        ButterKnife.bind(this);
        mDBOpenHelper = new DBOpenHelper(this);

        //将验证码用图片的形式显示出来
        mIvRegisteractivityShowcode.setImageBitmap(Code.getInstance().createBitmap());
        realCode = Code.getInstance().getCode().toLowerCase();
    }

    @BindView(R.id.rl_registeractivity_top)
    RelativeLayout mRlRegisteractivityTop;
    @BindView(R.id.iv_registeractivity_back)
    ImageView mIvRegisteractivityBack;
    @BindView(R.id.ll_registeractivity_body)
    LinearLayout mLlRegisteractivityBody;
    @BindView(R.id.et_registeractivity_username)
    EditText mEtRegisteractivityUsername;
    @BindView(R.id.et_registeractivity_password1)
    EditText mEtRegisteractivityPassword1;
    @BindView(R.id.et_registeractivity_password2)
    EditText mEtRegisteractivityPassword2;
    @BindView(R.id.et_registeractivity_phoneCodes)
    EditText mEtRegisteractivityPhonecodes;
    @BindView(R.id.iv_registeractivity_showCode)
    ImageView mIvRegisteractivityShowcode;
    @BindView(R.id.rl_registeractivity_bottom)
    RelativeLayout mRlRegisteractivityBottom;

    /**
     * 注册页面能点击的就三个地方
     * top处返回箭头、刷新验证码图片、注册按钮
     */
    @OnClick({
            R.id.iv_registeractivity_back,
            R.id.iv_registeractivity_showCode,
            R.id.bt_registeractivity_register
    })
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.iv_registeractivity_back: //返回登录页面
                Intent intent1 = new Intent(this, loginActivity.class);
                startActivity(intent1);
                finish();
                break;
            case R.id.iv_registeractivity_showCode:    //改变随机验证码的生成
                mIvRegisteractivityShowcode.setImageBitmap(Code.getInstance().createBitmap());
                realCode = Code.getInstance().getCode().toLowerCase();
                break;
            case R.id.bt_registeractivity_register:    //注册按钮
                //获取用户输入的用户名、密码、验证码
                String username = mEtRegisteractivityUsername.getText().toString().trim();
                String password = mEtRegisteractivityPassword2.getText().toString().trim();
                String phoneCode = mEtRegisteractivityPhonecodes.getText().toString().toLowerCase();
                //注册验证
                if (!TextUtils.isEmpty(username) && !TextUtils.isEmpty(password) && !TextUtils.isEmpty(phoneCode) ) {
                    if (phoneCode.equals(realCode)) {
                        //将用户名和密码加入到数据库中
                        mDBOpenHelper.add(username, password);
                        Intent intent2 = new Intent(this, MainActivity.class);
                        startActivity(intent2);
                        finish();
                        Toast.makeText(this,  "验证通过,注册成功", Toast.LENGTH_SHORT).show();
                    } else {
                        Toast.makeText(this, "验证码错误,注册失败", Toast.LENGTH_SHORT).show();
                    }
                }else {
                    Toast.makeText(this, "未完善信息,注册失败", Toast.LENGTH_SHORT).show();
                }
                break;
        }
    }
}


User.java

package com.example.justloginregistertest;
/**
 * Created by littlecurl 2018/6/24
 */
public class User {
    private String name;            //用户名
    private String password;        //密码
    public User(String name, String password) {
        this.name = name;
        this.password = password;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", password='" + password + '\'' +
                '}';
    }
}

res → drawable 文件夹下面的内容:三个xml  一个.png图片

前两个xml是自动生成的我就不在这粘贴了,只粘贴图片和图片下面那个xml



ic_left_back.png

 ←←←←←你用鼠标选中一下,   这一行开头确实有个图片,很尴尬,看不见。


selector_loginactivity_button.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <!--默认情况下是一个带圆角,蓝色背景,白色边框的矩形-->
    <!--第二种方法-->
    <item android:state_window_focused="false">
        <shape android:shape="rectangle">
            <!--圆角-->
            <corners android:radius="5dp" />
            <!--填充颜色-->
            <solid android:color="@color/color_minefragment_top" />
            <!--描边-->
            <stroke android:width="1dp" android:color="#fff" />
        </shape>
    </item>
    <!--单击时是一个带圆角,绿色背景,白色边框的矩形-->
    <item android:state_pressed="true">
        <shape android:shape="rectangle">
            <!--圆角-->
            <corners android:radius="5dp" />
            <!--填充颜色-->
            <solid android:color="#008B8B" />
            <!--描边-->
            <stroke android:width="1dp" android:color="#fff" />
        </shape>
    </item>
</selector>

res → layout 文件夹下面的内容:三个xml 


activity_login.xml


<?xml version="1.0" encoding="utf-8"?>
<!--
这里把整个Activity_login的布局设置成相对布局,
因为相对布局比较灵活,想咋放咋放
看代码,上来就是三个 xmlns,xml这仨字母认识,ns这俩字母是namespace的缩写
正是有了这些namespace的声明,才能在不同的xml中使用相同的id名,
而不会造成使用时的冲突
-->
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#eeeeee"
    tools:context=".loginActivity">
<!--
整体是相对布局,
在整体上方放三个东西,这三个东西也是相对布局
合在一起称为一个top
一个返回箭头   ←
两个文字显示   登录  注册
也就是说   login界面的上方长这个样子
      ←   登录       注册
下面是具体代码
-->
    <RelativeLayout
        android:id="@+id/rl_loginactivity_top"
        android:layout_width="match_parent"
        android:layout_height="70dp"
        android:background="@color/color_minefragment_top" >
    <ImageView
        android:id="@+id/iv_loginactivity_back"
        android:layout_width="30dp"
        android:layout_height="30dp"
        android:background="@drawable/ic_left_back"
        android:layout_centerVertical="true"
        android:layout_marginLeft="10dp"
        android:clickable="true"
        android:onClick="onClick"
        />

    <TextView
        android:id="@+id/tv_loginactivity_login"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="登录"
        android:textColor="#fff"
        android:textSize="20dp"
        android:layout_toRightOf="@+id/iv_loginactivity_back"
        android:layout_centerVertical="true"
        android:layout_marginLeft="20dp"
        />
    <TextView
        android:id="@+id/tv_loginactivity_register"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="注册"
        android:textColor="#fff"
        android:textSize="20dp"
        android:layout_centerVertical="true"
        android:layout_alignParentRight="true"
        android:layout_marginRight="30dp"
        android:clickable="true"
        android:onClick="onClick"
        />
    </RelativeLayout>
<!--
 顶部三个东西摆放好之后
 就该来摆放登录时候的两个文本输入框了
 用户名
 密码
 这个明显的是LinerLayout
 LinerLayout必须指明orientation 方向 要么垂直vertical 要么水平 horizontal
 这里显然是垂直vertical
 -->
    <LinearLayout
        android:id="@+id/ll_loginactivity_two"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:layout_below="@+id/rl_loginactivity_top"
        android:layout_marginTop="10dp"
        android:layout_marginLeft="5dp"
        android:layout_marginRight="5dp"
        >
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal">
            <TextView
                android:id="@+id/tv_loginactivity_username"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="用户名:"/>
            <EditText
                android:id="@+id/et_loginactivity_username"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:hint="手机号/邮箱/用户名"/>
        </LinearLayout>
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal">
            <TextView
                android:id="@+id/tv_loginactivity_password"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="密    码:"/>
            <EditText
                android:id="@+id/et_loginactivity_password"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:hint="登录密码"
                android:inputType="textPassword"/>
        </LinearLayout>
    </LinearLayout>
<!--
  填好用户名、密码后,就该点击登录按钮了
  注意最后有一句: android:onClick="onClick"
  这是应用了一个开源库,详细信息在loginActivity.java 中有注释
  -->
    <Button
        android:id="@+id/bt_loginactivity_login"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/ll_loginactivity_two"
        android:layout_marginTop="10dp"
        android:layout_marginLeft="5dp"
        android:layout_marginRight="5dp"
        android:background="@drawable/selector_loginactivity_button"
        android:text="登录"
        android:textColor="#fff"
        android:gravity="center"
        android:onClick="onClick"
        />
<!--
    为了App的人性化,
    想到有以下三种无法密码登录的异常处理情况
    一、密码错误,重新输入
    二、忘记密码,重新修改密码
    三、不想注册,通过短信验证登录
    密码输错了,重新输入,这个没啥说的
    忘记密码应该以一个可以点击的文字出现在登录按钮的左下方
    短信验证登录也以一个可以点击的文字出现在登录按钮的右下方
-->
    <TextView
        android:id="@+id/tv_loginactivity_forget"
        android:text="忘记密码"
        android:textColor="#f00"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="50dp"
        android:layout_marginVertical="50dp"
        android:layout_below="@+id/bt_loginactivity_login"
        android:layout_alignLeft="@+id/bt_loginactivity_login"
        />
    <TextView
        android:id="@+id/tv_loginactivity_check"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="短信验证码登录"
        android:textColor="#f00"
        android:layout_marginRight="50dp"
        android:layout_marginVertical="50dp"
        android:layout_below="@+id/bt_loginactivity_login"
        android:layout_alignRight="@+id/bt_loginactivity_login"
        />
<!--
当然,QQ、微信、微博、GitHub...在当今如此火热
登录的时候完全可以免注册
直接使用第三方登录
  -->
    <TextView
        android:id="@+id/tv_loginactivity_else"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/tv_loginactivity_forget"
        android:layout_centerInParent="true"
        android:layout_marginVertical="30dp"

        android:text="---------------------------第三方登录---------------------------"
        android:textColor="#B3B3B3"
        android:gravity="center"
        />
</RelativeLayout>

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/tv_main_hello"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
    <Button
        android:id="@+id/bt_main_logout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="退出登录"
        android:textColor="@color/colorAccent"
        />
</android.support.constraint.ConstraintLayout>

activity_register.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"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.justloginregistertest.RegisterActivity"
    android:background="#eeeeee"
    >

    <RelativeLayout
        android:id="@+id/rl_registeractivity_top"
        android:layout_width="match_parent"
        android:layout_height="70dp"
        android:background="@color/color_minefragment_top"
        >
      <ImageView
          android:id="@+id/iv_registeractivity_back"
          android:layout_width="30dp"
          android:layout_height="30dp"
          android:background="@drawable/ic_left_back"
          android:layout_centerVertical="true"
          android:layout_marginLeft="10dp"
          android:clickable="true"
          android:onClick="onClick"
          />

       <TextView
           android:id="@+id/tv_registeractivity_register"
           android:layout_width="wrap_content"
           android:layout_height="wrap_content"
           android:text="注册"
           android:textColor="#fff"
           android:textSize="20dp"
           android:layout_toRightOf="@+id/iv_registeractivity_back"
           android:layout_centerVertical="true"
           android:layout_marginLeft="20dp"
           />
    </RelativeLayout>

    <LinearLayout
        android:id="@+id/ll_registeractivity_body"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:layout_below="@+id/rl_registeractivity_top"
        android:layout_marginTop="10dp"
        android:layout_marginLeft="5dp"
        android:layout_marginRight="5dp"
        >
<!-- 第一个文本编辑框  输入用户名 -->
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal">
            <TextView
                android:id="@+id/tv_registeractivity_username"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="用户名:"/>
            <EditText
                android:id="@+id/et_registeractivity_username"
                android:layout_width="match_parent"
                android:layout_height="50dp"
                android:hint="请输入用户名"
                android:gravity="center_vertical"
                android:layout_marginLeft="10dp"
                />
        </LinearLayout>
<!-- 第二个文本编辑框  输入密码 -->
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">
        <TextView
            android:id="@+id/tv_registeractivity_password1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="密    码:"/>
        <EditText
            android:id="@+id/et_registeractivity_password1"
            android:layout_width="match_parent"
            android:layout_height="50dp"
            android:gravity="center_vertical"
            android:layout_marginLeft="10dp"
            android:inputType="textPassword"
            android:hint="请输入密码" />
    </LinearLayout>
<!-- 第三个文本编辑框  再次输入密码 -->
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">
        <TextView
            android:id="@+id/tv_registeractivity_password2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="密    码:"/>
        <EditText
            android:id="@+id/et_registeractivity_password2"
            android:layout_width="match_parent"
            android:layout_height="50dp"
            android:hint="请再次输入密码"
            android:gravity="center_vertical"
            android:layout_marginLeft="10dp"
            android:inputType="textPassword"
            />
    </LinearLayout>
<!-- 验证码部分 -->
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginRight="15dp"
            android:layout_marginTop="10dp"
            android:orientation="horizontal" >
            <!-- 第四个文本编辑框  输入验证码 -->
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="horizontal">
                <TextView
                    android:id="@+id/tv_registeractivity_phoneCodes"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="验证码:"/>
                <EditText
                    android:id="@+id/et_registeractivity_phoneCodes"
                    android:layout_width="0dp"
                    android:layout_weight="3"
                    android:layout_height="50dp"
                    android:layout_marginLeft="10dp"
                    android:layout_marginRight="10dp"
                    android:hint="请输入4位验证码" />

                <ImageView
                    android:id="@+id/iv_registeractivity_showCode"
                    android:layout_width="0dp"
                    android:layout_height="70dp"
                    android:layout_weight="1.5"
                    android:clickable="true"
                    android:onClick="onClick"
                    android:layout_marginTop="-10dp"
                />
            </LinearLayout>
        </LinearLayout>
        <!-- 注册按钮 -->
        <Button
            android:id="@+id/bt_registeractivity_register"
            android:layout_width="match_parent"
            android:layout_height="50dp"
            android:layout_marginLeft="5dp"
            android:background="@drawable/selector_loginactivity_button"
            android:textColor="#fff"
            android:text="注册"
            android:onClick="onClick"
            android:layout_marginTop="40dp"
            />

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="50dp"
            android:id="@+id/rl_registeractivity_bottom"
            android:layout_marginTop="10dp"
            >
            <TextView
                android:layout_centerInParent="true"
                android:text="注册即代表同意《用户协议》"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"/>
        </RelativeLayout>

    </LinearLayout>

</RelativeLayout>

values → colors.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="colorPrimary">#008577</color>
    <color name="colorPrimaryDark">#00574B</color>
    <color name="colorAccent">#D81B60</color>
    <color name="color_minefragment_top">#20B2AA</color>
</resources>

因为我这个程序用到了开源库,编译的时候Gradle需要根据下面这个文件去下载jar包,在这里特别的粘贴一下下面这个文件

 build.gradle(Module:app)


apply plugin: 'com.android.application'

android {
    compileSdkVersion 27
    defaultConfig {
        applicationId "com.example.justloginregistertest"
        minSdkVersion 18
        targetSdkVersion 27
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.android.support:appcompat-v7:27.1.1'
    implementation 'com.android.support.constraint:constraint-layout:1.1.2'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
    implementation 'com.jakewharton:butterknife:8.8.1'
    annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'
}


build.gradle(后缀名不是app的那个文件)

// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
    
    repositories {
        google()
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.2.0-alpha18'
        

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
        google()
        jcenter()
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

gradle-wrapper.properties

distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists


猜你喜欢

转载自blog.csdn.net/midnight_time/article/details/80792255
今日推荐