前言:
各位同學(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)始
效果圖:



準(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)
如圖:

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

登錄頁(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ā)謝謝