Android仿QQ登录下拉历史列表

龙旋

共 12102字,需浏览 25分钟

 ·

2021-12-31 11:50

效果图




我们的需求和明确,就是要把登录成功的账号密码缓存保存好,然后并且显示到历史信息列表里面让用户可以自由切换已经登录过的账号。


具体实现


我这边是写了一个数据模型bean类 selectphone;

package com.example.accountrecord/*** * 用户登录信息 */public class SelectPhone  {        private String account_id;        private String name;        private String password;        private String user_type;        private String token;        public String getName() {            return name;        }        public void setName(String name) {            this.name = name;        }        public String getToken() {            return token;        }        public void setToken(String token) {            this.token = token;        }        public String getUser_type() {            return user_type;        }        public void setUser_type(String user_type) {            this.user_type = user_type;        }        public String getPassword() {            return password;        }        public void setPassword(String password)             this.password = password;        }       public String getAccount_id() {         return account_id;       }        public void setAccount_id(String account_id) {        this.account_id = account_id;       }}


然后在将多条selectphone 存储在list集合里面 使用的存储方案是安卓自带的 SharedPreferences


但是SharedPreferences 默认只支持基础数据类型 所以我们要做简单的转换改造 将list转成json字符串存起来 获取的适合我们再讲json还原成list集合


存储

 /**     * 4.存储账本SelectPhone的list     */    public static void putSelectBean(Context context, List phoneList, String key) {        if (sp == null) {            sp = context.getSharedPreferences("config", MODE_PRIVATE);        }        SharedPreferences.Editor editor = sp.edit();        Gson gson = new Gson();        String json = gson.toJson(phoneList);        editor.putString(key, json);        editor.commit();    }


读取

 /**     * 读取账本SelectPhone的list     */    public static List getSelectBean(Context context, String key) {        if (sp == null) {            sp = context.getSharedPreferences("config", MODE_PRIVATE);        }        Gson gson = new Gson();        String json = sp.getString(key, null);        Type type = new TypeToken>() {        }.getType();        List arrayList = gson.fromJson(json, type);        return arrayList;    }


loginActivity中具体调用存储数据

 private  void  login(){        account=account_ed.getText().toString();        password=password_ed.getText().toString();        if(TextUtils.isEmpty(account)||TextUtils.isEmpty(password)){            Toast.makeText(mContext,"账号或者密码输入不能为空",Toast.LENGTH_LONG).show();        }        SelectPhone selectPhone=new SelectPhone();        selectPhone.setName(account);        selectPhone.setPassword(password);        List getdata = SharedPreferencesUtils.getSelectBean(LoginActivity.this,       "selectphone");        if (getdata != null && getdata.size() > 0) {            getdata.add(0,selectPhone);            SharedPreferencesUtils.putSelectBean(LoginActivity.this, getdata, "selectphone");        } else {            data.add(selectPhone);            SharedPreferencesUtils.putSelectBean(LoginActivity.this, data, "selectphone");        }        Toast.makeText(mContext,"登录成功数据缓存成功",Toast.LENGTH_LONG).show();        finish();    }





弹出的popupwindow 具体实现:


布局代码

    xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    >
android:layout_width="300dp" android:layout_height="148.44dp" android:background="@color/activityTextWhite" android:layout_centerHorizontal="true" > android:id="@+id/select_listview" android:layout_width="match_parent" android:layout_height="match_parent">


具体逻辑代码:

