1. 程式人生 > >登入和退出登入的操作邏輯

登入和退出登入的操作邏輯

登入功能的操作邏輯步驟如下:可以分為五個步驟來實現。
1、進入頁面先判斷使用者是否已經登入

    private void isLogin() {
        //檢視本地是否有使用者的登入資訊
        SharedPreferences sp = this.getActivity().getSharedPreferences("user_info", Context.MODE_PRIVATE);
        String name = sp.getString("name", "");
        if (TextUtils.isEmpty(name)) {
            //本地沒有儲存過使用者資訊,給出提示:登入
doLogin(); } else { //已經登入過,直接載入使用者的資訊並顯示 doUser(); } }

2、沒有登入過,則提示使用者登入,點選後跳轉到登入頁面

    //提示使用者登入
    private void doLogin() {
        new AlertDialog.Builder(this.getActivity())
                .setTitle("提示")
                .setMessage("您還沒有登入哦!麼麼~"
) .setPositiveButton("確定", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int i) { // UIUtils.toast("進入登入介面",false); ((BaseActivity) MeFragment.this.getActivity()).goToActivity(LoginActivity.class, null
); } }) .setCancelable(false) .show(); }

3、在登入頁面中做登入操作,登入成功後儲存相應的使用者資訊到本地

    //儲存使用者資訊
    public void saveUser(User user){
        SharedPreferences sp = this.getSharedPreferences("user_info", Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sp.edit();
        editor.putString("name",user.getName());
        editor.putString("imageurl",user.getImageurl());
        editor.putBoolean("iscredit",user.isCredit());
        editor.putString("phone",user.getPhone());
        editor.commit();//必須提交,否則儲存不成功
    }

4、使用者已經登入過了,則載入並顯示相應的資訊

//載入使用者資訊並顯示
    private void doUser() {
        //1.讀取本地儲存的使用者資訊
        User user = ((BaseActivity) this.getActivity()).readUser();
        //2.獲取物件資訊,並設定給相應的檢視顯示
        tvMeName.setText(user.getName());
        //判斷本地是否已經儲存頭像的圖片,如果有,則不執行聯網操作
        boolean isExist = readImage();
        if (isExist){
            return;
        }
        //使用Picasso聯網獲取圖片
        Picasso.with(this.getActivity()).load(user.getImageurl()).transform(new Transformation() {
            @Override
            public Bitmap transform(Bitmap source) {//下載以後的記憶體中的bitmap物件
                //壓縮處理
                Bitmap bitmap = BitmapUtils.zoom(source, UIUtils.dp2px(62), UIUtils.dp2px(62));
                //圖形處理
                bitmap = BitmapUtils.circleBitmap(bitmap);
                //回收bitmap物件
                source.recycle();
                return bitmap;
            }

            @Override
            public String key() {
                return "";
            }
        }).into(ivMeIcon);
    }

5、退出登入,需要清除本地儲存的使用者資訊

   public void logout(View view){//"退出登入"button的回撥方法
        //1、將儲存在sp中的資料刪除
        SharedPreferences sp = this.getSharedPreferences("user_info", Context.MODE_PRIVATE);
        sp.edit().clear().commit();//清除資料必須要提交:提交以後,檔案仍存在,只是檔案中的資料被清除了
        //2、將本地儲存的圖片的file刪除
        File filesDir;
        if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {//判斷sd卡是否掛載
            //路徑1:storage/sdcard/Android/data/包名/files
            filesDir = this.getExternalFilesDir("");
        } else {//手機內部儲存
            //路徑:data/data/包名/files
            filesDir = this.getFilesDir();
        }
        File file = new File(filesDir, "icon.png");
        if (file.exists()){
            file.delete();//刪除儲存中的檔案
        }
        //3、銷燬所有的Activity
        this.removeAll();
        //4、重新進入首頁面
        goToActivity(MainActivity.class,null);
    }

登入返回的資訊實體類User.class


public class User {
    private int id;// 編號
    private String name;// 姓名
    private String password;// 密碼
    private String phone;// 手機號
    private String imageurl;// 頭像地址
    private boolean iscredit;// 是否公安部認證

    public User() {
        super();
    }

    public User(int id, String name, String password, String phone) {
        super();
        this.id = id;
        this.name = name;
        this.password = password;
        this.phone = phone;
    }

    public User(int id, String name, String password, String phone,
            String imageurl) {
        super();
        this.id = id;
        this.name = name;
        this.password = password;
        this.phone = phone;
        this.imageurl = imageurl;
    }

    public User(int id, String name, String password, String phone,
            String imageurl, boolean iscredit) {
        super();
        this.id = id;
        this.name = name;
        this.password = password;
        this.phone = phone;
        this.imageurl = imageurl;
        this.iscredit = iscredit;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    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;
    }

    public String getPhone() {
        return phone;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }

    public String getImageurl() {
        return imageurl;
    }

    public void setImageurl(String imageurl) {
        this.imageurl = imageurl;
    }

    public boolean isCredit() {
        return iscredit;
    }

    public void setCredit(boolean iscredit) {
        this.iscredit = iscredit;
    }

    @Override
    public String toString() {
        return "User [id=" + id + ", name=" + name + ", password=" + password
                + ", phone=" + phone + ", imageurl=" + imageurl + ", iscredit="
                + iscredit + "]";
    }

}

登入的時候,後臺返回的資訊,我們需要把常用的使用者資訊儲存到本地。
儲存程式碼方法如下:

    //儲存使用者資訊
    public void saveUser(User user){
        SharedPreferences sp = this.getSharedPreferences("user_info", Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sp.edit();
        editor.putString("name",user.getName());
        editor.putString("imageurl",user.getImageurl());
        editor.putBoolean("iscredit",user.isCredit());
        editor.putString("phone",user.getPhone());
        editor.commit();//必須提交,否則儲存不成功
    }

讀取使用者資訊方法如下:

    //讀取使用者資訊
    public User readUser(){
        SharedPreferences sp = this.getSharedPreferences("user_info", Context.MODE_PRIVATE);
        User user = new User();
        user.setName(sp.getString("name",""));
        user.setImageurl(sp.getString("imageurl",""));
        user.setPhone(sp.getString("phone",""));
        user.setCredit(sp.getBoolean("iscredit",false));
        return user;
    }

退出登入的時候,需要把使用者資訊清除。程式碼方法如下:

    public void logout(View view){//"退出登入"button的回撥方法
        //1、將儲存在sp中的資料刪除
        SharedPreferences sp = this.getSharedPreferences("user_info", Context.MODE_PRIVATE);
        sp.edit().clear().commit();//清除資料必須要提交:提交以後,檔案仍存在,只是檔案中的資料被清除了
        //2、將本地儲存的圖片的file刪除
        File filesDir;
        if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {//判斷sd卡是否掛載
            //路徑1:storage/sdcard/Android/data/包名/files
            filesDir = this.getExternalFilesDir("");
        } else {//手機內部儲存
            //路徑:data/data/包名/files
            filesDir = this.getFilesDir();
        }
        File file = new File(filesDir, "icon.png");
        if (file.exists()){
            file.delete();//刪除儲存中的檔案
        }
        //3、銷燬所有的Activity
        this.removeAll();
        //4、重新進入首頁面
        goToActivity(MainActivity.class,null);
    }

將bitmap圖片儲存到本地的操作

//將bitmap儲存到本地的操作
    /**
     * 資料的儲存。(5種)
     * Bimap:記憶體層面的圖片物件。
     *
     * 儲存--->記憶體:
     *      BitmapFactory.decodeFile(String filePath);
     *      BitmapFactory.decodeStream(InputStream is);
     * 記憶體--->儲存:
     *      bitmap.compress(Bitmap.CompressFormat.PNG,100,OutputStream os);
     */
    private void saveImage(Bitmap bitmap) {
        File filesDir;
        if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){//判斷sd卡是否掛載
            //路徑1:storage/sdcard/Android/data/包名/files
            filesDir = this.getExternalFilesDir("");
        }else {//手機內部儲存
            //路徑:data/data/包名/files
            filesDir = this.getFilesDir();
        }
        FileOutputStream fos = null;
        try {
            File file = new File(filesDir,"icon.png");
            fos = new FileOutputStream(file);
            bitmap.compress(Bitmap.CompressFormat.PNG,100,fos);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }finally {
            if (fos!=null){
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

讀取本地儲存的圖片,並設定到相應的ImageView控制元件

    //讀取本地儲存的頭像圖片
    private void readImage(ImageView img) {
        File filesDir;
        if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {//判斷sd卡是否掛載
            //路徑1:storage/sdcard/Android/data/包名/files
            filesDir = this.getExternalFilesDir("");
        } else {//手機內部儲存
            //路徑:data/data/包名/files
            filesDir = this.getFilesDir();
        }
        File file = new File(filesDir, "icon.png");
        if (file.exists()){
            //儲存-->記憶體
            Bitmap bitmap = BitmapFactory.decodeFile(file.getAbsolutePath());
            img.setImageBitmap(bitmap);
        }
    }

Activity的管理器類程式碼如下:


import android.app.Activity;

import java.util.Stack;

/**
 * 作者: willkong on 2017/10/31.
 * 作用:統一應用程式中所有的Activity的棧管理(單例)
 *      涉及到activity的新增、刪除指定、刪除當前、刪除所有、返回棧大小的方法
 */
public class ActivityManager {
    //單例模式:餓漢式
    private ActivityManager(){

    }
    private static ActivityManager activityManager = new ActivityManager();

    public static ActivityManager getInstance(){
        return activityManager;
    }

    //提供棧的物件
    private Stack<Activity> activityStack = new Stack<>();

    //activity的新增
    public void add(Activity activity){
        if(activity != null){
            activityStack.add(activity);
        }
    }

    //插曲:[12,3,44,6,332,65,-56,1]
    //刪除指定的activity
    public void remove(Activity activity){
        if(activity != null){
//            for(int i = 0; i < activityStack.size(); i++) {
//                Activity currentActivity = activityStack.get(i);
//                if(currentActivity.getClass().equals(activity.getClass())){
//                    currentActivity.finish();//銷燬當前的activity
//                    activityStack.remove(i);//從棧空間移除
//                }
//            }

            for(int i = activityStack.size() - 1;i >= 0;i--){
                Activity currentActivity = activityStack.get(i);
                if(currentActivity.getClass().equals(activity.getClass())){
                    currentActivity.finish();//銷燬當前的activity
                    activityStack.remove(i);//從棧空間移除
                }
            }
        }
    }

    //刪除當前的activity
    public void removeCurrent(){
        //方式一:
//        Activity activity = activityStack.get(activityStack.size() - 1);
//        activity.finish();
//        activityStack.remove(activityStack.size() - 1);

        //方式二:
        Activity activity = activityStack.lastElement();
        activity.finish();
        activityStack.remove(activity);
    }

    //刪除所有的activity
    public void removeAll(){
        for (int i = activityStack.size() - 1;i >= 0;i--){
            Activity activity = activityStack.get(i);
            activity.finish();
            activityStack.remove(activity);
        }
    }

    //返回棧大小
    public int size(){
        return activityStack.size();
    }
}

用法是在基類BaseActivity中進行初始化,並編寫操作方法。
在BaseActivity的onCreate方法中初始化管理器

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //將當前的Activity新增到ActivityManager中
        ActivityManager.getInstance().add(this);
    }
//啟動新的Activity
    public void goToActivity(Class Activity,Bundle bundle){
        Intent intent = new Intent(this,Activity);
        if (bundle!=null&&bundle.size()!=0){
            intent.putExtra("data",bundle);
        }
        startActivity(intent);
    }

    //銷燬當前的Activity
    public void removeCurrentActivity(){
        ActivityManager.getInstance().removeCurrent();
    }

    //銷燬所有的Activity
    public void removeAll(){
        ActivityManager.getInstance().removeAll();
    }

影象處理工具類BitmapUtils.class


import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;

/**
 * 作者: willkong on 2017/11/21.
 * 作用:影象處理工具類
 */
public class BitmapUtils {
    public static Bitmap circleBitmap(Bitmap source) {

        int width = source.getWidth();
        Bitmap bitmap = Bitmap.createBitmap(width, width, Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(bitmap);
        Paint paint = new Paint();
        paint.setAntiAlias(true);
        canvas.drawCircle(width / 2, width / 2, width / 2, paint);

        //設定圖片相交情況下的處理方式
        //setXfermode:設定當繪製的影象出現相交情況時候的處理方式的,它包含的常用模式有:
        //PorterDuff.Mode.SRC_IN 取兩層影象交集部分,只顯示上層影象
        //PorterDuff.Mode.DST_IN 取兩層影象交集部分,只顯示下層影象
        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));

        canvas.drawBitmap(source, 0, 0, paint);

        return bitmap;
    }

    //實現圖片的壓縮處理
    public static Bitmap zoom(Bitmap source,float w,float h){
        Matrix matrix = new Matrix();
        //圖片的壓縮處理
        matrix.postScale(w / source.getWidth(),h / source.getHeight());

        Bitmap bitmap = Bitmap.createBitmap(source,0,0,source.getWidth(),source.getHeight(),matrix,true);
        return bitmap;
    }
}