diff --git a/simple-bookkeeping-master/.gitignore b/simple-bookkeeping-master/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/simple-bookkeeping-master/.gitignore @@ -0,0 +1,14 @@ +*.iml +.gradle +/local.properties +/.idea/caches +/.idea/libraries +/.idea/modules.xml +/.idea/workspace.xml +/.idea/navEditor.xml +/.idea/assetWizardSettings.xml +.DS_Store +/build +/captures +.externalNativeBuild +.cxx diff --git a/simple-bookkeeping-master/.idea/.gitignore b/simple-bookkeeping-master/.idea/.gitignore new file mode 100644 index 0000000..26d3352 --- /dev/null +++ b/simple-bookkeeping-master/.idea/.gitignore @@ -0,0 +1,3 @@ +# Default ignored files +/shelf/ +/workspace.xml diff --git a/simple-bookkeeping-master/.idea/.name b/simple-bookkeeping-master/.idea/.name new file mode 100644 index 0000000..b931945 --- /dev/null +++ b/simple-bookkeeping-master/.idea/.name @@ -0,0 +1 @@ +tally \ No newline at end of file diff --git a/simple-bookkeeping-master/.idea/codeStyles/Project.xml b/simple-bookkeeping-master/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/simple-bookkeeping-master/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +
+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+
+
+
+
+
\ No newline at end of file diff --git a/simple-bookkeeping-master/.idea/compiler.xml b/simple-bookkeeping-master/.idea/compiler.xml new file mode 100644 index 0000000..61a9130 --- /dev/null +++ b/simple-bookkeeping-master/.idea/compiler.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/simple-bookkeeping-master/.idea/dbnavigator.xml b/simple-bookkeeping-master/.idea/dbnavigator.xml new file mode 100644 index 0000000..70f212e --- /dev/null +++ b/simple-bookkeeping-master/.idea/dbnavigator.xml @@ -0,0 +1,414 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/simple-bookkeeping-master/.idea/gradle.xml b/simple-bookkeeping-master/.idea/gradle.xml new file mode 100644 index 0000000..a2d7c21 --- /dev/null +++ b/simple-bookkeeping-master/.idea/gradle.xml @@ -0,0 +1,19 @@ + + + + + + + \ No newline at end of file diff --git a/simple-bookkeeping-master/.idea/jarRepositories.xml b/simple-bookkeeping-master/.idea/jarRepositories.xml new file mode 100644 index 0000000..eb2873e --- /dev/null +++ b/simple-bookkeeping-master/.idea/jarRepositories.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/simple-bookkeeping-master/.idea/misc.xml b/simple-bookkeeping-master/.idea/misc.xml new file mode 100644 index 0000000..d5d35ec --- /dev/null +++ b/simple-bookkeeping-master/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/simple-bookkeeping-master/.idea/vcs.xml b/simple-bookkeeping-master/.idea/vcs.xml new file mode 100644 index 0000000..830a534 --- /dev/null +++ b/simple-bookkeeping-master/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/simple-bookkeeping-master/README.md b/simple-bookkeeping-master/README.md new file mode 100644 index 0000000..2e8ea74 --- /dev/null +++ b/simple-bookkeeping-master/README.md @@ -0,0 +1,23 @@ +# 简约记账 + +#### 介绍 + 项目名称: 简约记账 + 项目描述:基于安卓基础知识点开发的个人记账工具,其中包括记录当天收支情况,计算当天以及当月共收支总钱数,能查看历史账单,能对于每月收支情况进行图标分析,百分比分析, + 能够搜索用户关于某种记录的全部收支情况等功能。基本上能够解决个人记账的所有问题,界面简约美观,滑动流畅。 + 项目重要技术点: + 1-绘制布局,掌握android基本view控件的属性和使用 + 2-熟练掌握Activity页面展示,跳转和传值 + 3-使用碎片加载界面,滑动视图切换页面 + 4-自定义对话框 + 5-自定义软键盘绘制和使用 + 6-列表视图以及网格视图的适配器使用和页面加载 + 7-使用Android自带数据库,熟练创建表,并进行增删改查 + 8-定义drawable文件,设定布局以及控件样式 + 9-使用MPAndroidChart第三方框架绘制柱状图 + + + + + + + diff --git a/simple-bookkeeping-master/app/.gitignore b/simple-bookkeeping-master/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/simple-bookkeeping-master/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/simple-bookkeeping-master/app/build.gradle b/simple-bookkeeping-master/app/build.gradle new file mode 100644 index 0000000..bb23e24 --- /dev/null +++ b/simple-bookkeeping-master/app/build.gradle @@ -0,0 +1,32 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 29 + buildToolsVersion "29.0.3" + defaultConfig { + applicationId "com.hui.tally" + minSdkVersion 21 + targetSdkVersion 29 + versionCode 1 + versionName "1.0" + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'androidx.constraintlayout:constraintlayout:2.0.2' + implementation 'androidx.legacy:legacy-support-v4:1.0.0' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.2' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0' + implementation 'com.google.android.material:material:1.2.0' + implementation 'com.github.PhilJay:MPAndroidChart:v3.0.2' +} diff --git a/simple-bookkeeping-master/app/proguard-rules.pro b/simple-bookkeeping-master/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /dev/null +++ b/simple-bookkeeping-master/app/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile diff --git a/simple-bookkeeping-master/app/src/androidTest/java/com/hui/tally/ExampleInstrumentedTest.java b/simple-bookkeeping-master/app/src/androidTest/java/com/hui/tally/ExampleInstrumentedTest.java new file mode 100644 index 0000000..ce7a8cd --- /dev/null +++ b/simple-bookkeeping-master/app/src/androidTest/java/com/hui/tally/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package com.hui.tally; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.hui.tally", appContext.getPackageName()); + } +} diff --git a/simple-bookkeeping-master/app/src/main/AndroidManifest.xml b/simple-bookkeeping-master/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..b8dad5c --- /dev/null +++ b/simple-bookkeeping-master/app/src/main/AndroidManifest.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/simple-bookkeeping-master/app/src/main/assets/项目介绍.txt b/simple-bookkeeping-master/app/src/main/assets/项目介绍.txt new file mode 100644 index 0000000..e632655 --- /dev/null +++ b/simple-bookkeeping-master/app/src/main/assets/项目介绍.txt @@ -0,0 +1,17 @@ +项目名称: 简约记账 +开发工具:Android Studio +项目描述:基于安卓基础知识点开发的个人记账工具,其中包括记录当天收支情况,计算当天以及当月共收支总钱数,能查看历史账单,能对于每月收支情况进行图标分析,百分比分析, +能够搜索用户关于某种记录的全部收支情况等功能。基本上能够解决个人记账的所有问题,界面简约美观,滑动流畅。 +项目重要技术点: + 1-绘制布局,掌握android基本view控件的属性和使用 + 2-熟练掌握Activity页面展示,跳转和传值 + 3-使用碎片加载界面,滑动视图切换页面 + 4-自定义对话框 + 5-自定义软键盘绘制和使用 + 6-列表视图以及网格视图的适配器使用和页面加载 + 7-使用Android自带数据库,熟练创建表,并进行增删改查 + 8-定义drawable文件,设定布局以及控件样式 + 9-使用MPAndroidChart第三方框架绘制柱状图 + + + diff --git a/simple-bookkeeping-master/app/src/main/java/com/hui/tally/AboutActivity.java b/simple-bookkeeping-master/app/src/main/java/com/hui/tally/AboutActivity.java new file mode 100644 index 0000000..bb358cb --- /dev/null +++ b/simple-bookkeeping-master/app/src/main/java/com/hui/tally/AboutActivity.java @@ -0,0 +1,19 @@ +package com.hui.tally; + +import androidx.appcompat.app.AppCompatActivity; + +import android.os.Bundle; +import android.view.View; + +public class AboutActivity extends AppCompatActivity { + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_about); + } + + public void onClick(View view) { + finish(); + } +} diff --git a/simple-bookkeeping-master/app/src/main/java/com/hui/tally/HistoryActivity.java b/simple-bookkeeping-master/app/src/main/java/com/hui/tally/HistoryActivity.java new file mode 100644 index 0000000..ee43b12 --- /dev/null +++ b/simple-bookkeeping-master/app/src/main/java/com/hui/tally/HistoryActivity.java @@ -0,0 +1,109 @@ +package com.hui.tally; + +import androidx.appcompat.app.AppCompatActivity; + +import android.app.AlertDialog; +import android.content.DialogInterface; +import android.os.Bundle; +import android.view.View; +import android.widget.AdapterView; +import android.widget.ListView; +import android.widget.TextView; + +import com.hui.tally.adapter.AccountAdapter; +import com.hui.tally.db.AccountBean; +import com.hui.tally.db.DBManager; +import com.hui.tally.utils.CalendarDialog; + +import java.util.ArrayList; +import java.util.Calendar; +import java.util.List; + +public class HistoryActivity extends AppCompatActivity { + ListView historyLv; + TextView timeTv; + + ListmDatas; + AccountAdapter adapter; + int year,month; + int dialogSelPos = -1; + int dialogSelMonth = -1; + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_history); + historyLv = findViewById(R.id.history_lv); + timeTv = findViewById(R.id.history_tv_time); + mDatas = new ArrayList<>(); + // 设置适配器 + adapter = new AccountAdapter(this,mDatas); + historyLv.setAdapter(adapter); + initTime(); + timeTv.setText(year+"年"+month+"月"); + loadData(year,month); + setLVClickListener(); + } + /*设置ListView每一个item的长按事件*/ + private void setLVClickListener() { + historyLv.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() { + @Override + public boolean onItemLongClick(AdapterView parent, View view, int position, long id) { + AccountBean accountBean = mDatas.get(position); + deleteItem(accountBean); + return false; + } + }); + } + + private void deleteItem(final AccountBean accountBean) { + final int delId = accountBean.getId(); + AlertDialog.Builder builder = new AlertDialog.Builder(this); + builder.setTitle("提示信息").setMessage("您确定要删除这条记录么?") + .setNegativeButton("取消",null) + .setPositiveButton("确定", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + DBManager.deleteItemFromAccounttbById(delId); + mDatas.remove(accountBean); //实时刷新,从数据源删除 + adapter.notifyDataSetChanged(); + } + }); + builder.create().show(); + } + + /* 获取指定年份月份收支情况的列表*/ + private void loadData(int year,int month) { + List list = DBManager.getAccountListOneMonthFromAccounttb(year, month); + mDatas.clear(); + mDatas.addAll(list); + adapter.notifyDataSetChanged(); + } + + private void initTime() { + Calendar calendar = Calendar.getInstance(); + year = calendar.get(Calendar.YEAR); + month = calendar.get(Calendar.MONTH)+1; + } + + public void onClick(View view) { + switch (view.getId()) { + case R.id.history_iv_back: + finish(); + break; + case R.id.history_iv_rili: + CalendarDialog dialog = new CalendarDialog(this,dialogSelPos,dialogSelMonth); + dialog.show(); + dialog.setDialogSize(); + dialog.setOnRefreshListener(new CalendarDialog.OnRefreshListener() { + @Override + public void onRefresh(int selPos, int year, int month) { + timeTv.setText(year+"年"+month+"月"); + loadData(year,month); + dialogSelPos = selPos; + dialogSelMonth = month; + } + }); + break; + } + } +} diff --git a/simple-bookkeeping-master/app/src/main/java/com/hui/tally/MainActivity.java b/simple-bookkeeping-master/app/src/main/java/com/hui/tally/MainActivity.java new file mode 100644 index 0000000..364ba2e --- /dev/null +++ b/simple-bookkeeping-master/app/src/main/java/com/hui/tally/MainActivity.java @@ -0,0 +1,243 @@ +package com.hui.tally; + +import androidx.appcompat.app.AppCompatActivity; + +import android.app.AlertDialog; +import android.content.Context; +import android.content.DialogInterface; +import android.content.Intent; +import android.content.SharedPreferences; +import android.os.Bundle; +import android.text.method.HideReturnsTransformationMethod; +import android.text.method.PasswordTransformationMethod; +import android.view.View; +import android.widget.AdapterView; +import android.widget.Button; +import android.widget.ImageButton; +import android.widget.ImageView; +import android.widget.ListView; +import android.widget.TextView; + +import com.hui.tally.adapter.AccountAdapter; +import com.hui.tally.db.AccountBean; +import com.hui.tally.db.DBManager; +import com.hui.tally.utils.BudgetDialog; +import com.hui.tally.utils.MoreDialog; + +import java.util.ArrayList; +import java.util.Calendar; +import java.util.List; +import java.util.Set; + +public class MainActivity extends AppCompatActivity implements View.OnClickListener { + ListView todayLv; //展示今日收支情况的ListView + ImageView searchIv; + Button editBtn; + ImageButton moreBtn; + //声明数据源 + ListmDatas; + AccountAdapter adapter; + int year,month,day; + //头布局相关控件 + View headerView; + TextView topOutTv,topInTv,topbudgetTv,topConTv; + ImageView topShowIv; + SharedPreferences preferences; + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_main); + initTime(); + initView(); + preferences = getSharedPreferences("budget", Context.MODE_PRIVATE); + //添加ListView的头布局 + addLVHeaderView(); + mDatas = new ArrayList<>(); + //设置适配器:加载每一行数据到列表当中 + adapter = new AccountAdapter(this, mDatas); + todayLv.setAdapter(adapter); + } + /** 初始化自带的View的方法*/ + private void initView() { + todayLv = findViewById(R.id.main_lv); + editBtn = findViewById(R.id.main_btn_edit); + moreBtn = findViewById(R.id.main_btn_more); + searchIv = findViewById(R.id.main_iv_search); + editBtn.setOnClickListener(this); + moreBtn.setOnClickListener(this); + searchIv.setOnClickListener(this); + setLVLongClickListener(); + } + /** 设置ListView的长按事件*/ + private void setLVLongClickListener() { + todayLv.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() { + @Override + public boolean onItemLongClick(AdapterView parent, View view, int position, long id) { + if (position == 0) { //点击了头布局 + return false; + } + int pos = position-1; + AccountBean clickBean = mDatas.get(pos); //获取正在被点击的这条信息 + + //弹出提示用户是否删除的对话框 + showDeleteItemDialog(clickBean); + return false; + } + }); + } + /* 弹出是否删除某一条记录的对话框*/ + private void showDeleteItemDialog(final AccountBean clickBean) { + AlertDialog.Builder builder = new AlertDialog.Builder(this); + builder.setTitle("提示信息").setMessage("您确定要删除这条记录么?") + .setNegativeButton("取消",null) + .setPositiveButton("确定", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + int click_id = clickBean.getId(); + //执行删除的操作 + DBManager.deleteItemFromAccounttbById(click_id); + mDatas.remove(clickBean); //实时刷新,移除集合当中的对象 + adapter.notifyDataSetChanged(); //提示适配器更新数据 + setTopTvShow(); //改变头布局TextView显示的内容 + } + }); + builder.create().show(); //显示对话框 + } + + /** 给ListView添加头布局的方法*/ + private void addLVHeaderView() { + //将布局转换成View对象 + headerView = getLayoutInflater().inflate(R.layout.item_mainlv_top, null); + todayLv.addHeaderView(headerView); + //查找头布局可用控件 + topOutTv = headerView.findViewById(R.id.item_mainlv_top_tv_out); + topInTv = headerView.findViewById(R.id.item_mainlv_top_tv_in); + topbudgetTv = headerView.findViewById(R.id.item_mainlv_top_tv_budget); + topConTv = headerView.findViewById(R.id.item_mainlv_top_tv_day); + topShowIv = headerView.findViewById(R.id.item_mainlv_top_iv_hide); + + topbudgetTv.setOnClickListener(this); + headerView.setOnClickListener(this); + topShowIv.setOnClickListener(this); + + } + /* 获取今日的具体时间*/ + private void initTime() { + Calendar calendar = Calendar.getInstance(); + year = calendar.get(Calendar.YEAR); + month = calendar.get(Calendar.MONTH)+1; + day = calendar.get(Calendar.DAY_OF_MONTH); + } + + // 当activity获取焦点时,会调用的方法 + @Override + protected void onResume() { + super.onResume(); + loadDBData(); + setTopTvShow(); + } + /* 设置头布局当中文本内容的显示*/ + private void setTopTvShow() { + //获取今日支出和收入总金额,显示在view当中 + float incomeOneDay = DBManager.getSumMoneyOneDay(year, month, day, 1); + float outcomeOneDay = DBManager.getSumMoneyOneDay(year, month, day, 0); + String infoOneDay = "今日支出 ¥"+outcomeOneDay+" 收入 ¥"+incomeOneDay; + topConTv.setText(infoOneDay); +// 获取本月收入和支出总金额 + float incomeOneMonth = DBManager.getSumMoneyOneMonth(year, month, 1); + float outcomeOneMonth = DBManager.getSumMoneyOneMonth(year, month, 0); + topInTv.setText("¥"+incomeOneMonth); + topOutTv.setText("¥"+outcomeOneMonth); + +// 设置显示运算剩余 + float bmoney = preferences.getFloat("bmoney", 0);//预算 + if (bmoney == 0) { + topbudgetTv.setText("¥ 0"); + }else{ + float syMoney = bmoney-outcomeOneMonth; + topbudgetTv.setText("¥"+syMoney); + } + } + + // 加载数据库数据 + private void loadDBData() { + List list = DBManager.getAccountListOneDayFromAccounttb(year, month, day); + mDatas.clear(); + mDatas.addAll(list); + adapter.notifyDataSetChanged(); + } + + + @Override + public void onClick(View v) { + switch (v.getId()) { + case R.id.main_iv_search: + Intent it = new Intent(this, SearchActivity.class); //跳转界面 + startActivity(it); + break; + case R.id.main_btn_edit: + Intent it1 = new Intent(this, RecordActivity.class); //跳转界面 + startActivity(it1); + break; + case R.id.main_btn_more: + MoreDialog moreDialog = new MoreDialog(this); + moreDialog.show(); + moreDialog.setDialogSize(); + break; + case R.id.item_mainlv_top_tv_budget: + showBudgetDialog(); + break; + case R.id.item_mainlv_top_iv_hide: + // 切换TextView明文和密文 + toggleShow(); + break; + } + if (v == headerView) { + //头布局被点击了 + Intent intent = new Intent(); + intent.setClass(this, MonthChartActivity.class); + startActivity(intent); + } + } + /** 显示运算设置对话框*/ + private void showBudgetDialog() { + BudgetDialog dialog = new BudgetDialog(this); + dialog.show(); + dialog.setDialogSize(); + dialog.setOnEnsureListener(new BudgetDialog.OnEnsureListener() { + @Override + public void onEnsure(float money) { + //将预算金额写入到共享参数当中,进行存储 + SharedPreferences.Editor editor = preferences.edit(); + editor.putFloat("bmoney",money); + editor.commit(); + //计算剩余金额 + float outcomeOneMonth = DBManager.getSumMoneyOneMonth(year, month, 0); + float syMoney = money-outcomeOneMonth;//预算剩余 = 预算-支出 + topbudgetTv.setText("¥"+syMoney); + } + }); + } + + boolean isShow = true; + /** + * 点击头布局眼睛时,如果原来是明文,就加密,如果是密文,就显示出来 + * */ + private void toggleShow() { + if (isShow) { //明文====》密文 + PasswordTransformationMethod passwordMethod = PasswordTransformationMethod.getInstance(); + topInTv.setTransformationMethod(passwordMethod); //设置隐藏 + topOutTv.setTransformationMethod(passwordMethod); //设置隐藏 + topbudgetTv.setTransformationMethod(passwordMethod); //设置隐藏 + topShowIv.setImageResource(R.mipmap.ih_hide); + isShow = false; //设置标志位为隐藏状态 + }else{ //密文---》明文 + HideReturnsTransformationMethod hideMethod = HideReturnsTransformationMethod.getInstance(); + topInTv.setTransformationMethod(hideMethod); //设置隐藏 + topOutTv.setTransformationMethod(hideMethod); //设置隐藏 + topbudgetTv.setTransformationMethod(hideMethod); //设置隐藏 + topShowIv.setImageResource(R.mipmap.ih_show); + isShow = true; //设置标志位为隐藏状态 + } + } +} diff --git a/simple-bookkeeping-master/app/src/main/java/com/hui/tally/MonthChartActivity.java b/simple-bookkeeping-master/app/src/main/java/com/hui/tally/MonthChartActivity.java new file mode 100644 index 0000000..aaa9919 --- /dev/null +++ b/simple-bookkeeping-master/app/src/main/java/com/hui/tally/MonthChartActivity.java @@ -0,0 +1,153 @@ +package com.hui.tally; + +import androidx.appcompat.app.AppCompatActivity; +import androidx.fragment.app.Fragment; +import androidx.viewpager.widget.ViewPager; + +import android.graphics.Color; +import android.os.Bundle; +import android.view.View; +import android.widget.Button; +import android.widget.TextView; + +import com.hui.tally.adapter.ChartVPAdapter; +import com.hui.tally.db.DBManager; +import com.hui.tally.frag_chart.IncomChartFragment; +import com.hui.tally.frag_chart.OutcomChartFragment; +import com.hui.tally.utils.CalendarDialog; + +import java.util.ArrayList; +import java.util.Calendar; +import java.util.List; + +public class MonthChartActivity extends AppCompatActivity { + Button inBtn,outBtn; + TextView dateTv,inTv,outTv; + ViewPager chartVp; + int year; + int month; + int selectPos = -1,selectMonth =-1; + ListchartFragList; + private IncomChartFragment incomChartFragment; + private OutcomChartFragment outcomChartFragment; + private ChartVPAdapter chartVPAdapter; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_month_chart); + initView(); + initTime(); + initStatistics(year,month); + initFrag(); + setVPSelectListener(); + } + + private void setVPSelectListener() { + chartVp.addOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener(){ + @Override + public void onPageSelected(int position) { + setButtonStyle(position); + } + }); + } + + private void initFrag() { + chartFragList = new ArrayList<>(); +// 添加Fragment的对象 + incomChartFragment = new IncomChartFragment(); + outcomChartFragment = new OutcomChartFragment(); +// 添加数据到Fragment当中 + Bundle bundle = new Bundle(); + bundle.putInt("year",year); + bundle.putInt("month",month); + incomChartFragment.setArguments(bundle); + outcomChartFragment.setArguments(bundle); +// 将Fragment添加到数据源当中 + chartFragList.add(outcomChartFragment); + chartFragList.add(incomChartFragment); +// 使用适配器 + chartVPAdapter = new ChartVPAdapter(getSupportFragmentManager(), chartFragList); + chartVp.setAdapter(chartVPAdapter); +// 将Fragment加载到Acitivy当中 + } + + /* 统计某年某月的收支情况数据*/ + private void initStatistics(int year, int month) { + float inMoneyOneMonth = DBManager.getSumMoneyOneMonth(year, month, 1); //收入总钱数 + float outMoneyOneMonth = DBManager.getSumMoneyOneMonth(year, month, 0); //支出总钱数 + int incountItemOneMonth = DBManager.getCountItemOneMonth(year, month, 1); //收入多少笔 + int outcountItemOneMonth = DBManager.getCountItemOneMonth(year, month, 0); //支出多少笔 + dateTv.setText(year+"年"+month+"月账单"); + inTv.setText("共"+incountItemOneMonth+"笔收入, ¥ "+inMoneyOneMonth); + outTv.setText("共"+outcountItemOneMonth+"笔支出, ¥ "+outMoneyOneMonth); + + } + + /** 初始化时间的方法*/ + private void initTime() { + Calendar calendar = Calendar.getInstance(); + year = calendar.get(Calendar.YEAR); + month = calendar.get(Calendar.MONTH)+1; + } + + /** 初始化控件*/ + private void initView() { + inBtn = findViewById(R.id.chart_btn_in); + outBtn = findViewById(R.id.chart_btn_out); + dateTv = findViewById(R.id.chart_tv_date); + inTv = findViewById(R.id.chart_tv_in); + outTv = findViewById(R.id.chart_tv_out); + chartVp = findViewById(R.id.chart_vp); + } + + public void onClick(View view) { + switch (view.getId()) { + case R.id.chart_iv_back: + finish(); + break; + case R.id.chart_iv_rili: + showCalendarDialog(); + break; + case R.id.chart_btn_in: + setButtonStyle(1); + chartVp.setCurrentItem(1); + break; + case R.id.chart_btn_out: + setButtonStyle(0); + chartVp.setCurrentItem(0); + break; + } + } + /* 显示日历对话框*/ + private void showCalendarDialog() { + CalendarDialog dialog = new CalendarDialog(this, selectPos, selectMonth); + dialog.show(); + dialog.setDialogSize(); + dialog.setOnRefreshListener(new CalendarDialog.OnRefreshListener() { + @Override + public void onRefresh(int selPos, int year, int month) { + MonthChartActivity.this.selectPos = selPos; + MonthChartActivity.this.selectMonth = month; + initStatistics(year,month); + incomChartFragment.setDate(year,month); + outcomChartFragment.setDate(year,month); + } + }); + } + + /* 设置按钮样式的改变 支出-0 收入-1*/ + private void setButtonStyle(int kind){ + if (kind == 0) { + outBtn.setBackgroundResource(R.drawable.main_recordbtn_bg); + outBtn.setTextColor(Color.WHITE); + inBtn.setBackgroundResource(R.drawable.dialog_btn_bg); + inBtn.setTextColor(Color.BLACK); + }else if (kind == 1){ + inBtn.setBackgroundResource(R.drawable.main_recordbtn_bg); + inBtn.setTextColor(Color.WHITE); + outBtn.setBackgroundResource(R.drawable.dialog_btn_bg); + outBtn.setTextColor(Color.BLACK); + } + } +} diff --git a/simple-bookkeeping-master/app/src/main/java/com/hui/tally/RecordActivity.java b/simple-bookkeeping-master/app/src/main/java/com/hui/tally/RecordActivity.java new file mode 100644 index 0000000..38904eb --- /dev/null +++ b/simple-bookkeeping-master/app/src/main/java/com/hui/tally/RecordActivity.java @@ -0,0 +1,58 @@ +package com.hui.tally; + +import androidx.appcompat.app.AppCompatActivity; +import androidx.fragment.app.Fragment; +import androidx.viewpager.widget.ViewPager; + +import android.os.Bundle; +import android.view.View; + +import com.google.android.material.tabs.TabLayout; +import com.hui.tally.adapter.RecordPagerAdapter; +import com.hui.tally.frag_record.IncomeFragment; +import com.hui.tally.frag_record.BaseRecordFragment; +import com.hui.tally.frag_record.OutcomeFragment; + +import java.util.ArrayList; +import java.util.List; + +public class RecordActivity extends AppCompatActivity { + TabLayout tabLayout; + ViewPager viewPager; + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_record); + //1.查找控件 + tabLayout = findViewById(R.id.record_tabs); + viewPager = findViewById(R.id.record_vp); + //2.设置ViewPager加载页面 + initPager(); + } + + private void initPager() { +// 初始化ViewPager页面的集合 + ListfragmentList = new ArrayList<>(); +// 创建收入和支出页面,放置在Fragment当中 + OutcomeFragment outFrag = new OutcomeFragment(); //支出 + IncomeFragment inFrag = new IncomeFragment(); //收入 + fragmentList.add(outFrag); + fragmentList.add(inFrag); + +// 创建适配器 + RecordPagerAdapter pagerAdapter = new RecordPagerAdapter(getSupportFragmentManager(), fragmentList); +// 设置适配器 + viewPager.setAdapter(pagerAdapter); + //将TabLayout和ViwePager进行关联 + tabLayout.setupWithViewPager(viewPager); + } + + /* 点击事件*/ + public void onClick(View view) { + switch (view.getId()) { + case R.id.record_iv_back: + finish(); + break; + } + } +} diff --git a/simple-bookkeeping-master/app/src/main/java/com/hui/tally/SearchActivity.java b/simple-bookkeeping-master/app/src/main/java/com/hui/tally/SearchActivity.java new file mode 100644 index 0000000..961a043 --- /dev/null +++ b/simple-bookkeeping-master/app/src/main/java/com/hui/tally/SearchActivity.java @@ -0,0 +1,63 @@ +package com.hui.tally; + +import androidx.appcompat.app.AppCompatActivity; + +import android.os.Bundle; +import android.text.TextUtils; +import android.view.View; +import android.widget.EditText; +import android.widget.ListView; +import android.widget.TextView; +import android.widget.Toast; + +import com.hui.tally.adapter.AccountAdapter; +import com.hui.tally.db.AccountBean; +import com.hui.tally.db.DBManager; + +import java.util.ArrayList; +import java.util.List; + +public class SearchActivity extends AppCompatActivity { + ListView searchLv; + EditText searchEt; + TextView emptyTv; + ListmDatas; //数据源 + AccountAdapter adapter; //适配器对象 + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_search); + initView(); + mDatas = new ArrayList<>(); + adapter = new AccountAdapter(this,mDatas); + searchLv.setAdapter(adapter); + searchLv.setEmptyView(emptyTv); //设置无数局时,显示的控件 + } + + private void initView() { + searchEt = findViewById(R.id.search_et); + searchLv = findViewById(R.id.search_lv); + emptyTv = findViewById(R.id.search_tv_empty); + } + + public void onClick(View view) { + switch (view.getId()) { + case R.id.search_iv_back: + finish(); + break; + case R.id.search_iv_sh: //执行搜索的操作 + String msg = searchEt.getText().toString().trim(); +// 判断输入内容是否为空,如果为空,就提示不能搜索 + if (TextUtils.isEmpty(msg)) { + Toast.makeText(this,"输入内容不能为空!",Toast.LENGTH_SHORT).show(); + return; + } + //开始搜索 + List list = DBManager.getAccountListByRemarkFromAccounttb(msg); + mDatas.clear(); + mDatas.addAll(list); + adapter.notifyDataSetChanged(); + break; + } + } +} diff --git a/simple-bookkeeping-master/app/src/main/java/com/hui/tally/SettingActivity.java b/simple-bookkeeping-master/app/src/main/java/com/hui/tally/SettingActivity.java new file mode 100644 index 0000000..69737ef --- /dev/null +++ b/simple-bookkeeping-master/app/src/main/java/com/hui/tally/SettingActivity.java @@ -0,0 +1,46 @@ +package com.hui.tally; + +import androidx.appcompat.app.AppCompatActivity; + +import android.app.AlertDialog; +import android.content.DialogInterface; +import android.os.Bundle; +import android.view.View; +import android.widget.Toast; + +import com.hui.tally.db.DBManager; + +public class SettingActivity extends AppCompatActivity { + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_setting); + } + + public void onClick(View view) { + switch (view.getId()) { + case R.id.setting_iv_back: + finish(); + break; + case R.id.setting_tv_clear: + showDeleteDialog(); + break; + } + } + + private void showDeleteDialog() { + AlertDialog.Builder builder = new AlertDialog.Builder(this); + builder.setTitle("删除提示") + .setMessage("您确定要删除所有记录么?\n注意:删除后无法恢复,请慎重选择!") + .setPositiveButton("取消",null) + .setNegativeButton("确定", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + DBManager.deleteAllAccount(); + Toast.makeText(SettingActivity.this,"删除成功!",Toast.LENGTH_SHORT).show(); + } + }); + builder.create().show(); + } +} diff --git a/simple-bookkeeping-master/app/src/main/java/com/hui/tally/UniteApp.java b/simple-bookkeeping-master/app/src/main/java/com/hui/tally/UniteApp.java new file mode 100644 index 0000000..3c3a481 --- /dev/null +++ b/simple-bookkeeping-master/app/src/main/java/com/hui/tally/UniteApp.java @@ -0,0 +1,15 @@ +package com.hui.tally; + +import android.app.Application; + +import com.hui.tally.db.DBManager; + +/* 表示全局应用的类*/ +public class UniteApp extends Application { + @Override + public void onCreate() { + super.onCreate(); + // 初始化数据库 + DBManager.initDB(getApplicationContext()); + } +} diff --git a/simple-bookkeeping-master/app/src/main/java/com/hui/tally/adapter/AccountAdapter.java b/simple-bookkeeping-master/app/src/main/java/com/hui/tally/adapter/AccountAdapter.java new file mode 100644 index 0000000..dc9f117 --- /dev/null +++ b/simple-bookkeeping-master/app/src/main/java/com/hui/tally/adapter/AccountAdapter.java @@ -0,0 +1,83 @@ +package com.hui.tally.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; +import android.widget.TextView; + +import com.hui.tally.R; +import com.hui.tally.db.AccountBean; + +import java.util.Calendar; +import java.util.List; + +public class AccountAdapter extends BaseAdapter { + Context context; + ListmDatas; + LayoutInflater inflater; + int year,month,day; + public AccountAdapter(Context context, List mDatas) { + this.context = context; + this.mDatas = mDatas; + inflater = LayoutInflater.from(context); + Calendar calendar = Calendar.getInstance(); + year = calendar.get(Calendar.YEAR); + month = calendar.get(Calendar.MONTH)+1; + day = calendar.get(Calendar.DAY_OF_MONTH); + } + + @Override + public int getCount() { + return mDatas.size(); + } + + @Override + public Object getItem(int position) { + return mDatas.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ViewHolder holder = null; + if (convertView == null) { + convertView = inflater.inflate(R.layout.item_mainlv,parent,false); + holder = new ViewHolder(convertView); + convertView.setTag(holder); + }else{ + holder = (ViewHolder) convertView.getTag(); + } + AccountBean bean = mDatas.get(position); + holder.typeIv.setImageResource(bean.getsImageId()); + holder.typeTv.setText(bean.getTypename()); + holder.beizhuTv.setText(bean.getBeizhu()); + holder.moneyTv.setText("¥ "+bean.getMoney()); + if (bean.getYear()==year&&bean.getMonth()==month&&bean.getDay()==day) { + String time = bean.getTime().split(" ")[1]; + holder.timeTv.setText("今天 "+time); + }else { + holder.timeTv.setText(bean.getTime()); + } + return convertView; + } + + class ViewHolder{ + ImageView typeIv; + TextView typeTv,beizhuTv,timeTv,moneyTv; + public ViewHolder(View view){ + typeIv = view.findViewById(R.id.item_mainlv_iv); + typeTv = view.findViewById(R.id.item_mainlv_tv_title); + timeTv = view.findViewById(R.id.item_mainlv_tv_time); + beizhuTv = view.findViewById(R.id.item_mainlv_tv_beizhu); + moneyTv = view.findViewById(R.id.item_mainlv_tv_money); + + } + } +} diff --git a/simple-bookkeeping-master/app/src/main/java/com/hui/tally/adapter/CalendarAdapter.java b/simple-bookkeeping-master/app/src/main/java/com/hui/tally/adapter/CalendarAdapter.java new file mode 100644 index 0000000..5f9a83b --- /dev/null +++ b/simple-bookkeeping-master/app/src/main/java/com/hui/tally/adapter/CalendarAdapter.java @@ -0,0 +1,76 @@ +package com.hui.tally.adapter; + +import android.content.Context; +import android.graphics.Color; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.TextView; + +import androidx.core.content.ContextCompat; + +import com.hui.tally.R; + +import java.util.ArrayList; +import java.util.List; + +/* +* 历史账单界面,点击日历表,弹出对话框,当中的GridView对应的适配器 +* */ +public class CalendarAdapter extends BaseAdapter { + Context context; + ListmDatas; + public int year; + public int selPos = -1; + + public void setYear(int year) { + this.year = year; + mDatas.clear(); + loadDatas(year); + notifyDataSetChanged(); + } + + public CalendarAdapter(Context context, int year) { + this.context = context; + this.year = year; + mDatas = new ArrayList<>(); + loadDatas(year); + } + + private void loadDatas(int year) { + for (int i = 1; i < 13; i++) { + String data = year+"/"+i; + mDatas.add(data); + } + } + + @Override + public int getCount() { + return mDatas.size(); + } + + @Override + public Object getItem(int position) { + return mDatas.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + convertView = LayoutInflater.from(context).inflate(R.layout.item_dialogcal_gv,parent,false); + TextView tv = convertView.findViewById(R.id.item_dialogcal_gv_tv); + tv.setText(mDatas.get(position)); + tv.setBackgroundResource(R.color.grey_f3f3f3); + tv.setTextColor(Color.BLACK); + if (position == selPos) { + tv.setBackgroundResource(R.color.green_006400); + tv.setTextColor(Color.WHITE); + } + return convertView; + } +} diff --git a/simple-bookkeeping-master/app/src/main/java/com/hui/tally/adapter/ChartItemAdapter.java b/simple-bookkeeping-master/app/src/main/java/com/hui/tally/adapter/ChartItemAdapter.java new file mode 100644 index 0000000..042d4e0 --- /dev/null +++ b/simple-bookkeeping-master/app/src/main/java/com/hui/tally/adapter/ChartItemAdapter.java @@ -0,0 +1,78 @@ +package com.hui.tally.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; +import android.widget.ListView; +import android.widget.TextView; + +import com.hui.tally.R; +import com.hui.tally.db.ChartItemBean; +import com.hui.tally.utils.FloatUtils; + +import java.util.List; + +/* +* 账单详情页面,listview的适配器 +* */ +public class ChartItemAdapter extends BaseAdapter { + Context context; + List mDatas; + LayoutInflater inflater; + public ChartItemAdapter(Context context, List mDatas) { + this.context = context; + this.mDatas = mDatas; + inflater = LayoutInflater.from(context); + } + + @Override + public int getCount() { + return mDatas.size(); + } + + @Override + public Object getItem(int position) { + return mDatas.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ViewHolder holder = null; + if (convertView == null) { + convertView = inflater.inflate(R.layout.item_chartfrag_lv,parent,false); + holder = new ViewHolder(convertView); + convertView.setTag(holder); + }else{ + holder = (ViewHolder) convertView.getTag(); + } +// 获取显示内容 + ChartItemBean bean = mDatas.get(position); + holder.iv.setImageResource(bean.getsImageId()); + holder.typeTv.setText(bean.getType()); + float ratio = bean.getRatio(); + String pert = FloatUtils.ratioToPercent(ratio); + holder.ratioTv.setText(pert); + + holder.totalTv.setText("¥ "+bean.getTotalMoney()); + return convertView; + } + + class ViewHolder{ + TextView typeTv,ratioTv,totalTv; + ImageView iv; + public ViewHolder(View view){ + typeTv = view.findViewById(R.id.item_chartfrag_tv_type); + ratioTv = view.findViewById(R.id.item_chartfrag_tv_pert); + totalTv = view.findViewById(R.id.item_chartfrag_tv_sum); + iv = view.findViewById(R.id.item_chartfrag_iv); + } + } +} diff --git a/simple-bookkeeping-master/app/src/main/java/com/hui/tally/adapter/ChartVPAdapter.java b/simple-bookkeeping-master/app/src/main/java/com/hui/tally/adapter/ChartVPAdapter.java new file mode 100644 index 0000000..34324ad --- /dev/null +++ b/simple-bookkeeping-master/app/src/main/java/com/hui/tally/adapter/ChartVPAdapter.java @@ -0,0 +1,27 @@ +package com.hui.tally.adapter; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; + +import java.util.List; + +public class ChartVPAdapter extends FragmentPagerAdapter { + ListfragmentList; + public ChartVPAdapter(@NonNull FragmentManager fm, ListfragmentList) { + super(fm); + this.fragmentList = fragmentList; + } + + @NonNull + @Override + public Fragment getItem(int position) { + return fragmentList.get(position); + } + + @Override + public int getCount() { + return fragmentList.size(); + } +} diff --git a/simple-bookkeeping-master/app/src/main/java/com/hui/tally/adapter/RecordPagerAdapter.java b/simple-bookkeeping-master/app/src/main/java/com/hui/tally/adapter/RecordPagerAdapter.java new file mode 100644 index 0000000..c693cdb --- /dev/null +++ b/simple-bookkeeping-master/app/src/main/java/com/hui/tally/adapter/RecordPagerAdapter.java @@ -0,0 +1,35 @@ +package com.hui.tally.adapter; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; + +import java.util.List; + +public class RecordPagerAdapter extends FragmentPagerAdapter { + ListfragmentList; + String[]titles = {"支出","收入"}; + public RecordPagerAdapter(@NonNull FragmentManager fm,ListfragmentList) { + super(fm); + this.fragmentList = fragmentList; + } + + @NonNull + @Override + public Fragment getItem(int position) { + return fragmentList.get(position); + } + + @Override + public int getCount() { + return fragmentList.size(); + } + + @Nullable + @Override + public CharSequence getPageTitle(int position) { + return titles[position]; + } +} diff --git a/simple-bookkeeping-master/app/src/main/java/com/hui/tally/db/AccountBean.java b/simple-bookkeeping-master/app/src/main/java/com/hui/tally/db/AccountBean.java new file mode 100644 index 0000000..259a733 --- /dev/null +++ b/simple-bookkeeping-master/app/src/main/java/com/hui/tally/db/AccountBean.java @@ -0,0 +1,110 @@ +package com.hui.tally.db; +/** 描述记录一条数据的相关内容类*/ +public class AccountBean { + int id; + String typename; //类型 + int sImageId; //被选中类型图片 + String beizhu; //备注 + float money; //价格 + String time ; //保存时间字符串 + int year; + int month; + int day; + int kind; //类型 收入---1 支出---0 + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getTypename() { + return typename; + } + + public void setTypename(String typename) { + this.typename = typename; + } + + public int getsImageId() { + return sImageId; + } + + public void setsImageId(int sImageId) { + this.sImageId = sImageId; + } + + public String getBeizhu() { + return beizhu; + } + + public void setBeizhu(String beizhu) { + this.beizhu = beizhu; + } + + public float getMoney() { + return money; + } + + public void setMoney(float money) { + this.money = money; + } + + public String getTime() { + return time; + } + + public void setTime(String time) { + this.time = time; + } + + public int getYear() { + return year; + } + + public void setYear(int year) { + this.year = year; + } + + public int getMonth() { + return month; + } + + public void setMonth(int month) { + this.month = month; + } + + public int getDay() { + return day; + } + + public void setDay(int day) { + this.day = day; + } + + public int getKind() { + return kind; + } + + public void setKind(int kind) { + this.kind = kind; + } + + public AccountBean() { + } + + public AccountBean(int id, String typename, int sImageId, String beizhu, float money, String time, int year, int month, int day, int kind) { + this.id = id; + this.typename = typename; + this.sImageId = sImageId; + this.beizhu = beizhu; + this.money = money; + this.time = time; + this.year = year; + this.month = month; + this.day = day; + this.kind = kind; + } +} diff --git a/simple-bookkeeping-master/app/src/main/java/com/hui/tally/db/BarChartItemBean.java b/simple-bookkeeping-master/app/src/main/java/com/hui/tally/db/BarChartItemBean.java new file mode 100644 index 0000000..eabc503 --- /dev/null +++ b/simple-bookkeeping-master/app/src/main/java/com/hui/tally/db/BarChartItemBean.java @@ -0,0 +1,50 @@ +package com.hui.tally.db; +/* 用于描述绘制柱状图时,每一个柱子表示的对象*/ +public class BarChartItemBean { + int year; + int month; + int day; + float summoney; + + public BarChartItemBean() { + } + + public int getYear() { + return year; + } + + public void setYear(int year) { + this.year = year; + } + + public int getMonth() { + return month; + } + + public void setMonth(int month) { + this.month = month; + } + + public int getDay() { + return day; + } + + public void setDay(int day) { + this.day = day; + } + + public float getSummoney() { + return summoney; + } + + public void setSummoney(float summoney) { + this.summoney = summoney; + } + + public BarChartItemBean(int year, int month, int day, float summoney) { + this.year = year; + this.month = month; + this.day = day; + this.summoney = summoney; + } +} diff --git a/simple-bookkeeping-master/app/src/main/java/com/hui/tally/db/ChartItemBean.java b/simple-bookkeeping-master/app/src/main/java/com/hui/tally/db/ChartItemBean.java new file mode 100644 index 0000000..a7fb397 --- /dev/null +++ b/simple-bookkeeping-master/app/src/main/java/com/hui/tally/db/ChartItemBean.java @@ -0,0 +1,50 @@ +package com.hui.tally.db; + +public class ChartItemBean { + int sImageId; + String type; + float ratio; //所占比例 + float totalMoney; //此项的总钱数 + + public ChartItemBean() { + } + + public void setsImageId(int sImageId) { + this.sImageId = sImageId; + } + + public void setType(String type) { + this.type = type; + } + + public void setRatio(float ratio) { + this.ratio = ratio; + } + + public void setTotalMoney(float totalMoney) { + this.totalMoney = totalMoney; + } + + public int getsImageId() { + return sImageId; + } + + public String getType() { + return type; + } + + public float getRatio() { + return ratio; + } + + public float getTotalMoney() { + return totalMoney; + } + + public ChartItemBean(int sImageId, String type, float ratio, float totalMoney) { + this.sImageId = sImageId; + this.type = type; + this.ratio = ratio; + this.totalMoney = totalMoney; + } +} diff --git a/simple-bookkeeping-master/app/src/main/java/com/hui/tally/db/DBManager.java b/simple-bookkeeping-master/app/src/main/java/com/hui/tally/db/DBManager.java new file mode 100644 index 0000000..f5edc05 --- /dev/null +++ b/simple-bookkeeping-master/app/src/main/java/com/hui/tally/db/DBManager.java @@ -0,0 +1,265 @@ +package com.hui.tally.db; + +import android.content.ContentValues; +import android.content.Context; +import android.database.Cursor; +import android.database.sqlite.SQLiteDatabase; +import android.util.Log; + +import com.hui.tally.utils.FloatUtils; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.List; + +/* +* 负责管理数据库的类 +* 主要对于表当中的内容进行操作,增删改查 +* */ +public class DBManager { + + private static SQLiteDatabase db; + /* 初始化数据库对象*/ + public static void initDB(Context context){ + DBOpenHelper helper = new DBOpenHelper(context); //得到帮助类对象 + db = helper.getWritableDatabase(); //得到数据库对象 + } + + /** + * 读取数据库当中的数据,写入内存集合里 + * kind :表示收入或者支出 + * */ + public static ListgetTypeList(int kind){ + Listlist = new ArrayList<>(); + //读取typetb表当中的数据 + String sql = "select * from typetb where kind = "+kind; + Cursor cursor = db.rawQuery(sql, null); +// 循环读取游标内容,存储到对象当中 + while (cursor.moveToNext()) { + String typename = cursor.getString(cursor.getColumnIndex("typename")); + int imageId = cursor.getInt(cursor.getColumnIndex("imageId")); + int sImageId = cursor.getInt(cursor.getColumnIndex("sImageId")); + int kind1 = cursor.getInt(cursor.getColumnIndex("kind")); + int id = cursor.getInt(cursor.getColumnIndex("id")); + TypeBean typeBean = new TypeBean(id, typename, imageId, sImageId, kind); + list.add(typeBean); + } + return list; + } + + /* + * 向记账表当中插入一条元素 + * */ + public static void insertItemToAccounttb(AccountBean bean){ + ContentValues values = new ContentValues(); + values.put("typename",bean.getTypename()); + values.put("sImageId",bean.getsImageId()); + values.put("beizhu",bean.getBeizhu()); + values.put("money",bean.getMoney()); + values.put("time",bean.getTime()); + values.put("year",bean.getYear()); + values.put("month",bean.getMonth()); + values.put("day",bean.getDay()); + values.put("kind",bean.getKind()); + db.insert("accounttb",null,values); + } + /* + * 获取记账表当中某一天的所有支出或者收入情况 + * */ + public static ListgetAccountListOneDayFromAccounttb(int year,int month,int day){ + Listlist = new ArrayList<>(); + String sql = "select * from accounttb where year=? and month=? and day=? order by id desc"; + Cursor cursor = db.rawQuery(sql, new String[]{year + "", month + "", day + ""}); + //遍历符合要求的每一行数据 + while (cursor.moveToNext()) { + int id = cursor.getInt(cursor.getColumnIndex("id")); + String typename = cursor.getString(cursor.getColumnIndex("typename")); + String beizhu = cursor.getString(cursor.getColumnIndex("beizhu")); + String time = cursor.getString(cursor.getColumnIndex("time")); + int sImageId = cursor.getInt(cursor.getColumnIndex("sImageId")); + int kind = cursor.getInt(cursor.getColumnIndex("kind")); + float money = cursor.getFloat(cursor.getColumnIndex("money")); + AccountBean accountBean = new AccountBean(id, typename, sImageId, beizhu, money, time, year, month, day, kind); + list.add(accountBean); + } + return list; + } + + /* + * 获取记账表当中某一月的所有支出或者收入情况 + * */ + public static ListgetAccountListOneMonthFromAccounttb(int year,int month){ + Listlist = new ArrayList<>(); + String sql = "select * from accounttb where year=? and month=? order by id desc"; + Cursor cursor = db.rawQuery(sql, new String[]{year + "", month + ""}); + //遍历符合要求的每一行数据 + while (cursor.moveToNext()) { + int id = cursor.getInt(cursor.getColumnIndex("id")); + String typename = cursor.getString(cursor.getColumnIndex("typename")); + String beizhu = cursor.getString(cursor.getColumnIndex("beizhu")); + String time = cursor.getString(cursor.getColumnIndex("time")); + int sImageId = cursor.getInt(cursor.getColumnIndex("sImageId")); + int kind = cursor.getInt(cursor.getColumnIndex("kind")); + float money = cursor.getFloat(cursor.getColumnIndex("money")); + int day = cursor.getInt(cursor.getColumnIndex("day")); + AccountBean accountBean = new AccountBean(id, typename, sImageId, beizhu, money, time, year, month, day, kind); + list.add(accountBean); + } + return list; + } + /** + * 获取某一天的支出或者收入的总金额 kind:支出==0 收入===1 + * */ + public static float getSumMoneyOneDay(int year,int month,int day,int kind){ + float total = 0.0f; + String sql = "select sum(money) from accounttb where year=? and month=? and day=? and kind=?"; + Cursor cursor = db.rawQuery(sql, new String[]{year + "", month + "", day + "", kind + ""}); + // 遍历 + if (cursor.moveToFirst()) { + float money = cursor.getFloat(cursor.getColumnIndex("sum(money)")); + total = money; + } + return total; + } + /** + * 获取某一月的支出或者收入的总金额 kind:支出==0 收入===1 + * */ + public static float getSumMoneyOneMonth(int year,int month,int kind){ + float total = 0.0f; + String sql = "select sum(money) from accounttb where year=? and month=? and kind=?"; + Cursor cursor = db.rawQuery(sql, new String[]{year + "", month + "", kind + ""}); + // 遍历 + if (cursor.moveToFirst()) { + float money = cursor.getFloat(cursor.getColumnIndex("sum(money)")); + total = money; + } + return total; + } + /** 统计某月份支出或者收入情况有多少条 收入-1 支出-0*/ + public static int getCountItemOneMonth(int year,int month,int kind){ + int total = 0; + String sql = "select count(money) from accounttb where year=? and month=? and kind=?"; + Cursor cursor = db.rawQuery(sql, new String[]{year + "", month + "", kind + ""}); + if (cursor.moveToFirst()) { + int count = cursor.getInt(cursor.getColumnIndex("count(money)")); + total = count; + } + return total; + } + /** + * 获取某一年的支出或者收入的总金额 kind:支出==0 收入===1 + * */ + public static float getSumMoneyOneYear(int year,int kind){ + float total = 0.0f; + String sql = "select sum(money) from accounttb where year=? and kind=?"; + Cursor cursor = db.rawQuery(sql, new String[]{year + "", kind + ""}); + // 遍历 + if (cursor.moveToFirst()) { + float money = cursor.getFloat(cursor.getColumnIndex("sum(money)")); + total = money; + } + return total; + } + + /* + * 根据传入的id,删除accounttb表当中的一条数据 + * */ + public static int deleteItemFromAccounttbById(int id){ + int i = db.delete("accounttb", "id=?", new String[]{id + ""}); + return i; + } + /** + * 根据备注搜索收入或者支出的情况列表 + * */ + public static ListgetAccountListByRemarkFromAccounttb(String beizhu){ + Listlist = new ArrayList<>(); + String sql = "select * from accounttb where beizhu like '%"+beizhu+"%'"; + Cursor cursor = db.rawQuery(sql, null); + while (cursor.moveToNext()) { + int id = cursor.getInt(cursor.getColumnIndex("id")); + String typename = cursor.getString(cursor.getColumnIndex("typename")); + String bz = cursor.getString(cursor.getColumnIndex("beizhu")); + String time = cursor.getString(cursor.getColumnIndex("time")); + int sImageId = cursor.getInt(cursor.getColumnIndex("sImageId")); + int kind = cursor.getInt(cursor.getColumnIndex("kind")); + float money = cursor.getFloat(cursor.getColumnIndex("money")); + int year = cursor.getInt(cursor.getColumnIndex("year")); + int month = cursor.getInt(cursor.getColumnIndex("month")); + int day = cursor.getInt(cursor.getColumnIndex("day")); + AccountBean accountBean = new AccountBean(id, typename, sImageId, bz, money, time, year, month, day, kind); + list.add(accountBean); + } + return list; + } + + /** + * 查询记账的表当中有几个年份信息 + * */ + public static ListgetYearListFromAccounttb(){ + Listlist = new ArrayList<>(); + String sql = "select distinct(year) from accounttb order by year asc"; + Cursor cursor = db.rawQuery(sql, null); + while (cursor.moveToNext()) { + int year = cursor.getInt(cursor.getColumnIndex("year")); + list.add(year); + } + return list; + } + + /* + * 删除accounttb表格当中的所有数据 + * */ + public static void deleteAllAccount(){ + String sql = "delete from accounttb"; + db.execSQL(sql); + } + + /** + * 查询指定年份和月份的收入或者支出每一种类型的总钱数 + * */ + public static ListgetChartListFromAccounttb(int year,int month,int kind){ + Listlist = new ArrayList<>(); + float sumMoneyOneMonth = getSumMoneyOneMonth(year, month, kind); //求出支出或者收入总钱数 + String sql = "select typename,sImageId,sum(money)as total from accounttb where year=? and month=? and kind=? group by typename " + + "order by total desc"; + Cursor cursor = db.rawQuery(sql, new String[]{year + "", month + "", kind + ""}); + while (cursor.moveToNext()) { + int sImageId = cursor.getInt(cursor.getColumnIndex("sImageId")); + String typename = cursor.getString(cursor.getColumnIndex("typename")); + float total = cursor.getFloat(cursor.getColumnIndex("total")); + //计算所占百分比 total /sumMonth + float ratio = FloatUtils.div(total,sumMoneyOneMonth); + ChartItemBean bean = new ChartItemBean(sImageId, typename, ratio, total); + list.add(bean); + } + return list; + } + + /** + * 获取这个月当中某一天收入支出最大的金额,金额是多少 + * */ + public static float getMaxMoneyOneDayInMonth(int year,int month,int kind){ + String sql = "select sum(money) from accounttb where year=? and month=? and kind=? group by day order by sum(money) desc"; + Cursor cursor = db.rawQuery(sql, new String[]{year + "", month + "", kind + ""}); + if (cursor.moveToFirst()) { + float money = cursor.getFloat(cursor.getColumnIndex("sum(money)")); + return money; + } + return 0; + } + + /** 根据指定月份每一日收入或者支出的总钱数的集合*/ + public static ListgetSumMoneyOneDayInMonth(int year,int month,int kind){ + String sql = "select day,sum(money) from accounttb where year=? and month=? and kind=? group by day"; + Cursor cursor = db.rawQuery(sql, new String[]{year + "", month + "", kind + ""}); + Listlist = new ArrayList<>(); + while (cursor.moveToNext()) { + int day = cursor.getInt(cursor.getColumnIndex("day")); + float smoney = cursor.getFloat(cursor.getColumnIndex("sum(money)")); + BarChartItemBean itemBean = new BarChartItemBean(year, month, day, smoney); + list.add(itemBean); + } + return list; + } + +} diff --git a/simple-bookkeeping-master/app/src/main/java/com/hui/tally/db/DBOpenHelper.java b/simple-bookkeeping-master/app/src/main/java/com/hui/tally/db/DBOpenHelper.java new file mode 100644 index 0000000..759d784 --- /dev/null +++ b/simple-bookkeeping-master/app/src/main/java/com/hui/tally/db/DBOpenHelper.java @@ -0,0 +1,64 @@ +package com.hui.tally.db; + +import android.content.Context; +import android.database.sqlite.SQLiteDatabase; +import android.database.sqlite.SQLiteOpenHelper; + +import androidx.annotation.Nullable; + +import com.hui.tally.R; + +public class DBOpenHelper extends SQLiteOpenHelper { + public DBOpenHelper(@Nullable Context context) { + super(context,"tally.db" , null, 1); + } + +// 创建数据库的方法,只有项目第一次运行时,会被调用 + @Override + public void onCreate(SQLiteDatabase db) { +// 创建表示类型的表 + String sql = "create table typetb(id integer primary key autoincrement,typename varchar(10),imageId integer,sImageId integer,kind integer)"; + db.execSQL(sql); + insertType(db); + //创建记账表 + sql = "create table accounttb(id integer primary key autoincrement,typename varchar(10),sImageId integer,beizhu varchar(80),money float," + + "time varchar(60),year integer,month integer,day integer,kind integer)"; + db.execSQL(sql); + } + + private void insertType(SQLiteDatabase db) { +// 向typetb表当中插入元素 + String sql = "insert into typetb (typename,imageId,sImageId,kind) values (?,?,?,?)"; + db.execSQL(sql,new Object[]{"其他", R.mipmap.ic_qita,R.mipmap.ic_qita_fs,0}); + db.execSQL(sql,new Object[]{"餐饮", R.mipmap.ic_canyin,R.mipmap.ic_canyin_fs,0}); + db.execSQL(sql,new Object[]{"交通", R.mipmap.ic_jiaotong,R.mipmap.ic_jiaotong_fs,0}); + db.execSQL(sql,new Object[]{"购物", R.mipmap.ic_gouwu,R.mipmap.ic_gouwu_fs,0}); + db.execSQL(sql,new Object[]{"服饰", R.mipmap.ic_fushi,R.mipmap.ic_fushi_fs,0}); + db.execSQL(sql,new Object[]{"日用品", R.mipmap.ic_riyongpin,R.mipmap.ic_riyongpin_fs,0}); + db.execSQL(sql,new Object[]{"娱乐", R.mipmap.ic_yule,R.mipmap.ic_yule_fs,0}); + db.execSQL(sql,new Object[]{"零食", R.mipmap.ic_lingshi,R.mipmap.ic_lingshi_fs,0}); + db.execSQL(sql,new Object[]{"烟酒茶", R.mipmap.ic_yanjiu,R.mipmap.ic_yanjiu_fs,0}); + db.execSQL(sql,new Object[]{"学习", R.mipmap.ic_xuexi,R.mipmap.ic_xuexi_fs,0}); + db.execSQL(sql,new Object[]{"医疗", R.mipmap.ic_yiliao,R.mipmap.ic_yiliao_fs,0}); + db.execSQL(sql,new Object[]{"住宅", R.mipmap.ic_zhufang,R.mipmap.ic_zhufang_fs,0}); + db.execSQL(sql,new Object[]{"水电煤", R.mipmap.ic_shuidianfei,R.mipmap.ic_shuidianfei_fs,0}); + db.execSQL(sql,new Object[]{"通讯", R.mipmap.ic_tongxun,R.mipmap.ic_tongxun_fs,0}); + db.execSQL(sql,new Object[]{"人情往来", R.mipmap.ic_renqingwanglai,R.mipmap.ic_renqingwanglai_fs,0}); + + db.execSQL(sql,new Object[]{"其他", R.mipmap.in_qt,R.mipmap.in_qt_fs,1}); + db.execSQL(sql,new Object[]{"薪资", R.mipmap.in_xinzi,R.mipmap.in_xinzi_fs,1}); + db.execSQL(sql,new Object[]{"奖金", R.mipmap.in_jiangjin,R.mipmap.in_jiangjin_fs,1}); + db.execSQL(sql,new Object[]{"借入", R.mipmap.in_jieru,R.mipmap.in_jieru_fs,1}); + db.execSQL(sql,new Object[]{"收债", R.mipmap.in_shouzhai,R.mipmap.in_shouzhai_fs,1}); + db.execSQL(sql,new Object[]{"利息收入", R.mipmap.in_lixifuji,R.mipmap.in_lixifuji_fs,1}); + db.execSQL(sql,new Object[]{"投资回报", R.mipmap.in_touzi,R.mipmap.in_touzi_fs,1}); + db.execSQL(sql,new Object[]{"二手交易", R.mipmap.in_ershoushebei,R.mipmap.in_ershoushebei_fs,1}); + db.execSQL(sql,new Object[]{"意外所得", R.mipmap.in_yiwai,R.mipmap.in_yiwai_fs,1}); + } + + // 数据库版本在更新时发生改变,会调用此方法 + @Override + public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { + + } +} diff --git a/simple-bookkeeping-master/app/src/main/java/com/hui/tally/db/TypeBean.java b/simple-bookkeeping-master/app/src/main/java/com/hui/tally/db/TypeBean.java new file mode 100644 index 0000000..8393d9a --- /dev/null +++ b/simple-bookkeeping-master/app/src/main/java/com/hui/tally/db/TypeBean.java @@ -0,0 +1,62 @@ +package com.hui.tally.db; +/* +* 表示收入或者支出具体类型的类 +* */ +public class TypeBean { + int id; + String typename; //类型名称 + int imageId; //未被选中图片id + int simageId; //被选中图片id + int kind; //收入-1 支出-0 + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getTypename() { + return typename; + } + + public void setTypename(String typename) { + this.typename = typename; + } + + public int getImageId() { + return imageId; + } + + public void setImageId(int imageId) { + this.imageId = imageId; + } + + public int getSimageId() { + return simageId; + } + + public void setSimageId(int simageId) { + this.simageId = simageId; + } + + public int getKind() { + return kind; + } + + public void setKind(int kind) { + this.kind = kind; + } + + public TypeBean() { + } + + public TypeBean(int id, String typename, int imageId, int simageId, int kind) { + this.id = id; + this.typename = typename; + this.imageId = imageId; + this.simageId = simageId; + this.kind = kind; + } +} diff --git a/simple-bookkeeping-master/app/src/main/java/com/hui/tally/frag_chart/BaseChartFragment.java b/simple-bookkeeping-master/app/src/main/java/com/hui/tally/frag_chart/BaseChartFragment.java new file mode 100644 index 0000000..6941547 --- /dev/null +++ b/simple-bookkeeping-master/app/src/main/java/com/hui/tally/frag_chart/BaseChartFragment.java @@ -0,0 +1,138 @@ +package com.hui.tally.frag_chart; + + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ListView; +import android.widget.TextView; + +import androidx.fragment.app.Fragment; + +import com.github.mikephil.charting.charts.BarChart; +import com.github.mikephil.charting.components.AxisBase; +import com.github.mikephil.charting.components.XAxis; +import com.github.mikephil.charting.formatter.IAxisValueFormatter; +import com.hui.tally.R; +import com.hui.tally.adapter.ChartItemAdapter; +import com.hui.tally.db.ChartItemBean; +import com.hui.tally.db.DBManager; + +import java.util.ArrayList; +import java.util.List; + +/** + * A simple {@link Fragment} subclass. + */ +abstract public class BaseChartFragment extends Fragment { + ListView chartLv; + int year; + int month; + ListmDatas; //数据源 + private ChartItemAdapter itemAdapter; + BarChart barChart; //代表柱状图的控件 + TextView chartTv; //如果没有收支情况,显示的TextView + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + + View view = inflater.inflate(R.layout.fragment_incom_chart, container, false); + chartLv = view.findViewById(R.id.frag_chart_lv); + //获取Activity传递的数据 + Bundle bundle = getArguments(); + year = bundle.getInt("year"); + month = bundle.getInt("month"); + //设置数据源 + mDatas = new ArrayList<>(); +// 设置适配器 + itemAdapter = new ChartItemAdapter(getContext(), mDatas); + chartLv.setAdapter(itemAdapter); +// 添加头布局 + addLVHeaderView(); + return view; + } + + protected void addLVHeaderView(){ +// 将布局转换成View对象 + View headerView = getLayoutInflater().inflate(R.layout.item_chartfrag_top,null); +// 将View添加到ListView的头布局上 + chartLv.addHeaderView(headerView); +// 查找头布局当中包含的控件 + barChart = headerView.findViewById(R.id.item_chartfrag_chart); + chartTv = headerView.findViewById(R.id.item_chartfrag_top_tv); +// 设定柱状图不显示描述 + barChart.getDescription().setEnabled(false); +// 设置柱状图的内边距 + barChart.setExtraOffsets(20, 20, 20, 20); + setAxis(year,month); // 设置坐标轴 +// 设置坐标轴显示的数据 + setAxisData(year,month); + } +/** 设置坐标轴显示的数据*/ + protected abstract void setAxisData(int year, int month); + + /** 设置柱状图坐标轴的显示 方法必须重新*/ + protected void setAxis(int year, final int month){ +// 设置X轴 + XAxis xAxis = barChart.getXAxis(); + xAxis.setPosition(XAxis.XAxisPosition.BOTTOM); //设置x轴显示在下方 + xAxis.setDrawGridLines(true); //设置绘制该轴的网格线 +// 设置x轴标签的个数 + xAxis.setLabelCount(31); + xAxis.setTextSize(12f); //x轴标签的大小 +// 设置X轴显示的值的格式 + xAxis.setValueFormatter(new IAxisValueFormatter() { + @Override + public String getFormattedValue(float value, AxisBase axis) { + int val = (int) value; + if (val == 0) { + return month+"-1"; + } + if (val==14) { + return month+"-15"; + } +// 根据不同的月份,显示最后一天的位置 + if (month==2) { + if (val == 27) { + return month+"-28"; + } + }else if(month==1||month==3||month==5||month==7||month==8||month==10||month==12){ + if (val == 30) { + return month+"-31"; + } + }else if(month==4||month==6||month==9||month==11){ + if (val==29) { + return month+"-30"; + } + } + return ""; + } + }); + xAxis.setYOffset(10); // 设置标签对x轴的偏移量,垂直方向 + + // y轴在子类的设置 + setYAxis(year,month); + } + + /* 设置y轴,因为最高的坐标不确定,所以在子类当中设置*/ + protected abstract void setYAxis(int year,int month); + + public void setDate(int year,int month){ + this.year = year; + this.month = month; + // 清空柱状图当中的数据 + barChart.clear(); + barChart.invalidate(); //重新绘制柱状图 + setAxis(year,month); + setAxisData(year,month); + } + + + public void loadData(int year,int month,int kind) { + List list = DBManager.getChartListFromAccounttb(year, month, kind); + mDatas.clear(); + mDatas.addAll(list); + itemAdapter.notifyDataSetChanged(); + } +} diff --git a/simple-bookkeeping-master/app/src/main/java/com/hui/tally/frag_chart/IncomChartFragment.java b/simple-bookkeeping-master/app/src/main/java/com/hui/tally/frag_chart/IncomChartFragment.java new file mode 100644 index 0000000..9bb7448 --- /dev/null +++ b/simple-bookkeeping-master/app/src/main/java/com/hui/tally/frag_chart/IncomChartFragment.java @@ -0,0 +1,120 @@ +package com.hui.tally.frag_chart; + + +import android.graphics.Color; +import android.os.Bundle; + +import androidx.fragment.app.Fragment; + +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ListView; + +import com.github.mikephil.charting.components.Legend; +import com.github.mikephil.charting.components.YAxis; +import com.github.mikephil.charting.data.BarData; +import com.github.mikephil.charting.data.BarDataSet; +import com.github.mikephil.charting.data.BarEntry; +import com.github.mikephil.charting.data.Entry; +import com.github.mikephil.charting.formatter.IValueFormatter; +import com.github.mikephil.charting.interfaces.datasets.IBarDataSet; +import com.github.mikephil.charting.utils.ViewPortHandler; +import com.hui.tally.R; +import com.hui.tally.adapter.ChartItemAdapter; +import com.hui.tally.db.BarChartItemBean; +import com.hui.tally.db.ChartItemBean; +import com.hui.tally.db.DBManager; + +import java.util.ArrayList; +import java.util.List; + +/** + * A simple {@link Fragment} subclass. + */ +public class IncomChartFragment extends BaseChartFragment { + int kind = 1; + @Override + public void onResume() { + super.onResume(); + loadData(year,month,kind); + } + + @Override + protected void setAxisData(int year, int month) { + List sets = new ArrayList<>(); +// 获取这个月每天的支出总金额, + List list = DBManager.getSumMoneyOneDayInMonth(year, month, kind); + if (list.size() == 0) { + barChart.setVisibility(View.GONE); + chartTv.setVisibility(View.VISIBLE); + }else{ + barChart.setVisibility(View.VISIBLE); + chartTv.setVisibility(View.GONE); +// 设置有多少根柱子 + List barEntries1 = new ArrayList<>(); + for (int i = 0; i < 31; i++) { +// 初始化每一根柱子,添加到柱状图当中 + BarEntry entry = new BarEntry(i, 0.0f); + barEntries1.add(entry); + } + for (int i = 0; i < list.size(); i++) { + BarChartItemBean itemBean = list.get(i); + int day = itemBean.getDay(); //获取日期 + // 根据天数,获取x轴的位置 + int xIndex = day-1; + BarEntry barEntry = barEntries1.get(xIndex); + barEntry.setY(itemBean.getSummoney()); + } + BarDataSet barDataSet1 = new BarDataSet(barEntries1, ""); + barDataSet1.setValueTextColor(Color.BLACK); // 值的颜色 + barDataSet1.setValueTextSize(8f); // 值的大小 + barDataSet1.setColor(Color.parseColor("#006400")); // 柱子的颜色 + + // 设置柱子上数据显示的格式 + barDataSet1.setValueFormatter(new IValueFormatter() { + @Override + public String getFormattedValue(float value, Entry entry, int dataSetIndex, ViewPortHandler viewPortHandler) { + // 此处的value默认保存一位小数 + if (value==0) { + return ""; + } + return value + ""; + } + }); + sets.add(barDataSet1); + + BarData barData = new BarData(sets); + barData.setBarWidth(0.2f); // 设置柱子的宽度 + barChart.setData(barData); + } + } + + @Override + protected void setYAxis(int year, int month) { +// 获取本月收入最高的一天为多少,将他设定为y轴的最大值 + float maxMoney = DBManager.getMaxMoneyOneDayInMonth(year, month, kind); + float max = (float) Math.ceil(maxMoney); // 将最大金额向上取整 +// 设置y轴 + YAxis yAxis_right = barChart.getAxisRight(); + yAxis_right.setAxisMaximum(max); // 设置y轴的最大值 + yAxis_right.setAxisMinimum(0f); // 设置y轴的最小值 + yAxis_right.setEnabled(false); // 不显示右边的y轴 + + YAxis yAxis_left = barChart.getAxisLeft(); + yAxis_left.setAxisMaximum(max); + yAxis_left.setAxisMinimum(0f); + yAxis_left.setEnabled(false); + +// 设置不显示图例 + Legend legend = barChart.getLegend(); + legend.setEnabled(false); + } + + + @Override + public void setDate(int year, int month) { + super.setDate(year, month); + loadData(year,month,kind); + } +} diff --git a/simple-bookkeeping-master/app/src/main/java/com/hui/tally/frag_chart/OutcomChartFragment.java b/simple-bookkeeping-master/app/src/main/java/com/hui/tally/frag_chart/OutcomChartFragment.java new file mode 100644 index 0000000..0a47834 --- /dev/null +++ b/simple-bookkeeping-master/app/src/main/java/com/hui/tally/frag_chart/OutcomChartFragment.java @@ -0,0 +1,116 @@ +package com.hui.tally.frag_chart; + + +import android.graphics.Color; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.fragment.app.Fragment; + +import com.github.mikephil.charting.components.Legend; +import com.github.mikephil.charting.components.YAxis; +import com.github.mikephil.charting.data.BarData; +import com.github.mikephil.charting.data.BarDataSet; +import com.github.mikephil.charting.data.BarEntry; +import com.github.mikephil.charting.data.Entry; +import com.github.mikephil.charting.formatter.IValueFormatter; +import com.github.mikephil.charting.interfaces.datasets.IBarDataSet; +import com.github.mikephil.charting.utils.ViewPortHandler; +import com.hui.tally.R; +import com.hui.tally.db.BarChartItemBean; +import com.hui.tally.db.DBManager; + +import java.util.ArrayList; +import java.util.List; + +/** + * A simple {@link Fragment} subclass. + */ +public class OutcomChartFragment extends BaseChartFragment { + int kind = 0; + @Override + public void onResume() { + super.onResume(); + loadData(year,month,kind); + } + + + @Override + protected void setAxisData(int year, int month) { + List sets = new ArrayList<>(); +// 获取这个月每天的支出总金额, + List list = DBManager.getSumMoneyOneDayInMonth(year, month, kind); + if (list.size() == 0) { + barChart.setVisibility(View.GONE); + chartTv.setVisibility(View.VISIBLE); + }else{ + barChart.setVisibility(View.VISIBLE); + chartTv.setVisibility(View.GONE); +// 设置有多少根柱子 + List barEntries1 = new ArrayList<>(); + for (int i = 0; i < 31; i++) { +// 初始化每一根柱子,添加到柱状图当中 + BarEntry entry = new BarEntry(i, 0.0f); + barEntries1.add(entry); + } + for (int i = 0; i < list.size(); i++) { + BarChartItemBean itemBean = list.get(i); + int day = itemBean.getDay(); //获取日期 + // 根据天数,获取x轴的位置 + int xIndex = day-1; + BarEntry barEntry = barEntries1.get(xIndex); + barEntry.setY(itemBean.getSummoney()); + } + BarDataSet barDataSet1 = new BarDataSet(barEntries1, ""); + barDataSet1.setValueTextColor(Color.BLACK); // 值的颜色 + barDataSet1.setValueTextSize(8f); // 值的大小 + barDataSet1.setColor(Color.RED); // 柱子的颜色 + + // 设置柱子上数据显示的格式 + barDataSet1.setValueFormatter(new IValueFormatter() { + @Override + public String getFormattedValue(float value, Entry entry, int dataSetIndex, ViewPortHandler viewPortHandler) { + // 此处的value默认保存一位小数 + if (value==0) { + return ""; + } + return value + ""; + } + }); + sets.add(barDataSet1); + + BarData barData = new BarData(sets); + barData.setBarWidth(0.2f); // 设置柱子的宽度 + barChart.setData(barData); + } + } + + @Override + protected void setYAxis(int year, int month) { +// 获取本月收入最高的一天为多少,将他设定为y轴的最大值 + float maxMoney = DBManager.getMaxMoneyOneDayInMonth(year, month, kind); + float max = (float) Math.ceil(maxMoney); // 将最大金额向上取整 +// 设置y轴 + YAxis yAxis_right = barChart.getAxisRight(); + yAxis_right.setAxisMaximum(max); // 设置y轴的最大值 + yAxis_right.setAxisMinimum(0f); // 设置y轴的最小值 + yAxis_right.setEnabled(false); // 不显示右边的y轴 + + YAxis yAxis_left = barChart.getAxisLeft(); + yAxis_left.setAxisMaximum(max); + yAxis_left.setAxisMinimum(0f); + yAxis_left.setEnabled(false); + +// 设置不显示图例 + Legend legend = barChart.getLegend(); + legend.setEnabled(false); + } + + @Override + public void setDate(int year, int month) { + super.setDate(year, month); + loadData(year,month,kind); + } +} diff --git a/simple-bookkeeping-master/app/src/main/java/com/hui/tally/frag_record/BaseRecordFragment.java b/simple-bookkeeping-master/app/src/main/java/com/hui/tally/frag_record/BaseRecordFragment.java new file mode 100644 index 0000000..5de5a68 --- /dev/null +++ b/simple-bookkeeping-master/app/src/main/java/com/hui/tally/frag_record/BaseRecordFragment.java @@ -0,0 +1,188 @@ +package com.hui.tally.frag_record; +import android.inputmethodservice.KeyboardView; +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import android.text.TextUtils; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.AdapterView; +import android.widget.EditText; +import android.widget.GridView; +import android.widget.ImageView; +import android.widget.TextView; + +import com.hui.tally.R; +import com.hui.tally.db.AccountBean; +import com.hui.tally.db.DBManager; +import com.hui.tally.db.TypeBean; +import com.hui.tally.utils.BeiZhuDialog; +import com.hui.tally.utils.KeyBoardUtils; +import com.hui.tally.utils.SelectTimeDialog; + +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; +import java.util.List; + +/** + * 记录页面当中的支出模块 + */ +public abstract class BaseRecordFragment extends Fragment implements View.OnClickListener { + + KeyboardView keyboardView; + EditText moneyEt; + ImageView typeIv; + TextView typeTv,beizhuTv,timeTv; + GridView typeGv; + ListtypeList; + TypeBaseAdapter adapter; + AccountBean accountBean; //将需要插入到记账本当中的数据保存成对象的形式 + + @Override + public void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + accountBean = new AccountBean(); //创建对象 + accountBean.setTypename("其他"); + accountBean.setsImageId(R.mipmap.ic_qita_fs); + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + // Inflate the layout for this fragment + View view = inflater.inflate(R.layout.fragment_outcome, container, false); + initView(view); + setInitTime(); + //给GridView填充数据的方法 + loadDataToGV(); + setGVListener(); //设置GridView每一项的点击事件 + return view; + } + /* 获取当前时间,显示在timeTv上*/ + private void setInitTime() { + Date date = new Date(); + SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm"); + String time = sdf.format(date); + timeTv.setText(time); + accountBean.setTime(time); + + Calendar calendar = Calendar.getInstance(); + int year = calendar.get(Calendar.YEAR); + int month = calendar.get(Calendar.MONTH)+1; + int day = calendar.get(Calendar.DAY_OF_MONTH); + accountBean.setYear(year); + accountBean.setMonth(month); + accountBean.setDay(day); + } + + /* 设置GridView每一项的点击事件*/ + private void setGVListener() { + typeGv.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + adapter.selectPos = position; + adapter.notifyDataSetInvalidated(); //提示绘制发生变化了 + TypeBean typeBean = typeList.get(position); + String typename = typeBean.getTypename(); + typeTv.setText(typename); + accountBean.setTypename(typename); + int simageId = typeBean.getSimageId(); + typeIv.setImageResource(simageId); + accountBean.setsImageId(simageId); + } + }); + } + + /* 给GridView填出数据的方法*/ + public void loadDataToGV() { + typeList = new ArrayList<>(); + adapter = new TypeBaseAdapter(getContext(), typeList); + typeGv.setAdapter(adapter); + } + + private void initView(View view) { + keyboardView = view.findViewById(R.id.frag_record_keyboard); + moneyEt = view.findViewById(R.id.frag_record_et_money); + typeIv = view.findViewById(R.id.frag_record_iv); + typeGv = view.findViewById(R.id.frag_record_gv); + typeTv = view.findViewById(R.id.frag_record_tv_type); + beizhuTv = view.findViewById(R.id.frag_record_tv_beizhu); + timeTv = view.findViewById(R.id.frag_record_tv_time); + beizhuTv.setOnClickListener(this); + timeTv.setOnClickListener(this); + //让自定义软键盘显示出来 + KeyBoardUtils boardUtils = new KeyBoardUtils(keyboardView, moneyEt); + boardUtils.showKeyboard(); + //设置接口,监听确定按钮按钮被点击了 + boardUtils.setOnEnsureListener(new KeyBoardUtils.OnEnsureListener() { + @Override + public void onEnsure() { + //获取输入钱数 + String moneyStr = moneyEt.getText().toString(); + if (TextUtils.isEmpty(moneyStr)||moneyStr.equals("0")) { + getActivity().finish(); + return; + } + float money = Float.parseFloat(moneyStr); + accountBean.setMoney(money); + //获取记录的信息,保存在数据库当中 + saveAccountToDB(); + // 返回上一级页面 + getActivity().finish(); + } + }); + } + /* 让子类一定要重写这个方法*/ + public abstract void saveAccountToDB(); + + @Override + public void onClick(View v) { + switch (v.getId()) { + case R.id.frag_record_tv_time: + showTimeDialog(); + break; + case R.id.frag_record_tv_beizhu: + showBZDialog(); + break; + } + } + /* 弹出显示时间的对话框*/ + private void showTimeDialog() { + SelectTimeDialog dialog = new SelectTimeDialog(getContext()); + dialog.show(); + //设定确定按钮被点击了的监听器 + dialog.setOnEnsureListener(new SelectTimeDialog.OnEnsureListener() { + @Override + public void onEnsure(String time, int year, int month, int day) { + timeTv.setText(time); + accountBean.setTime(time); + accountBean.setYear(year); + accountBean.setMonth(month); + accountBean.setDay(day); + } + }); + } + + /* 弹出备注对话框*/ + public void showBZDialog(){ + final BeiZhuDialog dialog = new BeiZhuDialog(getContext()); + dialog.show(); + dialog.setDialogSize(); + dialog.setOnEnsureListener(new BeiZhuDialog.OnEnsureListener() { + @Override + public void onEnsure() { + String msg = dialog.getEditText(); + if (!TextUtils.isEmpty(msg)) { + beizhuTv.setText(msg); + accountBean.setBeizhu(msg); + } + dialog.cancel(); + } + }); + } +} diff --git a/simple-bookkeeping-master/app/src/main/java/com/hui/tally/frag_record/IncomeFragment.java b/simple-bookkeeping-master/app/src/main/java/com/hui/tally/frag_record/IncomeFragment.java new file mode 100644 index 0000000..0ff829f --- /dev/null +++ b/simple-bookkeeping-master/app/src/main/java/com/hui/tally/frag_record/IncomeFragment.java @@ -0,0 +1,28 @@ +package com.hui.tally.frag_record; +import com.hui.tally.R; +import com.hui.tally.db.DBManager; +import com.hui.tally.db.TypeBean; +import java.util.List; +/** + * 收入记录页面 + */ +public class IncomeFragment extends BaseRecordFragment { + + + @Override + public void loadDataToGV() { + super.loadDataToGV(); + //获取数据库当中的数据源 + List inlist = DBManager.getTypeList(1); + typeList.addAll(inlist); + adapter.notifyDataSetChanged(); + typeTv.setText("其他"); + typeIv.setImageResource(R.mipmap.in_qt_fs); + } + + @Override + public void saveAccountToDB() { + accountBean.setKind(1); + DBManager.insertItemToAccounttb(accountBean); + } +} diff --git a/simple-bookkeeping-master/app/src/main/java/com/hui/tally/frag_record/OutcomeFragment.java b/simple-bookkeeping-master/app/src/main/java/com/hui/tally/frag_record/OutcomeFragment.java new file mode 100644 index 0000000..3d354db --- /dev/null +++ b/simple-bookkeeping-master/app/src/main/java/com/hui/tally/frag_record/OutcomeFragment.java @@ -0,0 +1,30 @@ +package com.hui.tally.frag_record; +import androidx.fragment.app.Fragment; +import com.hui.tally.R; +import com.hui.tally.db.DBManager; +import com.hui.tally.db.TypeBean; +import java.util.List; +/** + * A simple {@link Fragment} subclass. + */ +public class OutcomeFragment extends BaseRecordFragment { + + + // 重写 + @Override + public void loadDataToGV() { + super.loadDataToGV(); + //获取数据库当中的数据源 + List outlist = DBManager.getTypeList(0); + typeList.addAll(outlist); + adapter.notifyDataSetChanged(); + typeTv.setText("其他"); + typeIv.setImageResource(R.mipmap.ic_qita_fs); + } + + @Override + public void saveAccountToDB() { + accountBean.setKind(0); + DBManager.insertItemToAccounttb(accountBean); + } +} diff --git a/simple-bookkeeping-master/app/src/main/java/com/hui/tally/frag_record/TypeBaseAdapter.java b/simple-bookkeeping-master/app/src/main/java/com/hui/tally/frag_record/TypeBaseAdapter.java new file mode 100644 index 0000000..cd9ff7a --- /dev/null +++ b/simple-bookkeeping-master/app/src/main/java/com/hui/tally/frag_record/TypeBaseAdapter.java @@ -0,0 +1,54 @@ +package com.hui.tally.frag_record; +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; +import android.widget.TextView; +import com.hui.tally.R; +import com.hui.tally.db.TypeBean; +import java.util.List; + +public class TypeBaseAdapter extends BaseAdapter { + Context context; + ListmDatas; + int selectPos = 0; //选中位置 + public TypeBaseAdapter(Context context, List mDatas) { + this.context = context; + this.mDatas = mDatas; + } + + @Override + public int getCount() { + return mDatas.size(); + } + + @Override + public Object getItem(int position) { + return mDatas.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } +// 此适配器不考虑复用问题,因为所有的item都显示在界面上,不会因为滑动就消失,所有没有剩余的convertView,所以不用复写 + @Override + public View getView(int position, View convertView, ViewGroup parent) { + convertView = LayoutInflater.from(context).inflate(R.layout.item_recordfrag_gv,parent,false); + //查找布局当中的控件 + ImageView iv = convertView.findViewById(R.id.item_recordfrag_iv); + TextView tv = convertView.findViewById(R.id.item_recordfrag_tv); + //获取指定位置的数据源 + TypeBean typeBean = mDatas.get(position); + tv.setText(typeBean.getTypename()); +// 判断当前位置是否为选中位置,如果是选中位置,就设置为带颜色的图片,否则为灰色图片 + if (selectPos == position) { + iv.setImageResource(typeBean.getSimageId()); + }else{ + iv.setImageResource(typeBean.getImageId()); + } + return convertView; + } +} diff --git a/simple-bookkeeping-master/app/src/main/java/com/hui/tally/utils/BeiZhuDialog.java b/simple-bookkeeping-master/app/src/main/java/com/hui/tally/utils/BeiZhuDialog.java new file mode 100644 index 0000000..b268dda --- /dev/null +++ b/simple-bookkeeping-master/app/src/main/java/com/hui/tally/utils/BeiZhuDialog.java @@ -0,0 +1,89 @@ +package com.hui.tally.utils; + +import android.app.Dialog; +import android.content.Context; +import android.os.Bundle; +import android.os.Handler; +import android.os.Message; +import android.view.Display; +import android.view.Gravity; +import android.view.View; +import android.view.Window; +import android.view.WindowManager; +import android.view.inputmethod.InputMethodManager; +import android.widget.Button; +import android.widget.EditText; + +import androidx.annotation.NonNull; + +import com.hui.tally.R; + +public class BeiZhuDialog extends Dialog implements View.OnClickListener { + EditText et; + Button cancelBtn,ensureBtn; + OnEnsureListener onEnsureListener; + // 设定回调接口的方法 + public void setOnEnsureListener(OnEnsureListener onEnsureListener) { + this.onEnsureListener = onEnsureListener; + } + + public BeiZhuDialog(@NonNull Context context) { + super(context); + } + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.dialog_beizhu);//设置对话框显示布局 + et = findViewById(R.id.dialog_beizhu_et); + cancelBtn = findViewById(R.id.dialog_beizhu_btn_cancel); + ensureBtn = findViewById(R.id.dialog_beizhu_btn_ensure); + cancelBtn.setOnClickListener(this); + ensureBtn.setOnClickListener(this); + } + public interface OnEnsureListener{ + public void onEnsure(); + } + + @Override + public void onClick(View v) { + switch (v.getId()) { + case R.id.dialog_beizhu_btn_cancel: + cancel(); + break; + case R.id.dialog_beizhu_btn_ensure: + if (onEnsureListener!=null) { + onEnsureListener.onEnsure(); + } + break; + } + } + +// 获取输入数据的方法 + public String getEditText(){ + return et.getText().toString().trim(); + } + /* 设置Dialog的尺寸和屏幕尺寸一致*/ + public void setDialogSize(){ +// 获取当前窗口对象 + Window window = getWindow(); +// 获取窗口对象的参数 + WindowManager.LayoutParams wlp = window.getAttributes(); +// 获取屏幕宽度 + Display d = window.getWindowManager().getDefaultDisplay(); + wlp.width = (int)(d.getWidth()); //对话框窗口为屏幕窗口 + wlp.gravity = Gravity.BOTTOM; + window.setBackgroundDrawableResource(android.R.color.transparent); + window.setAttributes(wlp); + handler.sendEmptyMessageDelayed(1,100); + } + + Handler handler = new Handler(){ + @Override + public void handleMessage(@NonNull Message msg) { + //自动弹出软键盘的方法 + InputMethodManager inputMethodManager = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE); + inputMethodManager.toggleSoftInput(0,InputMethodManager.HIDE_NOT_ALWAYS); + } + }; +} diff --git a/simple-bookkeeping-master/app/src/main/java/com/hui/tally/utils/BudgetDialog.java b/simple-bookkeeping-master/app/src/main/java/com/hui/tally/utils/BudgetDialog.java new file mode 100644 index 0000000..575008b --- /dev/null +++ b/simple-bookkeeping-master/app/src/main/java/com/hui/tally/utils/BudgetDialog.java @@ -0,0 +1,101 @@ +package com.hui.tally.utils; + +import android.app.Dialog; +import android.content.Context; +import android.os.Bundle; +import android.os.Handler; +import android.os.Message; +import android.text.TextUtils; +import android.view.Display; +import android.view.Gravity; +import android.view.View; +import android.view.Window; +import android.view.WindowManager; +import android.view.inputmethod.InputMethodManager; +import android.widget.Button; +import android.widget.EditText; +import android.widget.ImageView; +import android.widget.Toast; + +import androidx.annotation.NonNull; + +import com.hui.tally.R; + +public class BudgetDialog extends Dialog implements View.OnClickListener { + ImageView cancelIv; + Button ensureBtn; + EditText moneyEt; + public interface OnEnsureListener{ + public void onEnsure(float money); + } + OnEnsureListener onEnsureListener; + + public void setOnEnsureListener(OnEnsureListener onEnsureListener) { + this.onEnsureListener = onEnsureListener; + } + + public BudgetDialog(@NonNull Context context) { + super(context); + } + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.dialog_budget); + cancelIv = findViewById(R.id.dialog_budget_iv_error); + ensureBtn = findViewById(R.id.dialog_budget_btn_ensure); + moneyEt = findViewById(R.id.dialog_budget_et); + cancelIv.setOnClickListener(this); + ensureBtn.setOnClickListener(this); + } + + @Override + public void onClick(View v) { + switch (v.getId()) { + case R.id.dialog_budget_iv_error: + cancel(); //取消对话框 + break; + case R.id.dialog_budget_btn_ensure: + //获取输入数据数值 + String data = moneyEt.getText().toString(); + if (TextUtils.isEmpty(data)) { + Toast.makeText(getContext(),"输入数据不能为空!",Toast.LENGTH_SHORT).show(); + return; + } + float money = Float.parseFloat(data); + if (money<=0) { + Toast.makeText(getContext(),"预算金额必须大于0",Toast.LENGTH_SHORT).show(); + return; + } + if (onEnsureListener!=null) { + onEnsureListener.onEnsure(money); + } + cancel(); + break; + } + } + + /* 设置Dialog的尺寸和屏幕尺寸一致*/ + public void setDialogSize(){ +// 获取当前窗口对象 + Window window = getWindow(); +// 获取窗口对象的参数 + WindowManager.LayoutParams wlp = window.getAttributes(); +// 获取屏幕宽度 + Display d = window.getWindowManager().getDefaultDisplay(); + wlp.width = (int)(d.getWidth()); //对话框窗口为屏幕窗口 + wlp.gravity = Gravity.BOTTOM; + window.setBackgroundDrawableResource(android.R.color.transparent); + window.setAttributes(wlp); + handler.sendEmptyMessageDelayed(1,100); + } + + Handler handler = new Handler(){ + @Override + public void handleMessage(@NonNull Message msg) { + //自动弹出软键盘的方法 + InputMethodManager inputMethodManager = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE); + inputMethodManager.toggleSoftInput(0,InputMethodManager.HIDE_NOT_ALWAYS); + } + }; +} diff --git a/simple-bookkeeping-master/app/src/main/java/com/hui/tally/utils/CalendarDialog.java b/simple-bookkeeping-master/app/src/main/java/com/hui/tally/utils/CalendarDialog.java new file mode 100644 index 0000000..019c53a --- /dev/null +++ b/simple-bookkeeping-master/app/src/main/java/com/hui/tally/utils/CalendarDialog.java @@ -0,0 +1,174 @@ +package com.hui.tally.utils; + +import android.app.Dialog; +import android.content.Context; +import android.graphics.Color; +import android.os.Bundle; +import android.view.Display; +import android.view.Gravity; +import android.view.View; +import android.view.Window; +import android.view.WindowManager; +import android.widget.AdapterView; +import android.widget.GridView; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.TextView; + +import com.hui.tally.R; +import com.hui.tally.adapter.CalendarAdapter; +import com.hui.tally.db.DBManager; + +import androidx.annotation.NonNull; + +import java.util.ArrayList; +import java.util.Calendar; +import java.util.List; + +public class CalendarDialog extends Dialog implements View.OnClickListener { + ImageView errorIv; + GridView gv; + LinearLayout hsvLayout; + + ListhsvViewList; + ListyearList; + + int selectPos = -1; //表示正在被点击的年份的位置 + private CalendarAdapter adapter; + int selectMonth = -1; + + public interface OnRefreshListener{ + public void onRefresh(int selPos,int year,int month); + } + OnRefreshListener onRefreshListener; + + public void setOnRefreshListener(OnRefreshListener onRefreshListener) { + this.onRefreshListener = onRefreshListener; + } + + public CalendarDialog(@NonNull Context context,int selectPos,int selectMonth) { + super(context); + this.selectPos = selectPos; + this.selectMonth = selectMonth; + } + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.dialog_calendar); + gv = findViewById(R.id.dialog_calendar_gv); + errorIv = findViewById(R.id.dialog_calendar_iv); + hsvLayout = findViewById(R.id.dialog_calendar_layout); + errorIv.setOnClickListener(this); + // 向横向的ScrollView当中添加View的方法 + addViewToLayout(); + initGridView(); + //设置GridView当中每一个item的点击事件 + setGVListener(); + } + + private void setGVListener() { + gv.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + adapter.selPos = position; + adapter.notifyDataSetInvalidated(); + int month = position + 1; + int year = adapter.year; + // 获取到被选中的年份和月份 + onRefreshListener.onRefresh(selectPos,year,month); + cancel(); + } + }); + } + + private void initGridView() { + int selYear = yearList.get(selectPos); + adapter = new CalendarAdapter(getContext(), selYear); + if (selectMonth == -1) { + int month = Calendar.getInstance().get(Calendar.MONTH); + adapter.selPos = month; + }else { + adapter.selPos = selectMonth-1; + } + gv.setAdapter(adapter); + } + + private void addViewToLayout() { + hsvViewList = new ArrayList<>(); //将添加进入线性布局当中的TextView进行统一管理的集合 + yearList = DBManager.getYearListFromAccounttb(); //获取数据库当中存储了多少个年份 + //如果数据库当中没有记录,就添加今年的记录 + if (yearList.size() == 0) { + int year = Calendar.getInstance().get(Calendar.YEAR); + yearList.add(year); + } + + //遍历年份,有几年,就向ScrollView当中添加几个view + for (int i = 0; i < yearList.size(); i++) { + int year = yearList.get(i); + View view = getLayoutInflater().inflate(R.layout.item_dialogcal_hsv, null); + hsvLayout.addView(view); //将view添加到布局当中 + TextView hsvTv = view.findViewById(R.id.item_dialogcal_hsv_tv); + hsvTv.setText(year+""); + hsvViewList.add(hsvTv); + } + if (selectPos == -1) { + selectPos = hsvViewList.size()-1; //设置当前被选中的是最近的年份 + } + changeTvbg(selectPos); //将最后一个设置为选中状态 + setHSVClickListener(); //设置每一个View的监听事件 + } + /** 给横向的ScrollView当中每一个TextView设置点击事件*/ + private void setHSVClickListener() { + for (int i = 0; i < hsvViewList.size(); i++) { + TextView view = hsvViewList.get(i); + final int pos = i; + view.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + changeTvbg(pos); + selectPos = pos; + // 获取被选中的年份,然后下面的GridView显示数据源会发生变化 + int year = yearList.get(selectPos); + adapter.setYear(year); + } + }); + } + } + + /** 传入被选中的位置,改变此位置上的背景和文字颜色*/ + private void changeTvbg(int selectPos) { + for (int i = 0; i < hsvViewList.size(); i++) { + TextView tv = hsvViewList.get(i); + tv.setBackgroundResource(R.drawable.dialog_btn_bg); + tv.setTextColor(Color.BLACK); + } + + TextView selView = hsvViewList.get(selectPos); + selView.setBackgroundResource(R.drawable.main_recordbtn_bg); + selView.setTextColor(Color.WHITE); + } + + @Override + public void onClick(View v) { + switch (v.getId()) { + case R.id.dialog_calendar_iv: + cancel(); + break; + } + } + + /* 设置Dialog的尺寸和屏幕尺寸一致*/ + public void setDialogSize(){ +// 获取当前窗口对象 + Window window = getWindow(); +// 获取窗口对象的参数 + WindowManager.LayoutParams wlp = window.getAttributes(); +// 获取屏幕宽度 + Display d = window.getWindowManager().getDefaultDisplay(); + wlp.width = (int)(d.getWidth()); //对话框窗口为屏幕窗口 + wlp.gravity = Gravity.TOP; + window.setBackgroundDrawableResource(android.R.color.transparent); + window.setAttributes(wlp); + } +} diff --git a/simple-bookkeeping-master/app/src/main/java/com/hui/tally/utils/FloatUtils.java b/simple-bookkeeping-master/app/src/main/java/com/hui/tally/utils/FloatUtils.java new file mode 100644 index 0000000..72e6790 --- /dev/null +++ b/simple-bookkeeping-master/app/src/main/java/com/hui/tally/utils/FloatUtils.java @@ -0,0 +1,23 @@ +package com.hui.tally.utils; + +import java.math.BigDecimal; + +public class FloatUtils { + + /* 进行除法运算,保留4位小数*/ + public static float div(float v1,float v2){ + float v3 = v1/v2; + BigDecimal b1 = new BigDecimal(v3); + float val = b1.setScale(4, 4).floatValue(); + return val; + } + +// 将浮点数类型,转换成百分比显示形式 + public static String ratioToPercent(float val){ + float v = val*100; + BigDecimal b1 = new BigDecimal(v); + float v1 = b1.setScale(2, 4).floatValue(); + String per = v1+"%"; + return per; + } +} diff --git a/simple-bookkeeping-master/app/src/main/java/com/hui/tally/utils/KeyBoardUtils.java b/simple-bookkeeping-master/app/src/main/java/com/hui/tally/utils/KeyBoardUtils.java new file mode 100644 index 0000000..993adb6 --- /dev/null +++ b/simple-bookkeeping-master/app/src/main/java/com/hui/tally/utils/KeyBoardUtils.java @@ -0,0 +1,100 @@ +package com.hui.tally.utils; + +import android.inputmethodservice.Keyboard; +import android.inputmethodservice.KeyboardView; +import android.text.Editable; +import android.text.InputType; +import android.view.View; +import android.widget.EditText; + +import com.hui.tally.R; + +public class KeyBoardUtils { + private final Keyboard k1; //自定义键盘 + private KeyboardView keyboardView; + private EditText editText; + + public interface OnEnsureListener{ + public void onEnsure(); + } + OnEnsureListener onEnsureListener; + + public void setOnEnsureListener(OnEnsureListener onEnsureListener) { + this.onEnsureListener = onEnsureListener; + } + + public KeyBoardUtils(KeyboardView keyboardView, EditText editText) { + this.keyboardView = keyboardView; + this.editText = editText; + this.editText.setInputType(InputType.TYPE_NULL); //取消弹出系统键盘 + k1 = new Keyboard(this.editText.getContext(), R.xml.key); + + this.keyboardView.setKeyboard(k1); //设置要显示键盘的样式 + this.keyboardView.setEnabled(true); + this.keyboardView.setPreviewEnabled(false); + this.keyboardView.setOnKeyboardActionListener(listener); //设置键盘按钮被点击了的监听 + } + + KeyboardView.OnKeyboardActionListener listener = new KeyboardView.OnKeyboardActionListener() { + @Override + public void onPress(int primaryCode) { + } + @Override + public void onRelease(int primaryCode) { + } + @Override + public void onKey(int primaryCode, int[] keyCodes) { + Editable editable = editText.getText(); + int start = editText.getSelectionStart(); + switch (primaryCode) { + case Keyboard.KEYCODE_DELETE: //点击了删除键 + if (editable!=null &&editable.length()>0) { + if (start>0) { + editable.delete(start-1,start); + } + } + break; + case Keyboard.KEYCODE_CANCEL: //点击了清零 + editable.clear(); + break; + case Keyboard.KEYCODE_DONE: //点击了完成 + onEnsureListener.onEnsure(); //通过接口回调的方法,当点击确定时,可以调用这个方法 + break; + default: //其他数字直接插入 + editable.insert(start,Character.toString((char)primaryCode)); + break; + } + } + @Override + public void onText(CharSequence text) { + } + @Override + public void swipeLeft() { + } + @Override + public void swipeRight() { + } + @Override + public void swipeDown() { + } + @Override + public void swipeUp() { + } + }; + +// 显示键盘 + public void showKeyboard(){ + int visibility = keyboardView.getVisibility(); + if (visibility == View.INVISIBLE ||visibility==View.GONE) { + keyboardView.setVisibility(View.VISIBLE); + } + } + +// 隐藏键盘 + public void hideKeyboard(){ + int visibility = keyboardView.getVisibility(); + if (visibility== View.VISIBLE||visibility==View.INVISIBLE) { + keyboardView.setVisibility(View.GONE); + } + } +} diff --git a/simple-bookkeeping-master/app/src/main/java/com/hui/tally/utils/MoreDialog.java b/simple-bookkeeping-master/app/src/main/java/com/hui/tally/utils/MoreDialog.java new file mode 100644 index 0000000..402a41a --- /dev/null +++ b/simple-bookkeeping-master/app/src/main/java/com/hui/tally/utils/MoreDialog.java @@ -0,0 +1,82 @@ +package com.hui.tally.utils; +import android.app.Dialog; +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; +import android.view.Display; +import android.view.Gravity; +import android.view.View; +import android.view.Window; +import android.view.WindowManager; +import android.widget.Button; +import android.widget.ImageView; +import androidx.annotation.NonNull; +import com.hui.tally.AboutActivity; +import com.hui.tally.HistoryActivity; +import com.hui.tally.MonthChartActivity; +import com.hui.tally.R; +import com.hui.tally.SettingActivity; + +public class MoreDialog extends Dialog implements View.OnClickListener { + Button aboutBtn,settingBtn,historyBtn,infoBtn; + ImageView errorIv; + public MoreDialog(@NonNull Context context) { + super(context); + } + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.dialog_more); + aboutBtn = findViewById(R.id.dialog_more_btn_about); + settingBtn = findViewById(R.id.dialog_more_btn_setting); + historyBtn = findViewById(R.id.dialog_more_btn_record); + infoBtn = findViewById(R.id.dialog_more_btn_info); + errorIv = findViewById(R.id.dialog_more_iv); + + aboutBtn.setOnClickListener(this); + settingBtn.setOnClickListener(this); + historyBtn.setOnClickListener(this); + infoBtn.setOnClickListener(this); + errorIv.setOnClickListener(this); + } + + @Override + public void onClick(View v) { + Intent intent = new Intent(); + switch (v.getId()) { + case R.id.dialog_more_btn_about: + intent.setClass(getContext(), AboutActivity.class); + getContext().startActivity(intent); + break; + case R.id.dialog_more_btn_setting: + intent.setClass(getContext(), SettingActivity.class); + getContext().startActivity(intent); + break; + case R.id.dialog_more_btn_record: + intent.setClass(getContext(), HistoryActivity.class); + getContext().startActivity(intent); + break; + case R.id.dialog_more_btn_info: + intent.setClass(getContext(), MonthChartActivity.class); + getContext().startActivity(intent); + break; + case R.id.dialog_more_iv: + break; + } + cancel(); + } + + /* 设置Dialog的尺寸和屏幕尺寸一致*/ + public void setDialogSize(){ +// 获取当前窗口对象 + Window window = getWindow(); +// 获取窗口对象的参数 + WindowManager.LayoutParams wlp = window.getAttributes(); +// 获取屏幕宽度 + Display d = window.getWindowManager().getDefaultDisplay(); + wlp.width = (int)(d.getWidth()); //对话框窗口为屏幕窗口 + wlp.gravity = Gravity.BOTTOM; + window.setBackgroundDrawableResource(android.R.color.transparent); + window.setAttributes(wlp); + } +} diff --git a/simple-bookkeeping-master/app/src/main/java/com/hui/tally/utils/SelectTimeDialog.java b/simple-bookkeeping-master/app/src/main/java/com/hui/tally/utils/SelectTimeDialog.java new file mode 100644 index 0000000..28f2243 --- /dev/null +++ b/simple-bookkeeping-master/app/src/main/java/com/hui/tally/utils/SelectTimeDialog.java @@ -0,0 +1,136 @@ +package com.hui.tally.utils; + +import android.app.Dialog; +import android.content.Context; +import android.os.Bundle; +import android.text.TextUtils; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Button; +import android.widget.DatePicker; +import android.widget.EditText; + +import androidx.annotation.NonNull; + +import com.hui.tally.R; + +/* +* 在记录页面弹出时间对话框 +* */ +public class SelectTimeDialog extends Dialog implements View.OnClickListener { + EditText hourEt,minuteEt; + DatePicker datePicker; + Button ensureBtn,cancelBtn; + public interface OnEnsureListener{ + public void onEnsure(String time,int year,int month,int day); + } + OnEnsureListener onEnsureListener; + + public void setOnEnsureListener(OnEnsureListener onEnsureListener) { + this.onEnsureListener = onEnsureListener; + } + + public SelectTimeDialog(@NonNull Context context) { + super(context); + } + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.dialog_time); + hourEt = findViewById(R.id.dialog_time_et_hour); + minuteEt = findViewById(R.id.dialog_time_et_minute); + datePicker = findViewById(R.id.dialog_time_dp); + ensureBtn = findViewById(R.id.dialog_time_btn_ensure); + cancelBtn = findViewById(R.id.dialog_time_btn_cancel); + ensureBtn.setOnClickListener(this); //添加点击监听事件 + cancelBtn.setOnClickListener(this); + hideDatePickerHeader(); + } + + @Override + public void onClick(View v) { + switch (v.getId()) { + case R.id.dialog_time_btn_cancel: + cancel(); + break; + case R.id.dialog_time_btn_ensure: + int year = datePicker.getYear(); //选择年份 + int month = datePicker.getMonth()+1; + int dayOfMonth = datePicker.getDayOfMonth(); + String monthStr = String.valueOf(month); + if (month<10){ + monthStr = "0"+month; + } + String dayStr = String.valueOf(dayOfMonth); + if (dayOfMonth<10){ + dayStr="0"+dayOfMonth; + } +// 获取输入的小时和分钟 + String hourStr = hourEt.getText().toString(); + String minuteStr = minuteEt.getText().toString(); + int hour = 0; + if (!TextUtils.isEmpty(hourStr)) { + hour = Integer.parseInt(hourStr); + hour=hour%24; + } + int minute = 0; + if (!TextUtils.isEmpty(minuteStr)) { + minute = Integer.parseInt(minuteStr); + minute=minute%60; + } + + hourStr=String.valueOf(hour); + minuteStr=String.valueOf(minute); + if (hour<10){ + hourStr="0"+hour; + } + if (minute<10){ + minuteStr="0"+minute; + } + String timeFormat = year+"年"+monthStr+"月"+dayStr+"日 "+hourStr+":"+minuteStr; + if (onEnsureListener!=null) { + onEnsureListener.onEnsure(timeFormat,year,month,dayOfMonth); + } + cancel(); + break; + } + } + + //隐藏DatePicker头布局 + private void hideDatePickerHeader(){ + ViewGroup rootView = (ViewGroup) datePicker.getChildAt(0); + if (rootView == null) { + return; + } + View headerView = rootView.getChildAt(0); + if (headerView == null) { + return; + } + //5.0+ + int headerId = getContext().getResources().getIdentifier("day_picker_selector_layout", "id", "android"); + if (headerId == headerView.getId()) { + headerView.setVisibility(View.GONE); + ViewGroup.LayoutParams layoutParamsRoot = rootView.getLayoutParams(); + layoutParamsRoot.width = ViewGroup.LayoutParams.WRAP_CONTENT; + rootView.setLayoutParams(layoutParamsRoot); + + ViewGroup animator = (ViewGroup) rootView.getChildAt(1); + ViewGroup.LayoutParams layoutParamsAnimator = animator.getLayoutParams(); + layoutParamsAnimator.width = ViewGroup.LayoutParams.WRAP_CONTENT; + animator.setLayoutParams(layoutParamsAnimator); + + View child = animator.getChildAt(0); + ViewGroup.LayoutParams layoutParamsChild = child.getLayoutParams(); + layoutParamsChild.width = ViewGroup.LayoutParams.WRAP_CONTENT; + child.setLayoutParams(layoutParamsChild); + return; + } + + // 6.0+ + headerId = getContext().getResources().getIdentifier("date_picker_header","id","android"); + if (headerId == headerView.getId()) { + headerView.setVisibility(View.GONE); + } + } +} diff --git a/simple-bookkeeping-master/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/simple-bookkeeping-master/app/src/main/res/drawable-v24/ic_launcher_foreground.xml new file mode 100644 index 0000000..1f6bb29 --- /dev/null +++ b/simple-bookkeeping-master/app/src/main/res/drawable-v24/ic_launcher_foreground.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + diff --git a/simple-bookkeeping-master/app/src/main/res/drawable/dialog_btn_bg.xml b/simple-bookkeeping-master/app/src/main/res/drawable/dialog_btn_bg.xml new file mode 100644 index 0000000..b212535 --- /dev/null +++ b/simple-bookkeeping-master/app/src/main/res/drawable/dialog_btn_bg.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/simple-bookkeeping-master/app/src/main/res/drawable/ic_launcher_background.xml b/simple-bookkeeping-master/app/src/main/res/drawable/ic_launcher_background.xml new file mode 100644 index 0000000..0d025f9 --- /dev/null +++ b/simple-bookkeeping-master/app/src/main/res/drawable/ic_launcher_background.xml @@ -0,0 +1,170 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/simple-bookkeeping-master/app/src/main/res/drawable/main_morebtn_bg.xml b/simple-bookkeeping-master/app/src/main/res/drawable/main_morebtn_bg.xml new file mode 100644 index 0000000..76062df --- /dev/null +++ b/simple-bookkeeping-master/app/src/main/res/drawable/main_morebtn_bg.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/simple-bookkeeping-master/app/src/main/res/drawable/main_recordbtn_bg.xml b/simple-bookkeeping-master/app/src/main/res/drawable/main_recordbtn_bg.xml new file mode 100644 index 0000000..aaf7e3b --- /dev/null +++ b/simple-bookkeeping-master/app/src/main/res/drawable/main_recordbtn_bg.xml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/simple-bookkeeping-master/app/src/main/res/layout/activity_about.xml b/simple-bookkeeping-master/app/src/main/res/layout/activity_about.xml new file mode 100644 index 0000000..a54ccb5 --- /dev/null +++ b/simple-bookkeeping-master/app/src/main/res/layout/activity_about.xml @@ -0,0 +1,114 @@ + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/simple-bookkeeping-master/app/src/main/res/layout/activity_history.xml b/simple-bookkeeping-master/app/src/main/res/layout/activity_history.xml new file mode 100644 index 0000000..adbbc57 --- /dev/null +++ b/simple-bookkeeping-master/app/src/main/res/layout/activity_history.xml @@ -0,0 +1,57 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/simple-bookkeeping-master/app/src/main/res/layout/activity_main.xml b/simple-bookkeeping-master/app/src/main/res/layout/activity_main.xml new file mode 100644 index 0000000..ac762a1 --- /dev/null +++ b/simple-bookkeeping-master/app/src/main/res/layout/activity_main.xml @@ -0,0 +1,61 @@ + + + + + + + + + + + +