/** * 自定义PopupWindow  主要用来显示ListView * * @param  * @param  * @create time */public class SpinerPopWindow extends PopupWindow {    private static final String TAG = "SpinerPopWindow";    private LayoutInflater inflater;    private ListView mListView;    private List list;    private MyAdapter mAdapter;    private Context context;    private RemoveUserinfoListner removeUserinfoListner;
public SpinerPopWindow(Context context, List list, OnItemClickListener clickListener, RemoveUserinfoListner removeUserinfoListner) { super(context); inflater = LayoutInflater.from(context); this.list = list; this.context = context; this.removeUserinfoListner = removeUserinfoListner; init(clickListener); }
private void init(OnItemClickListener clickListener) { //View view = inflater.inflate(R.layout.select_phonedialog, null); View view = inflater.inflate(ResourceUtil.getLayoutId(context, "select_phonedialog"), null); setContentView(view); setFocusable(true); setWidth(ViewGroup.LayoutParams.WRAP_CONTENT); setHeight(ViewGroup.LayoutParams.WRAP_CONTENT); ColorDrawable dw = new ColorDrawable(0x00); setBackgroundDrawable(dw); //mListView = view.findViewById(R.id.select_listview); mListView = view.findViewById(ResourceUtil.getId(context, "select_listview")); mAdapter = new MyAdapter(); if (list != null) { mListView.setAdapter(mAdapter); } mListView.setOnItemClickListener(clickListener); }
private class MyAdapter extends BaseAdapter { @Override public int getCount() {
return list.size(); }
@Override public Object getItem(int position) { return list.get(position); }
@Override public long getItemId(int position) { return position; }
@Override public View getView(final int position, View convertView, ViewGroup parent) { final SelectPhone selectPhone = (SelectPhone) list.get(position); ViewHodler hodler = null; if (convertView == null) { convertView = LayoutInflater.from(context).inflate(ResourceUtil.getLayoutId(context, "selectphone_item"), parent, false); hodler = new ViewHodler(); hodler.phonetextview = convertView.findViewById(ResourceUtil.getId(context, "account_textview"));//account_textview //account_image hodler.imageview = convertView.findViewById(ResourceUtil.getId(context, "account_image")); hodler.deleterl = convertView.findViewById(ResourceUtil.getId(context, "delete_account_rl")); convertView.setTag(hodler); } else { hodler = (ViewHodler) convertView.getTag(); } hodler.phonetextview.setText(selectPhone.getName()); //操作删除存在对象里面的数据刷新listview hodler.deleterl.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // data.remove(position); DeleteaccountDialog deleteaccountDialog = new DeleteaccountDialog(context, selectPhone.getName(), new Deleteaccountlistener() { @Override public void deleteaccountsuccess() { notifyDataSetChanged(); removeUserinfoListner.removeuserinfosuccess(position, (List) list); } }); deleteaccountDialog.show(); } }); return convertView; } public class ViewHodler { TextView phonetextview; ImageView imageview; RelativeLayout deleterl; } }}



删除弹窗dialog的实现:


布局文件

    xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"    android:layout_height="match_parent">            android:layout_width="316dp"        android:layout_height="180.89dp"        android:layout_centerHorizontal="true"        android:layout_centerVertical="true"        android:background="@drawable/activity_background_white"        android:orientation="vertical"        >                    android:layout_width="match_parent"            android:layout_height="124.44dp"            android:orientation="vertical"            >                            android:layout_width="wrap_content"                android:layout_height="wrap_content"                android:layout_marginTop="23.11dp"                android:text="删除账号记录"                android:textColor="@color/activityTitle"                android:textSize="23.11dp"                android:layout_gravity="center"                />                    android:id="@+id/deleteaccount_text"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:text="确认删除账号[XQ123456]"            android:layout_gravity="center"             android:textSize="18.67dp"            android:textColor="@color/activityTitle"            android:layout_marginTop="24dp"            />                            android:layout_width="match_parent"            android:layout_height="1.33dp"            android:background="@color/activityTextMainClor"            >                    android:layout_width="match_parent"            android:layout_height="match_parent"            android:orientation="horizontal"            >                            android:id="@+id/deleteaccount_cancel"                android:layout_width="0dp"                android:layout_height="match_parent"                android:layout_weight="1"                >                                    android:layout_width="wrap_content"                    android:layout_height="match_parent"                    android:layout_centerHorizontal="true"                    android:gravity="center"                    android:text="取消"                    android:textSize="24dp"                    android:textColor="@color/smsedittextcolor"                    />                                        android:layout_width="1.33dp"                android:layout_height="match_parent"                android:background="@color/activityTextMainClor"                >                            android:id="@+id/deleteaccount_confirm"                android:layout_width="0dp"                android:layout_height="match_parent"                android:layout_weight="1">                                    android:layout_width="wrap_content"                    android:layout_height="match_parent"                    android:layout_centerHorizontal="true"                    android:gravity="center"                    android:text="确定"                    android:textSize="24dp"                    android:textColor="@color/activityBlueButton"                    />                        


逻辑代码:

/** * 类说明:删除账号是否确认弹窗 */public class DeleteaccountDialog extends Dialog {    private Context context;    private RelativeLayout cancel, confirm;    private TextView accounttext;    private Deleteaccountlistener deleteaccountlistener;    private String account;    public DeleteaccountDialog(Context context, String account, Deleteaccountlistener            deleteaccountlistener) {        super(context);        this.context = context;        this.account = account;        this.deleteaccountlistener = deleteaccountlistener;    }    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        getWindow().setBackgroundDrawableResource(android.R.color.transparent);        getWindow().requestFeature(Window.FEATURE_NO_TITLE);        LayoutInflater inflater = (LayoutInflater) context                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);        View layout = inflater.inflate(ResourceUtil.getLayoutId(context,                "deleteaccount_dialog"), null);        setContentView(layout);        initview();    }    private void initview() {        cancel = findViewById(ResourceUtil.getId(context, "deleteaccount_cancel"));        confirm = findViewById(ResourceUtil.getId(context, "deleteaccount_confirm"));        accounttext = findViewById(ResourceUtil.getId(context, "deleteaccount_text"));        accounttext.setText("确定删除账号[" + account + "]");        //删除账号取消        cancel.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                DeleteaccountDialog.this.dismiss();            }        });        //确定删除账号        confirm.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                DeleteaccountDialog.this.dismiss();                deleteaccountlistener.deleteaccountsuccess();            }        });    }}


我们在loginactivity中调用自定义的popupwindow 显示列表的时候我们要注意几个回调,首先看具体调用

getdata = SharedPreferencesUtils.getSelectBean(mContext, "selectphone");        if (getdata != null && getdata.size() > 0) {            SelectPhone phone = getdata.get(0);            cacheaccount = phone.getName();            cachepsw=phone.getPassword();
if (!TextUtils.isEmpty(cacheaccount)) { account_ed.setText(cacheaccount); password_ed.setText(cachepsw); } else { account_ed.setText(null); password_ed.setText(null); } } mSpinerPopWindow = new SpinerPopWindow(LoginActivity.this, getdata, itemClickListener, removeUserinfoListner); mSpinerPopWindow.setOnDismissListener(dismissListener);


用户点击列表里面的某一条信息的回调监听

 /**     * popupwindow显示的ListView的item点击事件     */    private AdapterView.OnItemClickListener itemClickListener = new AdapterView.OnItemClickListener() {        @Override        public void onItemClick(AdapterView parent, View view, int position, long id) {            mSpinerPopWindow.dismiss();            flag = false;            SelectPhone selectPhone = getdata.get(position);            String getusername = selectPhone.getName();            String psw = selectPhone.getPassword();            account_ed.setText(getusername);            password_ed.setText(psw);
} };


用户点击空白部分的监听:

 /**     * 监听popupwindow取消     */    private PopupWindow.OnDismissListener dismissListener = new PopupWindow.OnDismissListener(){        @Override        public void onDismiss() {            flag = false;        }    };


用户点击确认删除按钮的监听:

 //删除用户缓存信息    private RemoveUserinfoListner removeUserinfoListner = new RemoveUserinfoListner() {        @Override        public void removeuserinfosuccess(int position, List data) {            if (data != null && data.size() > 0) {                data.remove(position);                SharedPreferencesUtils.putSelectBean(mContext, data, "selectphone");                flag = false;                List getdata = SharedPreferencesUtils.                        getSelectBean(LoginActivity.this, "selectphone");                if (getdata != null && getdata.size() > 0) {                    SelectPhone selectPhone = getdata.get(0);                    account_ed.setText(selectPhone.getName());                    password_ed.setText(selectPhone.getPassword());                } else {                    account_ed.setText(null);                    password_ed.setText(null);                }            } else {                Toast.makeText(mContext,"缓存数据为空",Toast.LENGTH_LONG).show();            }        }    };


我们需要在相应的用户操作的监听回调里面去更新一些UI来满足我们的需求,最后完整的loginactivity 的布局代码和 java逻辑代码看demo。

到此整个仿QQ的登录下拉历史功能实现基本讲完了 主要关键点是数据存储的逻辑要注意, UI实现相对简单。


源码地址:

https://github.com/xq19930522/accountrecord_demo


到这里就结束啦。

浏览 18
点赞
评论
收藏
分享

手机扫一扫分享

举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

举报