Flutter 仿QQ登錄下拉歷史列表案例

前言:

各位同學(xué)大家好,很長(zhǎng)一段時(shí)間沒(méi)有給大家更新文章了,之前發(fā)了一個(gè)Android 仿QQ登錄下拉歷史列表 (因?yàn)楣ぷ餍枰桶l(fā)一篇安卓的 算是基礎(chǔ)的常用功能實(shí)現(xiàn)吧)現(xiàn)在想著做一個(gè)
flutter的效果出來(lái),今天才把代碼擼好,就分享給大家 如果有什么錯(cuò)誤或者紕漏 希望大家指正,那么廢話(huà)不說(shuō) 我們正式開(kāi)始

效果圖:

QQ20200906-141737.png

QQ20200906-141839.png

QQ20200906-141907.png

準(zhǔn)備工作:

需要安裝flutter的開(kāi)發(fā)環(huán)境:大家可以去看看之前的教程:
1 win系統(tǒng)flutter開(kāi)發(fā)環(huán)境安裝教程: http://www.itdecent.cn/p/152447bc8718
2 mac系統(tǒng)flutter開(kāi)發(fā)環(huán)境安裝教程:http://www.itdecent.cn/p/bad2c35b41e3

需要用到三方庫(kù):

shared_preferences: "^0.4.2"
請(qǐng)大家在yaml 文件中添加依賴(lài)并且執(zhí)行flutter pub get 下載依賴(lài)

如圖:

QQ20200906-143825.png

我們的需求和明確,就是要把登錄成功的賬號(hào)密碼緩存保存好,然后并且顯示到歷史信息列表里面讓用戶(hù)可以自由切換已經(jīng)登錄過(guò)的賬號(hào)。

具體實(shí)現(xiàn):

QQ20200906-141737.png

登錄頁(yè)面實(shí)現(xiàn)

Container(
        margin: EdgeInsets.fromLTRB(20, 100, 20, 0),
        child: Column(
          children: <Widget>[
          TextField(
            controller: controller1,
          obscureText: false,
          decoration: InputDecoration(
            hintText: "請(qǐng)輸入賬號(hào)",
            border: InputBorder.none,
          ),
          onChanged: (value){
            setState(() {
              this._username=value;
            });
          },
          ),
            new Divider(
              height: 2.0,
              color: Colors.black54,
            ),
            TextField(
              controller: controller2,
              obscureText: false,
              decoration: InputDecoration(
                hintText: "請(qǐng)輸入密碼",
                border: InputBorder.none,
              ),
              onChanged: (value){
                setState(() {
                  this._password=value;
                });
              },
            ),
            new Divider(
              height: 2.0,
              color: Colors.black54,
            ),
            new Padding(padding: EdgeInsets.only(top: 20),
                child: Container(
                  width: double.infinity,
                  height: 40,
                  child: RaisedButton(
                    color: Colors.green,
                    textColor: Colors.white,
                    child: Text("登錄"),
                    onPressed: ()async{
                    User user=new User();
                    user.username=_username;
                    user.password=_password;
                    datalsit.add(user);
                    String jsonStringA = jsonEncode(datalsit);
                    print("jsonStringA   --------- >"+ jsonStringA);
                    SharedPreferences prefs = await SharedPreferences.getInstance();
                    prefs.setString("data",jsonStringA);
                    },
                  ),
                )
            ),
            new Padding(padding: EdgeInsets.only(top: 20),
                child: Container(
                  width: double.infinity,
                  height: 40,
                  child: RaisedButton(
                    color: Colors.green,
                    textColor: Colors.white,
                    child: Text("查看登錄歷史賬號(hào)信息"),
                    onPressed: ()async{
                      SharedPreferences prefs = await SharedPreferences.getInstance();
                      getdata = await prefs.getString("data");
                      print("getdata  ---  >"+getdata.toString());
                      showCustomDialog(context,getdata).then((value){
                        List  list= json.decode(getdata);
                        setState(() {
                          getusername=list[value]["username"];
                          getpassword=list[value]["password"];
                          controller1.text=getusername;
                          controller2.text=getpassword;
                        });
                        print(list[value]["username"]);
                        print(list[value]["password"]);
                      });
                    },
                  ),
                )
            )
          ],
        ),
      ),

