Android之SqliteDatabase(MVP模式)實現用戶登錄註冊功能

Android之SqliteDatabase(MVP模式)實現用戶登錄註冊功能

用戶登錄以及註冊功能的普遍使用就不用我說了,任何一款應用軟件基本都具有登錄和註冊功能,今天通過前面的學習,我寫了一個小demo,就是使用MVP模式寫一個用戶登錄和註冊的功能。有關MVP模式我就不做講解了,通常來說很多實現的登錄或者註冊功能都是使用MVC的模式來實現的,今天我將採用MVP模式來實現這個小demo,主要是爲了鞏固數據庫部分的知識點,然後讓大家熟悉MVP這種模式,看看MVP模式的優勢在哪裏(其實MVP最主要的就是達到完全解耦,不同的層實現不同的功能,互不影響)。

案例的主要功能:
1. 用戶登錄
2. 用戶註冊

模擬場景:當用戶點擊登錄按鈕時,模式了一個延時3秒的操作,相當於從服務器獲取用戶登錄信息,3秒後返回登錄結果。註冊也是一樣

程序整體結構圖:
這裏寫圖片描述

老樣子,主要功能在程序中註釋

view層:

ViewInter.java

/**
 * view層所有的功能
 */
public interface ViewInter {
    //獲取用戶名
    String getName();

    //獲取用戶密碼
    String getPass();

    //清除界面中編輯框裏的名字
    void clearUserName();

    //清除界面中編輯框裏的密碼
    void clearUserPass();

    //顯示進度條
    void showLoading();

    //隱藏進度條
    void hideLoading();

    /**
     * 提示用戶登錄或註冊成功後的狀態
     * @param user 用戶信息
     * @param tag 表示登錄或註冊提示
     */
    void successHint(User user, String tag);

    /**
     * 提示用戶登錄或註冊失敗後的狀態
     * @param user 用戶信息
     * @param tag 表示登錄或註冊提示
     */
    void failHint(User user, String tag);

}

Login.java

public class Login extends AppCompatActivity implements ViewInter{

    private EditText mUserName;//用戶名控件
    private EditText mUserPwd;//用戶密碼控件
    private Button mBtnLogin;//登錄按鈕
    private Button mBtnClear;//清除按鈕
    private ProgressBar mProBar;//進度條
    private TextView mRegister;//點我註冊控件
    private Presenter presenter;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);
        //初始化控件
        initView();
        //初始化事件
        event();
        //建立與presenter層的關係,創建presenter對象
        presenter = new Presenter(this, Login.this);
    }
    private void initView() {
        mUserName = (EditText) findViewById(R.id.user_name);
        mUserPwd = (EditText) findViewById(R.id.user_pwd);
        mBtnLogin = (Button) findViewById(R.id.btn_login);
        mBtnClear = (Button) findViewById(R.id.btn_clear);
        mProBar = (ProgressBar) findViewById(R.id.progressBar);
        mRegister = (TextView) findViewById(R.id.mRegister);
    }

    private void event() {
        /**
         * 登錄響應事件
         */
        mBtnLogin.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //告訴presenter層,我需要登錄操作
                presenter.login();
            }
        });
        /**
         * 清除響應事件
         */
        mBtnClear.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                //告訴presenter層,我需要清除操作
                presenter.clear();
            }
        });

        /**
         * 點擊註冊響應事件,跳轉到註冊界面
         */
        mRegister.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View view) {
                Intent intent = new Intent(Login.this,Register.class);
                startActivity(intent);
                finish();
            }
        });
    }

    @Override
    public String getName() {
        return mUserName.getText().toString();
    }

    @Override
    public String getPass() {
        return mUserPwd.getText().toString();
    }

    @Override
    public void clearUserName() {
        mUserName.setText("");
    }

    @Override
    public void clearUserPass() {
        mUserPwd.setText("");
    }

    @Override
    public void showLoading() {
        mProBar.setVisibility(View.VISIBLE);
    }

    @Override
    public void hideLoading() {
        mProBar.setVisibility(View.GONE);
    }

    @Override
    public void successHint(User user,String tag) {
        Toast.makeText(this,"用戶" + user.getUserName() + tag + "成功",Toast.LENGTH_SHORT).show();
    }

    @Override
    public void failHint(User user,String tag) {
        Toast.makeText(this,"用戶" + user.getUserName() + tag + "失敗,密碼或賬號不正確,maybe not this user",Toast.LENGTH_LONG).show();
    }
}

Register.java

public class Register extends AppCompatActivity implements ViewInter {

