使用Android studio版本:3.2 JDK版本: jdk1.8.0_151
华为 mate s 测试不显示Log.d()部分手机解决方法 https://blog.youkuaiyun.com/HorrorKwan/article/details/78717122
项目介绍
记账APP核心功能
展示,添加,编辑,删除
运用到的知识
- 数据库设计
- 复杂视图的编写
- 一些设计要素
- 单例模式
- 适配器模式(RecycleView,ListView)
- 编写实战项目中的经验
功能拆分
- 视图 两个Activity 用于展示添加账目
- 持久化实现 SQLite 数据库编辑账目
- 工具类 实现简单的日期操作,资源管理
- 主要界面控件 TextView 用于展示星期/日期 Floating Button ViewPager Fragment List View Dialog(弹出式对话框)
- 添加账目界面控件 TextView Edit Text Recycler View 自定义键盘(Table Layout的使用) 时间选择控件
- 逻辑层 SQLlitOpenHelper RecordBean(账目的抽象数据结构) DateUtil 工具类 GlobaUtil 工具类用于全局资源提供
Android 中的持久化方案-- SQLite
Android 中的持久化技术有
- SharedPerferences
- 文件储存(SD卡)
- SQLite
认识SQLite
- 轻量级关系数据库
- 运算速度快
- 占用资源少
- 支持标准SQl语法
数据库中的基本元素
- 关系数据库
- 表:同一类记录的集合
- 字段:对应实体的属性
- 元祖:也叫 做记录,表中的每一行
数据库中的四个主要操作 CRUD
- 增,添加(Create)
- 删,删除(Delete)
- 改,更新(Update)
- 查,查询(Retrieve)
编写数据结构
数据库实现
RecordBean类
- 支出/收入
- 消费类别
- 消费金额
- 备注
- 日期
- 时间
UUID
通用唯一识别码(Universally Unique Identifier),在一台机器上生成的数字,它保证同一时空中所有机器都是唯一的。
新建 RecordBean 类
/**
* 数据结构
* @author SmallLetters@sina.com
*/
public class RecordBean {
private String TAG = "RecordBean";
/**
* 消费类别
*/
public enum RecordType {
//支出,收入
RECORD_TYPE_EXPENSE, RECORD_TYPE_INCOME
}
//消费额
private double amount;
private RecordType type;
private String category;
private String remark;
private String date;
private long timeStamp;
private String uuid;
/**
* 生成唯一识别码
*/
public RecordBean() {
uuid = UUID.randomUUID().toString();
timeStamp = System.currentTimeMillis();
date = DateUtil.getFormattedDate();
}
public String getTAG() {
return TAG;
}
public void setTAG(String TAG) {
this.TAG = TAG;
}
public double getAmount() {
return amount;
}
public void setAmount(double amount) {
this.amount = amount;
}
public int getType() {
if(this.type == RecordType.RECORD_TYPE_EXPENSE){
return 1;
}else {
return 0;
}
}
public void setType(int type) {
if (type == 1){
this.type = RecordType.RECORD_TYPE_EXPENSE;
}else {
this.type = RecordType.RECORD_TYPE_INCOME;
}
}
public String getCategory() {
return category;
}
public void setCategory(String category) {
this.category = category;
}
public String getRemark() {
return remark;
}
public void setRemark(String remark) {
this.remark = remark;
}
public String getDate() {
return date;
}
public void setDate(String date) {
this.date = date;
}
public long getTimeStamp() {
return timeStamp;
}
public void setTimeStamp(long timeStamp) {
this.timeStamp = timeStamp;
}
public String getUuid() {
return uuid;
}
public void setUuid(String uuid) {
this.uuid = uuid;
}
}
编写日期工具类
新建DateUtil 类
/**
* @author SmallLetters@sina.com
*/
public class DateUtil {
/**
*unix time -> 23:43
* @param timeStamp
* @return HH:mm 当前时间
*/
public static String getFormattedTime(long timeStamp){
// yyyy-MM-dd HH:mm:ss
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("HH:mm");
return simpleDateFormat.format(new Date(timeStamp));
}
/**
* @return yyyy-MM-dd 当前时间
*/
public static String getFormattedDate(){
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
return simpleDateFormat.format(new Date());
}
}
编写数据库操作类
数据增删改查
新建RecordDatabaseHeleper 类 extends(继承) SQLiteOpenHelper
/**
* 数据库操作类
*
* @author SmallLetters@sina.com
*/
public class RecordDatabaseHeleper extends SQLiteOpenHelper {
public static final String BD_NAME = "Record";
public static final String CREATE_RECORD_DB = "create table Record("
+ "id integer primary key autoincrement,"
+ "uuid text,"
+ "type integer,"
+ "category text,"
+ "remark text,"
+ "amount double,"
+ "time integer,"
+ "date date)";
public RecordDatabaseHeleper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
super(context, name, factory, version);
}
@Override
public void onCreate(SQLiteDatabase sqLiteDatabase) {
sqLiteDatabase.execSQL(CREATE_RECORD_DB);
}
@Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
}
/**
* 增,添加数据
*
* @param bean
*/
public void addRecord(RecordBean bean) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put("uuid", bean.getUuid());
contentValues.put("type", bean.getType());
contentValues.put("category", bean.getCategory());
contentValues.put("remark", bean.getRemark());
contentValues.put("amount", bean.getAmount());
contentValues.put("time", bean.getTimeStamp());
contentValues.put("date", bean.getDate());
db.insert(BD_NAME, null, contentValues);
}
/**
* 删除数据
*
* @param uuid
*/
public void removeRecord(String uuid) {
SQLiteDatabase db = this.getWritableDatabase();
db.delete(BD_NAME, "uuid=?", new String[]{uuid});
}
/**
* 更改
*
* @param uuid
* @param record
*/
public void editRecord(String uuid, RecordBean record) {
//根据uuid删除当前数据
removeRecord(uuid);
//设置uuid
record.setUuid(uuid);
//添加数据
addRecord(record);
}
/**
* 根据日期查询数据 按大到小排序
* @param dateStr 日期
* @return RecordBean
*/
public LinkedList<RecordBean> readRecords(String dateStr){
LinkedList<RecordBean> records =new LinkedList<>();
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery("select DISTINCT * from Record where date = ? order by time asc",new String[]{dateStr});
if (cursor.moveToFirst()){
do {
String uuid = cursor.getString(cursor.getColumnIndex("uuid"));
int type = cursor.getInt(cursor.getColumnIndex("type"));
String category =cursor.getString(cursor.getColumnIndex("category"));
String remark = cursor.getString(cursor.getColumnIndex("remark"));
double amount = cursor.getDouble(cursor.getColumnIndex("amount"));
String date = cursor.getString(cursor.getColumnIndex("date"));
long timeStamp =cursor.getLong(cursor.getColumnIndex("timeStamp"));
RecordBean recordBean = new Record