登錄頁(yè)面我們寫(xiě)了兩個(gè)TextField和輸入框和兩個(gè) RaisedButton 按鈕的簡(jiǎn)單的布局當(dāng)我們點(diǎn)擊登錄按鈕的時(shí)候我們拿到賬號(hào)和密碼 通過(guò)SharedPreferences 存起來(lái)。
我們查閱了SharedPreferences 官方文檔使用 SharedPreferences 只能支持基本數(shù)據(jù)類(lèi)型和 string的集合所以不能滿(mǎn)足我們的需求,我這邊改變思路寫(xiě)了一個(gè)數(shù)據(jù)模型類(lèi):

class  User{
   String  username;
   String  password;
   User ({this.username,this.password});
   factory User .fromJson(Map<String,dynamic> json) {
     return User (
       username: json['username'],
       password: json['password'],
     );
   }

   Map toJson() {
     Map map = new Map();
     map["username"] = this.username;
     map["password"] = this.password;
     return map;
   }
}

在每次點(diǎn)擊登錄的時(shí)候我們 實(shí)例化User對(duì)象傳 設(shè)置值username password 屬性為我們輸入框拿到的值

  User user=new User();
  user.username=_username;
  user.password=_password;
  datalsit.add(user);

因?yàn)镾haredPreferences 是不支持存儲(chǔ) List<User>datalsit=new List();這種數(shù)據(jù)格式 所以我們需要把datalist 轉(zhuǎn)換成json字符串再存儲(chǔ) 這里我們需要用到dart里面自帶的 jsonEncode 需要引入dart:convert

import 'dart:convert';

數(shù)據(jù)存儲(chǔ)邏輯:

 String jsonStringA = jsonEncode(datalsit);
 print("jsonStringA   --------- >"+ jsonStringA);
 SharedPreferences prefs = await SharedPreferences.getInstance();
 prefs.setString("data",jsonStringA);

這樣我們就能把每次登錄的數(shù)據(jù)通過(guò)user實(shí)例化然后設(shè)置屬性 添加到datalist集合里面轉(zhuǎn)成json字符串并且通過(guò)緩存存儲(chǔ)起來(lái)了

歷史賬號(hào)彈窗的實(shí)現(xiàn):

import 'package:flutter/material.dart';
import 'dart:convert';
/***
 *
 *創(chuàng)建人:xuqing
 * 類(lèi)說(shuō)明:賬號(hào)歷史記錄彈窗
 * 創(chuàng)建時(shí)間:2020-9-5
 *
 *
 */
class   RecordDialog extends Dialog{
  String jsondata;
  RecordDialog({Key key, @required this.jsondata}) : super(key: key);
  List  list;
     @override
  Widget build(BuildContext context) {
     list= json.decode(jsondata);
    // TODO: implement build
       return new Material(
         //創(chuàng)建透明層
        type: MaterialType.transparency, //透明類(lèi)型
         child: new Center(
           //保證控件居中效果
           child: new SizedBox(
             width: 300.0,
             height: 200.0,
             child: new Container(
               color: Colors.white,
             child: ListView.builder(
                 itemCount:list.length==0?0:list.length,
                 itemBuilder: (BuildContext context, int  position){
                  return itemWidget(context,position);
                 }),
             ),
           ),
         ),
       );
  }
   Widget itemWidget(BuildContext context,int  index){
       return GestureDetector(
         child: Container(
           height: 40,
           width: double.infinity,
          child: Center(
            child:  Text("賬號(hào):"+list[index]["username"]),
          )
         onTap: (){
           Navigator.pop(context,index);
         },
       );
   }
}

在RecordDialog 定義了jsondata 也就換存的數(shù)據(jù)需要外部調(diào)用的時(shí)候需要需要外部傳入
然后在布局的地方我們通過(guò)Material中的 type: MaterialType.transparency, //透明類(lèi)型 實(shí)現(xiàn)了透明的效果
然后在Material 嵌套有個(gè)Center 組件來(lái)使得我們彈窗居中顯示 然后嵌套一個(gè) Container組件設(shè)置寬高 200 300 在Container 中嵌套listview 展示我們的緩存的賬號(hào)的列表

緩存數(shù)據(jù)的獲取

我們調(diào)用 SharedPreferences 中的 prefs.getString("data") 方法來(lái)獲取數(shù)據(jù)