    private EditText mUserName;
    private EditText mUserPwd;
    private Button mBtnRegister;
    private Button mBtnClear;
    private ProgressBar mProBar;
    private TextView mTvLogin;//點擊註冊控件
    private Presenter presenter;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_register);
        initView();
        event();
        presenter = new Presenter(this, Register.this);
    }


    private void initView() {
        mUserName = (EditText) findViewById(R.id.user_name);
        mUserPwd = (EditText) findViewById(R.id.user_pwd);
        mBtnRegister = (Button) findViewById(R.id.btn_register);
        mBtnClear = (Button) findViewById(R.id.btn_clear);
        mProBar = (ProgressBar) findViewById(R.id.progressBar);
        mTvLogin = (TextView) findViewById(R.id.mTvLogin);
    }

    private void event() {
        /**
         * 註冊功能
         */
        mBtnRegister.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                presenter.register();
            }
        });
        /**
         * 清除功能
         */
        mBtnClear.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                presenter.clear();
            }
        });
        /**
         * 啓動登錄界面
         */
        mTvLogin.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View view) {
                Intent intent = new Intent(Register.this,Login.class);
                startActivity(intent);
                finish();
            }
        });
    }

    @Override
    public String getName() {
        return mUserName.getText().toString();
    }

    @Override
    public String getPass() {
        return mUserPwd.getText().toString();
    }

    @Override
    public void clearUserName() {
        mUserName.setText("");
    }

    @Override
    public void clearUserPass() {
        mUserPwd.setText("");
    }

    @Override
    public void showLoading() {
        mProBar.setVisibility(View.VISIBLE);
    }

    @Override
    public void hideLoading() {
        mProBar.setVisibility(View.GONE);
    }

    @Override
    public void successHint(User user, String tag) {
        Toast.makeText(this, "用戶" + user.getUserName() + tag + "成功", Toast.LENGTH_SHORT).show();
    }

    @Override
    public void failHint(User user, String tag) {
        Toast.makeText(this, "用戶" + user.getUserName() + tag + "失敗,已存在該用戶", Toast.LENGTH_SHORT).show();
    }


}

presenter層:

Presenter.java

public class Presenter {
    //view層的控件,對view層進行操作
    ViewInter viewInter;
    //模型層的控件,對model層進行操作
    ModelInter modelInter;

    public Presenter(ViewInter viewInter, Context context) {
        this.viewInter = viewInter;
        modelInter = new ModelImp(context);
    }

    /**
     * 註冊功能
     */
    public void register() {
        //顯示進度條
        viewInter.showLoading();
         //控制層開始處理數據,拿到視圖層的name,pass之後,進行註冊操作
        //OnRegisterListener匿名內部類
        modelInter.register(viewInter.getName(), viewInter.getPass(), new OnRegisterListener() {
            /**
             * 如果註冊成功模型層就會調用該方法
             * 其中的handler表示模擬延時3秒響應操作
             * @param user 返回已經註冊的用戶信息
             */
            @Override
            public void registerSuccess(final User user) {
                Handler handler = new Handler();
                handler.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        //隱藏進度條
                        viewInter.hideLoading();
                        //返回成功狀態信息
                        viewInter.successHint(user,TAG);
                    }
                }, 3000);

            }
            /**
             * 如果註冊失敗模型層就會調用該方法
             * 其中的handler表示模擬延時3秒響應操作
             * @param user 返回未註冊的用戶信息
             */
            @Override
            public void registerFail(final User user) {
                Handler handler = new Handler();
                handler.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        //隱藏進度條
                        viewInter.hideLoading();
                        //返回失敗狀態信息
                        viewInter.failHint(user,TAG);
                    }
                }, 3000);

            }
        });
    }

    /**
     * 清除功能
     */
    public void clear() {
        viewInter.clearUserName();
        viewInter.clearUserPass();
    }

    /**
     * 登錄功能,其基本實現和註冊一樣,只是模型層處理的邏輯不一樣
     */
    public void login(){
        viewInter.showLoading();
        modelInter.login(viewInter.getName(), viewInter.getPass(), new OnLoginListener() {
            @Override
            public void loginSuccess(final User user) {
                Handler handler = new Handler();
                handler.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        viewInter.hideLoading();
                        viewInter.successHint(user,TAG);
                    }
                },3000);

            }

            @Override
            public void loginFail(final User user) {
                Handler handler = new Handler();
                handler.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        viewInter.hideLoading();
                        viewInter.failHint(user,TAG);
                    }
                },3000);

            }
        });
    }
}

model層:

ModelInter.java

/**
 * 所有數據處理操作功能都定義在這個接口中,方便擴展
 */
public interface ModelInter {
    /**
     * 註冊操作
     *
     * @param name     用戶名
     * @param pass     用戶密碼
     * @param listener 回調事件,如果成功調用註冊成功方法,失敗調用註冊失敗方法
     */
    void register(String name, String pass, OnRegisterListener listener);

