使用Android studio版本:3.2 JDK版本: jdk1.8.0_151
华为 mate s 测试不显示Log.d()部分手机解决方法 https://blog.csdn.net/HorrorKwan/article/details/78717122
记账APP核心功能
展示,添加,编辑,删除
Android 中的持久化技术有
认识SQLite
数据库中的基本元素
数据库中的四个主要操作 CRUD
数据库实现
RecordBean类
UUID
通用唯一识别码(Universally Unique Identifier),在一台机器上生成的数字,它保证同一时空中所有机器都是唯一的。
新建 RecordBean 类
/**
* 数据结构
* @author [email protected]
*/
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 [email protected]
*/
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 [email protected]
*/
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 readRecords(String dateStr){
LinkedList 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 RecordBean();
recordBean.setUuid(uuid);
recordBean.setType(type);
recordBean.setCategory(category);
recordBean.setRemark(remark);
recordBean.setAmount(amount);
recordBean.setDate(date);
recordBean.setTimeStamp(timeStamp);
records.add(recordBean);
}while (cursor.moveToNext());
}
cursor.close();
return records;
}
/**
* 获取有账目的日期
* @return
*/
public LinkedList getAvaliableDate(){
LinkedList dates = new LinkedList<>();
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery("select DISTINCT * from Record order by date asc",new String[]{});
if (cursor.moveToFirst()){
do {
String date = cursor.getString(cursor.getColumnIndex("date"));
if (!dates.contains(date)){
dates.add(date);
}
}while (cursor.moveToNext());
}
cursor.close();
return dates;
}
}
1.主界面功能 此处省略。。。
2.引入第三方开源库 这里作者使用的是 GitHub 搜索 ticker 然后根据使用方法应用
添加到 build.gradle (Mobule:app) 下 的
dependencies{
}
里面
首先在布局文件按CTRL+alt+shift+s 选择Dependencies 增加
com.android.support:support-v13:28.0.0
com.android.support:design:28.0.0
这两个依赖
然后下载图标 + 我是在 https://material.io/icons 下载的 然后复制到res文件夹下
下面是布局代码
效果图:
在代码部分 输入
getSupportActionBar().setElevation(0); 阴影就去除了
新建布局 content_main layout 写RelativeLayout
在activity_main 中引入content_main 布局
下面是content_main布局
新建布局 fragment_main
/**
* @author SmallLetters
*/
@SuppressLint("ValidFragment")
public class MainFragment extends Fragment {
private View mrootView;
private TextView mtextView;
private ListView mlistView;
private String date = "";
@SuppressLint("ValidFragment")
public MainFragment(String date){
this.date = date;
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
mrootView = inflater.inflate(R.layout.fragment_main,container,false);
initView();
return mrootView;
}
private void initView(){
mtextView = mrootView.findViewById(R.id.day_text);
mlistView = mrootView.findViewById(R.id.listView);
mtextView.setText(date);
}
}
新建MainViewPagerAdapter 继承 FragmentPagerAdapter
/**
* @author SmallLetters
*/
public class MainViewPagerAdapter extends FragmentPagerAdapter {
LinkedList fragments = new LinkedList<>();
LinkedList datas = new LinkedList<>();
public MainViewPagerAdapter(FragmentManager fm) {
super(fm);
initFragments();
}
@Override
public Fragment getItem(int i) {
return fragments.get(i);
}
@Override
public int getCount() {
return fragments.size();
}
private void initFragments(){
//测试数据
datas.add("2018-10-07");
datas.add("2018-10-08");
datas.add("2018-10-09");
//循环出有账目的日期
for (String date:datas){
//设置日期
MainFragment fragment = new MainFragment(date);
fragments.add(fragment);
}
}
/**
* 获取总日期数量
* @return 最后一次记账的日期
*/
public int getLastIndex(){
return fragments.size()-1;
}
}
package com.sina.smallletters;
import android.os.Bundle;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
/**
* @author [email protected]
*/
public class MainActivity extends AppCompatActivity {
private ViewPager viewPager;
private MainViewPagerAdapter pagerAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
RecordBean recordBean = new RecordBean();
viewPager = findViewById(R.id.view_pager);
//布局阴影设置为0
getSupportActionBar().setElevation(0);
pagerAdapter = new MainViewPagerAdapter(getSupportFragmentManager());
//更新
pagerAdapter.notifyDataSetChanged();
//设置ViewPager ->content_main.xml
viewPager.setAdapter(pagerAdapter);
//显示顺序
viewPager.setCurrentItem(pagerAdapter.getLastIndex());
}
}
drawable 下 新建circle .xml 图片背景文件
Layout 下新建 cell_list_view -> RelativeLayout
配置ListView Adapter
新建ListViewAdapter 继承 BaseAdapter
/**
* @author SmallLetters
*/
public class ListViewAdapter extends BaseAdapter {
private LinkedList records = new LinkedList<>();
private LayoutInflater minflater;
private Context mcontext;
public ListViewAdapter (Context context){
this.mcontext=context;
minflater = LayoutInflater.from(mcontext);
}
public void setData(LinkedList record){
this.records=record;
//更新
notifyDataSetChanged();
}
@Override
public int getCount() {
return records.size();
}
@Override
public Object getItem(int i) {
return records.get(i);
}
@Override
public long getItemId(int i) {
return i;
}
@Override
public View getView(int i, View view, ViewGroup viewGroup) {
ViewHolder holder;
if (view == null){
view=minflater.inflate(R.layout.cell_list_view,null);
RecordBean recordBean = (RecordBean) getItem(i);
holder = new ViewHolder(view,recordBean);
view.setTag(holder);
}else {
holder = (ViewHolder) view.getTag();
}
return view;
}
class ViewHolder{
TextView remarkTV;
TextView amountTV;
TextView timeTV;
ImageView categoryIcon;
public ViewHolder(View view,RecordBean recordBean){
remarkTV = view.findViewById(R.id.textView_remark);
amountTV=view.findViewById(R.id.textView_amount);
timeTV=view.findViewById(R.id.textView_time);
categoryIcon=view.findViewById(R.id.imageView_category);
}
}
}
然后在MainFragment 类里 添加
private LinkedList records = new LinkedList<>();
private ListViewAdapter listViewAdapter;
在MainFragment 类initView()方法中添加
//测试数据
records.add(new RecordBean());
records.add(new RecordBean());
records.add(new RecordBean());
listViewAdapter = new ListViewAdapter(getContext());
listViewAdapter.setData(records);
mlistView.setAdapter(listViewAdapter);
if (listViewAdapter.getCount() > 0){
mrootView.findViewById(R.id.no_record_layout).setVisibility(View.INVISIBLE);
}
新建activity_add_record.xml
新建AddRecordActivity 类
/**
* @author SmallLetters
*/
public class AddRecordActivity extends AppCompatActivity implements View.OnClickListener {
private static String TAG ="AddRecordActivity";
private TextView amountText;
/**
* 用来存储键盘输入的数
*/
private String userInput=" ";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_add_record);
findViewById(R.id.keyboard_one).setOnClickListener(this);
findViewById(R.id.keyboard_two).setOnClickListener(this);
findViewById(R.id.keyboard_three).setOnClickListener(this);
findViewById(R.id.keyboard_four).setOnClickListener(this);
findViewById(R.id.keyboard_five).setOnClickListener(this);
findViewById(R.id.keyboard_six).setOnClickListener(this);
findViewById(R.id.keyboard_seven).setOnClickListener(this);
findViewById(R.id.keyboard_eight).setOnClickListener(this);
findViewById(R.id.keyboard_nine).setOnClickListener(this);
findViewById(R.id.keyboard_zero).setOnClickListener(this);
amountText = findViewById(R.id.TextView_amount);
handleType();
handleDot();
handleBackspace();
handleDone();
}
/**
* 点
*/
private void handleDot(){
findViewById(R.id.keyboard_dot).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Log.d(TAG,"dot");
if (!userInput.contains(".")){
userInput += ".";
}
}
});
}
/**
* 支出/收入
*/
private void handleType(){
findViewById(R.id.keyboard_type).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Log.d(TAG,"type");
}
});
}
/**
* 删除/
*/
private void handleBackspace(){
findViewById(R.id.keyboard_backspace).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (userInput.length()>0){
//userInput有值 删除一个数
userInput=userInput.substring(0,userInput.length()-1);
}
if (userInput.length()>0 && userInput.charAt(userInput.length()-1)=='.'){
//如果userInput有值 与 最后一个数是 . 删除一个数
userInput=userInput.substring(0,userInput.length()-1);
}
//更新amountText
updateAmountText();
}
});
}
/**
*完成
*/
private void handleDone(){
findViewById(R.id.keyboard_done).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (userInput.equals("")){
//把输入的字符串类型的数转换成 double类型
double amount = Double.valueOf(userInput);
}else {
}
}
});
}
@Override
public void onClick(View view) {
Button button = (Button) view;
String intent=button.getText().toString();
Log.d(TAG,intent);
if (userInput.contains(".")){
//userInput 有 .
if (userInput.split("\\.").length==1 || userInput.split("\\.")[1].length()< 2 ){
//11.11 小数点后面 只能是两位数
userInput += intent;
}
}else {
//没有小数点
userInput += intent;
}
updateAmountText();
}
/**
* 键盘输入设置TextView_amuont
*/
private void updateAmountText() {
if (userInput.contains(".")){
//有小数点
if (userInput.split("\\.").length == 1){
//只有一个点
amountText.setText(userInput+"00");
}else if (userInput.split("\\.")[1].length()==1){
//小数点后面有一位数
amountText.setText(userInput+"0");
}else if (userInput.split("\\.")[1].length()==2){
//小数点后面有两位数
amountText.setText(userInput);
}
}else {
if (userInput.equals("")){
//没有数
amountText.setText("0.00");
}else {
//输入的是整数
amountText.setText(userInput+".00");
}
}
}
}
未完成 待续