 SharedPreferences prefs = await SharedPreferences.getInstance();
 getdata = await prefs.getString("data");
 print("getdata  ---  >"+getdata.toString());

我們?cè)诳刂婆_(tái)中捕捉到打印出的數(shù)據(jù)是含有了列表的json數(shù)據(jù)

[{
    "username": "xq9527",
    "password": "xq123456"
}, {
    "username": "wx1991",
    "password": "wx123456"
}, {
    "username": "zb1999",
    "password": "zb9377"
}]

我們?cè)赗ecordDialog 中拿到緩存的數(shù)據(jù) 我們需要通過(guò)調(diào)用 json.decode(需要引入dart:convert包) 來(lái)把json還原成list

List  list= json.decode(jsondata);

然后我們?cè)赗ecordDialog 中l(wèi)istview 里面的item里面調(diào)用 list[index]["username"] ;來(lái)展示
用戶(hù)點(diǎn)擊listview

 onTap: (){
           Navigator.pop(context,index); //通過(guò)調(diào)用    Navigator.pop 關(guān)閉RecordDialog  并且將點(diǎn)擊的下標(biāo)回調(diào)回去 
         },

RecordDialog 具體調(diào)用顯示

  //  RecordDialog  具體調(diào)用
  Future  showCustomDialog(BuildContext context,String getdata )async {
    var  result=await showDialog(
        context: context,
        builder: (BuildContext context) {
          return RecordDialog(jsondata: getdata,);
        });
    return result;
  }

這里我們 return 返回的result 就是用戶(hù)點(diǎn)擊 RecordDialog 列表的item的下標(biāo)我們可以通過(guò)這個(gè)下標(biāo)來(lái)獲取用戶(hù)是點(diǎn)擊的拿一條數(shù)據(jù)

  showCustomDialog(context,getdata).then((value){
    List  list= json.decode(getdata);
      setState(() {
           getusername=list[value]["username"];
            getpassword=list[value]["password"];
              controller1.text=getusername;
             controller2.text=getpassword;
               });
         print(list[value]["username"]);
         print(list[value]["password"]);
 });

我們拿到數(shù)據(jù)后臺(tái)需要調(diào)用 TextField 中的 controller屬性來(lái)將獲取到的getusername getpassword 賦值給
controller.text

  TextEditingController controller1 = TextEditingController();
  TextEditingController controller2 = TextEditingController();
   getusername=list[value]["username"];
   getpassword=list[value]["password"];
   controller1.text=getusername;
    controller2.text=getpassword;

這樣我們就把用戶(hù)點(diǎn)擊 RecordDialog 列表 中的賬號(hào)密碼填充到 賬號(hào)和密碼的 TextField 輸入框中
到此 Flutter 仿QQ登錄下拉歷史列表案例 功能實(shí)現(xiàn)我們就講完了 主要關(guān)鍵點(diǎn)是數(shù)據(jù)的存儲(chǔ) UI實(shí)現(xiàn)相對(duì)簡(jiǎn)單

最后總結(jié):

我是一名Android 游戲SDK開(kāi)發(fā)的人程序員 ,因?yàn)樽罱玫竭@個(gè)仿QQ下拉歷史列表的功能(之前很在就實(shí)現(xiàn)過(guò))之前寫(xiě)過(guò)一個(gè)Android 原生的 這個(gè)仿QQ下拉歷史列表的功能 ,今天就實(shí)現(xiàn)一個(gè)flutter版本的分享給各位
如果覺(jué)得文章還不錯(cuò)麻煩給個(gè)star 和轉(zhuǎn)發(fā)謝謝

項(xiàng)目地址:

碼云:https://gitee.com/qiuyu123/flutter_loginhistory.git

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀(guān)點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容