    /**
     * 登錄操作
     *
     * @param name     用戶名
     * @param pass     用戶密碼
     * @param listener 回調事件,如果成功調用登錄成功方法,失敗調用登錄失敗方法
     */
    void login(String name, String pass, OnLoginListener listener);
}

OnLoginListener.java

/**
 * 登錄成功或失敗的接口
 */
public interface OnLoginListener {
    //表示登錄標籤
    String TAG = "登錄";

    /**
     * 登錄成功,傳遞了用戶信息
     *
     * @param user
     */
    void loginSuccess(User user);

    /**
     * 登錄失敗,傳遞了用戶信息
     *
     * @param user
     */
    void loginFail(User user);
}

OnRegisterListener.java

/**
 * 註冊成功或失敗的接口
 */
public interface OnRegisterListener {
    //表示註冊標籤
    String TAG = "註冊";
    /**
     * 註冊成功,傳遞了用戶信息
     *
     * @param user
     */
    void registerSuccess(User user);

    /**
     * 註冊失敗,傳遞了用戶信息
     *
     * @param user
     */
    void registerFail(User user);

}

ModelIpm.java

/**
 * 整體的邏輯實現,判斷是否登錄成功,失敗
 */
public class ModelImp implements ModelInter {

    //獲取數據庫管理類,對數據庫進行操作
    private UserDao userDao;

    public ModelImp(Context context){
        userDao = new ImpUserDao(context);
    }

    /**
     * 註冊邏輯實現
     * @param name     用戶名
     * @param pass     用戶密碼
     * @param listener 回調事件,如果成功調用註冊成功方法,失敗調用註冊失敗方法
     */
    @Override
    public void register(String name, String pass, OnRegisterListener listener) {
        //將用戶名和密碼封裝到user中
        User user = new User(name,pass);
        //數據庫不存在該用戶註冊成功,否則註冊失敗
        if(userDao.isExistsUser(user)){
            listener.registerFail(user);
        }else{
            userDao.addUser(user);
            listener.registerSuccess(user);
        }
    }

    /**
     * 登錄邏輯實現
     * @param name     用戶名
     * @param pass     用戶密碼
     * @param listener 回調事件,如果成功調用登錄成功方法,失敗調用登錄失敗方法
     */
    @Override
    public void login(String name, String pass, OnLoginListener listener) {
        User user = new User(name,pass);
        //判斷是否登錄成功
        if(userDao.isLoginSuccess(user)){
            listener.loginSuccess(user);
        }else{
            listener.loginFail(user);
        }
    }
}

dao:(數據庫的操作工具類)

UserDao.java

public interface UserDao {

    void addUser(User user);//添加新用戶

    void delteUserByName(String name);//刪除用戶

    void updateUserPwd(String name, String pass);//通過同戶名修改密碼

    User queryUserByName(String name);//通過用戶名查找用戶

    boolean isExistsUser(User user);//判斷是否存在重複用戶

    boolean isLoginSuccess(User user);
}

ImpUserDao.java

/**
* 在這個方法中,我都採用了兩種對數據進行操作的方法,一種是sql語句,一種是直接調用封裝好了的方法
* 哪種方式都可以,看個人愛好
*/
public class ImpUserDao implements UserDao {
    private DBHelper dbHelper;
    private SQLiteDatabase database;
    private ContentValues values;

    public ImpUserDao(Context context) {
        dbHelper = new DBHelper(context);
    }

    /**
     * 添加新用戶
     * @param user 註冊的用戶信息
     */
    @Override
    public void addUser(User user) {
        database = dbHelper.getWritableDatabase();
        //方式一:sql語句操作數據庫
//        String sql = "insert into users(uName,uPass) values(?,?)";
//        database.execSQL(sql,new Object[]{user.getUserName(),user.getUserPass()});

        //方法二:封裝的api操作,直接操作方法即可
        values = new ContentValues();
        values.put(DBHelper.COLNUMNAME, user.getUserName());
        values.put(DBHelper.COLNUMPASS, user.getUserPass());
        database.insert(DBHelper.TABLENAME, null, values);
        database.close();
    }

    /**
     * 根據名字刪除用戶
     *
     * @param name 要刪除用戶的名字
     */
    @Override
    public void delteUserByName(String name) {
        database = dbHelper.getWritableDatabase();
        //方式一:sql語句操作數據庫
//        String sql = "delete from " + DBHelper.TABLENAME + " where " + DBHelper.COLNUMNAME + " = ?";
//        database.execSQL(sql,new Object[]{name});
        //方法二:封裝的api操作,直接操作方法即可
        database.delete(DBHelper.TABLENAME,DBHelper.COLNUMNAME + " = ?",new String[]{name});
        database.close();
    }

