打包apk:
链接:https://pan.baidu.com/s/1qfyfZ-56Hg80U4KHFln0SQ?pwd=gqzd
提取码:gqzd
会有报毒,建议自己下autoxjs跑程序
一、演示视频
本地密码本【AutoJS】
二、源代码
"ui";
var storage = storages.create("mimaben"); //获取缓存
var dataList = storage.get('dataList', []); //Storage.get(key[, defaultValue])
dataList.reverse(); //逆序
toastLog("**获取缓存成功**");
var search_word = '' //搜索词
var search_res = [] //搜索结果
var curUI = 'indexUI' //当前页面 indexUI/addUI/editUI
var isCanFinish = false; //两次返回键退出脚本
showIndexUI();
ui.statusBarColor("#FF4FB3FF")
//显示首页
function showIndexUI() {
curUI = 'indexUI'
ui.layout(
<vertical w='*' h='*'>
<appbar>
<toolbar title="密码本" bg="#FF4FB3FF">
<button id="add" text="+" layout_gravity="right" style="Widget.AppCompat.Button.Borderless"></button>
</toolbar>
</appbar>
<linear w='*'>
<input id="search_word" singleLine="true" marginTop="5" layout_weight="1"></input>
<button id="search_btn" text="搜索"></button>
</linear>
<grid spanCount="1" id='dataList' h="*">
<card w="*" h="auto" margin="10 10 10 0" cardCornerRadius="6dp" cardElevation="2dp" gravity="center">
<vertical margin="10" layout_gravity="center_vertical" layout_weight="1">
<text size="18" color="#FF4FB3FF" text="{{this.name}}" />
<horizontal>
<text size="14" color="#C0C0C0" text="{{this.type}} " gravity="right" />
<text size="14" color="#C0C0C0" text="{{this.key}}" gravity="right" />
</horizontal>
<text size="16" color="#444444" text="账号:{{this.account}}" />
{/* <text size="16" color="#444444" text="密码:{{this.password}}" /> */}
<text size="16" color="#444444" text="备注:{{this.desc}}" />
<text size="16" color="#C0C0C0" text="关联:{{this.contact}}" />
</vertical>
</card>
</grid>
</vertical>
);
if (search_word == '') {
if (dataList.length == 0) {
var tempList = [{
type: "类别用于扩展分类功能",
name: "暂无记录,快去添加吧",
key: " 类别和关键词用于搜索",
account: " 点击卡片复制密码",
password: " 长按加号,退出",
contact: " 长按搜索,刷新",
desc: " 长按卡片,编辑",
id: "id:时间戳",
}]
ui.dataList.setDataSource(tempList);
} else {
ui.dataList.setDataSource(dataList);
}
}
else {
ui.search_word.setText(search_word);
ui.dataList.setDataSource(search_res);
}
//点击复制
ui.dataList.on("item_click", function (item, i) {
log('click_elem:', item.name)
setClip(item.password)
toast(item.password)
});
//长按,修改
ui.dataList.on("item_long_click", function (event, item, i) {
//log(e)//com.stardust.autojs.core.ui.nativeview.NativeView$LongClickEvent@116bf5c
//log(item)//{,}
//log(i)//1
showEditUI(item)
event.consumed = true;
});
//新增
ui.add.on("click", () => showAddUI());
//退出
ui.add.on("long_click", (event) => {
ui.finish();
event.consumed = true;
});
//长按搜索,清空搜索框,刷新页面
ui.search_btn.on("long_click", (event) => {
search_word = ''
ui.search_word.setText(search_word);
dataList = storage.get('dataList');
dataList.reverse();
ui.dataList.setDataSource(dataList);
toastLog("**获取缓存成功**");
event.consumed = true;
});
//搜索
ui.search_btn.on("click", () => {
search_word = ui.search_word.text();
log("搜索关键词:" + search_word);
if (search_word == '') {
search_res = []
ui.dataList.setDataSource(dataList)
} else {
for (var i of dataList) {
if (i.name.indexOf(search_word) != -1 || i.type.indexOf(search_word) != -1 || i.key.indexOf(search_word) != -1 || i.desc.indexOf(search_word) != -1) {
search_res.push(i)
}
}
//log("搜索结果:" + search_res);
if (search_res.length == 0) toast('无记录')
ui.dataList.setDataSource(search_res)
}
});
}
function showAddUI() {
curUI = 'addUI'
ui.layout(
<frame>
<vertical h="auto" gravity="center_vertical" marginTop="60">
<linear>
<text w="56" gravity="center" color="#111111" size="16">类别</text>
<input id="type" w="*" h="45" />
</linear>
<linear>
<text w="56" gravity="center" color="#111111" size="16">名称</text>
<input id="name" w="*" h="45" />
</linear>
<linear>
<text w="56" gravity="center" color="#111111" size="16">关键词</text>
<input id="key" w="*" h="45" />
</linear>
<linear>
<text w="56" gravity="center" color="#111111" size="16">账号</text>
<input id="account" w="*" h="45" />
</linear>
<linear>
<text w="56" gravity="center" color="#111111" size="16">密码</text>
<input id="password" w="*" h="45" />
</linear>
<linear>
<text w="56" gravity="center" color="#111111" size="16">关联</text>
<input id="contact" w="*" h="45" />
</linear>
<linear>
<text w="56" gravity="center" color="#111111" size="16">备注</text>
<input id="desc" w="*" h="45" />
</linear>
<linear gravity="center">
<button id="cancel">取消</button>
<button id="add">Add</button>
</linear>
</vertical>
</frame>
);
ui.add.on("click", () => {
var timestamp = new Date().getTime(); //精确到毫秒
var temp_add = {
type: ui.type.text(),
name: ui.name.text(),
key: ui.key.text(),
account: ui.account.text(),
password: ui.password.text(),
contact: ui.contact.text(),
desc: ui.desc.text(),
id: timestamp.toString(),//时间戳
}
log('add_elem:', temp_add.id);
dataList.reverse(); //先将数组正序
dataList.push(temp_add); //尾部追加
storage.put("dataList", dataList); //更新缓存
toastLog("【更新缓存】--Add")
dataList.reverse(); //再逆序
if (search_word != '') {
search_res.reverse();
search_res.push(temp_add);
search_res.reverse();
}
ui.type.setText('')
ui.name.setText('')
ui.key.setText('')
ui.account.setText('')
ui.password.setText('')
ui.contact.setText('')
ui.desc.setText('')
});
ui.cancel.on("click", () => showIndexUI());
}
function showEditUI(item) {
curUI = 'editUI'
ui.layout(
<frame>
<vertical h="auto" gravity="center_vertical" marginTop="40">
<linear gravity="center" >
<button id="id" style="Widget.AppCompat.Button.Borderless"></button>
</linear>
<linear>
<text w="56" gravity="center" color="#111111" size="16">类别</text>
<input id="type" w="*" h="45" />
</linear>
<linear>
<text w="56" gravity="center" color="#111111" size="16">名称</text>
<input id="name" w="*" h="45" />
</linear>
<linear>
<text w="56" gravity="center" color="#111111" size="16">关键词</text>
<input id="key" w="*" h="45" />
</linear>
<linear>
<text w="56" gravity="center" color="#111111" size="16">账号</text>
<input id="account" w="*" h="45" />
</linear>
<linear>
<text w="56" gravity="center" color="#111111" size="16">密码</text>
<input id="password" w="*" h="45" />
</linear>
<linear>
<text w="56" gravity="center" color="#111111" size="16">关联</text>
<input id="contact" w="*" h="45" />
</linear>
<linear>
<text w="56" gravity="center" color="#111111" size="16">备注</text>
<input id="desc" w="*" h="45" />
</linear>
<linear gravity="center">
<button id="cancel">取消</button>
<button id="edit">Edit</button>
<button id="delete">删除</button>
</linear>
</vertical>
</frame>
);
ui.type.setText(item.type)
ui.name.setText(item.name)
ui.key.setText(item.key)
ui.account.setText(item.account)
ui.password.setText(item.password)
ui.contact.setText(item.contact)
ui.desc.setText(item.desc)
ui.id.setText(item.id)
ui.edit.on("click", () => {
log('edit_elem:', item.name)
var temp_edit = {
type: ui.type.text(),
name: ui.name.text(),
key: ui.key.text(),
account: ui.account.text(),
password: ui.password.text(),
contact: ui.contact.text(),
desc: ui.desc.text(),
id: item.id,
}
var temp_dataList = dataList.filter(function (temp_item) {
return temp_item.id != item.id; //先删
});
//log(temp_dataList)
temp_dataList.reverse(); //正序
temp_dataList.push(temp_edit); //后加
storage.put("dataList", temp_dataList); //缓存
toastLog("【更新缓存】--Edit")
temp_dataList.reverse(); //逆序
dataList = temp_dataList
if (search_word != '') {
var temp_dataList = search_res.filter(function (temp_item) {
return temp_item.id != item.id;//先删
});
temp_dataList.reverse();
temp_dataList.push(temp_edit);//后加
temp_dataList.reverse();
search_res = temp_dataList
}
showIndexUI();
});
ui.delete.on("click", () => {
confirm("确定要删除吗?")
.then((ok) => {
if (ok) {
log('del_elem:', item.name)
var temp_dataList = dataList.filter(function (temp_item) {
return temp_item.id != item.id; //删除
});
temp_dataList.reverse(); //正序
storage.put("dataList", temp_dataList); //缓存
toastLog("【更新缓存】--Delete");
temp_dataList.reverse(); //逆序
dataList = temp_dataList
if (search_word != '') {
var temp_dataList = search_res.filter(function (temp_item) {
return temp_item.id != item.id;//删除
});
search_res = temp_dataList
}
showIndexUI();
}
});
});
ui.cancel.on("click", () => showIndexUI());
}
ui.emitter.on("back_pressed", e => {
if (curUI == 'addUI' || curUI == 'editUI') {
showIndexUI();
e.consumed = true;
} else if (search_word != '') {
search_word = ''
search_res = []
showIndexUI();
e.consumed = true;
} else {
if (!isCanFinish) {
toast("连续按两次返回键退出");
isCanFinish = true;
isCanFinishTimeout = setTimeout(() => {
isCanFinish = false;
}, 700);
e.consumed = true;
} else {
clearTimeout(isCanFinishTimeout);
e.consumed = false;
}
}
})
三、学习笔记
1.数据存储
没有用数据库,就是对象数组存在缓存中
[{
type: '类别',
key: '关键词',
name: '名称',
account: '账号',
password: '密码',
desc: '备注',
contact: '手机/邮箱',
id: '编号'
},
{
type: '类别',
key: '关键词',
name: '名称',
account: '账号',
password: '密码',
desc: '备注',
contact: '手机/邮箱',
id: '编号'
}]
var storage = storages.create("mimaben"); //创建一个本地存储并返回一个Storage对象。
storages.remove();//删除一个本地存储以及他的全部数据。
storage.put('dataList', dataList);
var dataList = storage.get('dataList', []); //Storage.get(key[, defaultValue])
storage.contains(key);//返回该本地存储是否包含键值为key的数据。
storage.remove(key);//移除键值为key的数据。不返回任何值。
storage.clear();//移除该本地存储的所有数据。不返回任何值。
2.按两次返回键退出脚本
var isCanFinish = false; //两次返回键退出脚本
ui.emitter.on("back_pressed", e => {
if (!isCanFinish) {
toast("连续按两次返回键退出");
isCanFinish = true;
isCanFinishTimeout = setTimeout(() => {
isCanFinish = false;
}, 700);
e.consumed = true;
} else {
clearTimeout(isCanFinishTimeout);
e.consumed = false;
}
})
3.点击、长按
//点击复制
ui.dataList.on("item_click", function (item, i) {
//log(item)//{,}
//log(i)//1
log('click_elem:', item.name)
setClip(item.password)
toast(item.password)
});
//长按,修改
ui.dataList.on("item_long_click", function (event, item, i) {
//log(e)//com.stardust.autojs.core.ui.nativeview.NativeView$LongClickEvent@116bf5c
//log(item)//{,}
//log(i)//1
showEditUI(item)
event.consumed = true;
});
//新增
ui.add.on("click", () => showAddUI());
//退出
ui.add.on("long_click", (event) => {
ui.finish();
event.consumed = true;
});