    /**
     * 更新用戶密碼
     *
     * @param name 用戶名
     * @param pass 用戶密碼
     */
    @Override
    public void updateUserPwd(String name, String pass) {
        database = dbHelper.getWritableDatabase();
        //方式一:sql語句操作數據庫
//        String sql = "update " + DBHelper.TABLENAME + " set " + DBHelper.COLNUMPASS + " = ? where " + DBHelper.COLNUMNAME + " = ?";
//        database.execSQL(sql,new Object[]{pass,name});
        //方法二:封裝的api操作,直接操作方法即可
        values = new ContentValues();
        values.put(DBHelper.COLNUMPASS,pass);
        database.update(DBHelper.TABLENAME,values,DBHelper.COLNUMNAME + " = ?",new String[]{pass});
        database.close();
    }

    /**
     * 通過用戶名查找用戶
     *
     * @param name
     */
    @Override
    public User queryUserByName(String name) {
        database = dbHelper.getReadableDatabase();
        //方式一:sql語句操作數據庫
//        String sql = "select * from " + DBHelper.TABLENAME + " where " + DBHelper.COLNUMNAME + " = ?";
//        Cursor cursor = database.rawQuery(sql, new String[]{name});
        //方法二:封裝的api操作,直接操作方法即可
        Cursor cursor = database.query(DBHelper.TABLENAME, null, DBHelper.COLNUMNAME + " = ?", null, null, null, null);
        User user = null;
        while(cursor.moveToNext()){
            user = new User();
            user.setUserName(cursor.getString(cursor.getColumnIndex(DBHelper.COLNUMNAME)));
            user.setUserPass(cursor.getString(cursor.getColumnIndex(DBHelper.COLNUMPASS)));
        }
        cursor.close();

        return user;
    }

    /**
     * 判斷是否存在該用戶
     *
     * @param user
     * @return
     */
    @Override
    public boolean isExistsUser(User user) {
        User isExit = queryUserByName(user.getUserName());
        return isExit == null ? false : true;
    }

    /**
     * 判斷是否登錄成功
     * @param user 登錄的用戶信息
     * @return
     */
    @Override
    public boolean isLoginSuccess(User user) {
        database = dbHelper.getReadableDatabase();
        //方法一:sql語句操作
//        String sql = "select * from " + DBHelper.TABLENAME + " where " + DBHelper.COLNUMNAME + " = ? and " + DBHelper.COLNUMPASS + " = ?";
//        Cursor cursor = database.rawQuery(sql, new String[]{user.getUserName(), user.getUserPass()});
        //方法二:封裝的api操作,直接操作方法即可
        Cursor cursor = database.query(DBHelper.TABLENAME, null, DBHelper.COLNUMNAME + " = ? and " + DBHelper.COLNUMPASS + " = ?", new String[]{user.getUserName(), user.getUserPass()}, null, null, null);

        if(cursor.moveToFirst()){
            cursor.close();
            return true;
        }
        cursor.close();
        return false;
    }
}

database:(數據庫封裝類)

DBHelper.java

public class DBHelper extends SQLiteOpenHelper {

    //數據庫名
    public static final String DBNAME = "users.db";

    //版本號
    public static final int VERSION = 1;

    //表名
    public static final String TABLENAME = "users";
    //列名
    public static final String COLNUMNAME = "uName";
    //列名
    public static final String COLNUMPASS = "uPass";

    public DBHelper(Context context) {
        super(context, DBNAME, null, VERSION);
    }

    /**
     * 該方法只執行一次,首次執行創建表
     * @param db
     */
    @Override
    public void onCreate(SQLiteDatabase db) {
        String sql = "create table " + TABLENAME + "(_id integer primary key autoincrement,uName varchar(20) not null,uPass varchar(20) not null)";
        db.execSQL(sql);
    }

    /**
     * 版本更新調用該方法
     * @param db
     * @param oldVersion
     * @param newVersion
     */
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

    }

    /**
     * 還原舊版本
     * @param db
     * @param oldVersion
     * @param newVersion
     */
    @Override
    public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        super.onDowngrade(db, oldVersion, newVersion);
    }
}

bean:

User.java

public class User {
    private String userName;
    private String userPass;

    public User() {
    }

    public User(String userName, String userPass) {
        this.userName = userName;
        this.userPass = userPass;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getUserPass() {
        return userPass;
    }

    public void setUserPass(String userPass) {
        this.userPass = userPass;
    }

    @Override
    public String toString() {
        return "User{" +
                "userName='" + userName + '\'' +
                ", userPass='" + userPass + '\'' +
                '}';
    }
}

基本的功能都已經實現了,所有的代碼都在這裏,關於佈局的代碼就不貼上 ,等下我把整個項目打包一下,需要源代碼的直接自己下載就行了。對於不屬性MVP模式的童鞋,可能能看懂,但是自己要去實現就有一點點麻煩了,下面看看運行的結果吧。

這裏寫圖片描述

源碼下載

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章