一:app介绍
理财小助手是一款利用Android studio软件实现的APP,可以录入每天的消费项目以及消费金额,同时也可以查找消费记录、统计消费总额。我用到的Android studio版本如下:
二、模块设计
下面是我实现的一些模块:
1:进入理财小助手app时会有一个登陆界面,包括邮箱和密码,邮箱和密码都有限制,如邮箱必须带有@符号,而密码必须不少于特定位数。
2:如果没有登录的邮箱或者密码时选择注册账号:
3:进入理财app先进入理财记录的首页:(此时还没有添加一条记录,首页显示为空)
4:添加一条消费记录,消费主体是lunch,消费金额是12,消费感受是good
5:点击左上方的箭头会默认自动保存此记录,如果点击右上方的X,就会删去这条记录,这样,在理财app的主页就会显示添加的消费记录:
6:也可以双击每一条记录,这样就会出现此记录的详细信息,比如我选择了第一条记录:
7:查看第五个步骤可以发现第五个步骤的图像右上方有三个符号,第一个+符号是添加一条记录,第二个符号是查找消息记录,第三个符号是可以统计金钱总额也可以显示出所有的消费记录:
第一个符号:
第二个符号查找记录:
第三符号有两个功能:
(1):统计功能:
比如统计今天记录:2022年1月15日
(2)显示记录的条数:如下,显示了添加的两条记录
三、代码设计
此代码设计分为两个部分,一个为前端的局面分布,一个为后端的java编写。如下:
1:java文件夹里面包含的是后端的代码,其中包含了database和wengxiaoyang.personalfinanceassistant。其中包括的类如下图所示:
2:res文件夹里面包括的是图片和前端代码,包括button或者布局等,是安卓必须掌握的基础知识点。
其中可可爱爱的蜡笔小新就来自与drawable,当然也可以换成其他的图片啦。在这里插入图片描述
layout里面存放的就是整个app的布局:
menu用来控制右上方的三个符号功能:
values用来控制button按钮:
注意:其他没有特别说明就是图片。
四、详细代码
1:先贴入java后端的代码
database中的ManageBaseHelp类
package database;
//数据库的继承类,并重写两种方法
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import database.ManageDbSchema.ManageTable;
import database.ManageDbSchema.ManageTable2;
//打开数据库
public class ManageBaseHelper extends SQLiteOpenHelper {
private static final int VERSION = 1;
private static final String DATABASE_NAME = "manageBase.db";
//在此构造方法中用super方法调用父类的构造方法。传入四个参数,上下文对象,数据库名称,null,数据库版本
public ManageBaseHelper(Context context) {
super(context, DATABASE_NAME, null, VERSION);
}
//重写子类的onCreate方法
@Override
public void onCreate(SQLiteDatabase db) {
// manage表,暴力名称,金钱,支付方式等
db.execSQL("create table " + ManageTable.NAME + "(" +
"_id integer primary key autoincrement, " +
ManageTable.Cols.UUID + ", " +
ManageTable.Cols.TITLE + ", " +
ManageTable.Cols.MONEY + ", " +
ManageTable.Cols.DATE + ", " +
ManageTable.Cols.PAYMETHOD + ", " +
ManageTable.Cols.REMARK + ")"
);
// 账号密码表
db.execSQL("create table " + ManageTable2.NAME2 + "(" +
"_id integer primary key autoincrement, " +
ManageTable2.Cols2.UUID + ", " +
ManageTable2.Cols2.ACCOUNT + ", " +
ManageTable2.Cols2.PASSWORD + ")"
);
}
//重写子类的onUpgrade方法
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
ManageCursorWrapper类
package database;
//将用户信息和消费消息写入数据库
import android.database.Cursor;
import android.database.CursorWrapper;
import java.util.Date;
import java.util.UUID;
import database.ManageDbSchema.ManageTable;
import database.ManageDbSchema.ManageTable2;
import wengxiaoyang.personalfinanceassistant.Login;
import wengxiaoyang.personalfinanceassistant.Manage;
//获得manage和login表格填写时的信息,并把他们放入数据库里面
public class ManageCursorWrapper extends CursorWrapper {
public ManageCursorWrapper(Cursor cursor) {
super(cursor);
}
public Manage getManage() {
// 获得manage信息
String uuidString = getString(getColumnIndex(ManageTable.Cols.UUID));//得到相对应的列索引,并赋值给string对象
String title = getString(getColumnIndex(ManageTable.Cols.TITLE));
String money = getString(getColumnIndex(ManageTable.Cols.MONEY));
Long date = getLong(getColumnIndex(ManageTable.Cols.DATE));
int payMethod = getInt(getColumnIndex(ManageTable.Cols.PAYMETHOD));
String remark = getString(getColumnIndex(ManageTable.Cols.REMARK));
// 将数据写入数据库
Manage manage = new Manage(UUID.fromString(uuidString));
manage.setTitle(title);
manage.setMoney(money);
manage.setDate(new Date(date));
manage.setPayMethod(payMethod);
manage.setRemark(remark);
return manage;
}
public Login getLogin() {
// 获得登录信息
String uuidString = getString(getColumnIndex(ManageTable2.Cols2.UUID));
String account = getString(getColumnIndex(ManageTable2.Cols2.ACCOUNT));
String password = getString(getColumnIndex(ManageTable2.Cols2.PASSWORD));
// 将登录信息存入数据库
Login login = new Login(UUID.fromString(uuidString));
login.setAccount(account);
login.setPassword(password);
return login;
}
}
ManageDbSchema类
package database;
public class ManageDbSchema {
// Manage表,定义常量
public static final class ManageTable {
public static final String NAME = "manages";
public static final class Cols {
public static final String UUID = "uuid";
public static final String TITLE = "title";
public static final String MONEY = "money";
public static final String DATE = "date";
public static final String PAYMETHOD = "paymethod";
public static final String REMARK = "remark";
}
}
// 账号密码表
public static final class ManageTable2 {
public static final String NAME2 = "login";
public static final class Cols2 {
public static final String UUID = "uuid";
public static final String ACCOUNT = "account";
public static final String PASSWORD = "password";
}
}
}
然后开始编写wengxiaoyang.personalfinanceassistant部分
DatePickerFragment类
package wengxiaoyang.personalfinanceassistant;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.DialogFragment;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.DatePicker;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
//记录花销的日期(年月日)
public class DatePickerFragment extends DialogFragment {
public static final String EXTRA_DATE = "wengxiaoyang.hziee.criminalintent.date";
private static final String ARG_DATE = "date";
private DatePicker mDatePicker;
public static DatePickerFragment newInstance(Date date) {
Bundle args = new Bundle();
args.putSerializable(ARG_DATE, date);
DatePickerFragment fragment = new DatePickerFragment();
fragment.setArguments(args);
return fragment;
}
@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
Date date = (Date) getArguments().getSerializable(ARG_DATE);
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
int year = calendar.get(Calendar.YEAR);
int month = calendar.get(Calendar.MONTH);
int day = calendar.get(Calendar.DAY_OF_MONTH);
View v = LayoutInflater.from(getActivity()).inflate(R.layout.dialog_date, null);
mDatePicker = v.findViewById(R.id.dialog_date_picker);
mDatePicker.init(year, month, day, null);
return new AlertDialog.Builder(getActivity()).setView(v)
.setTitle(R.string.date_picker_title)
.setPositiveButton(android.R.string.ok,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
int year = mDatePicker.getYear();
int month = mDatePicker.getMonth();
int day = mDatePicker.getDayOfMonth();
Date date = new GregorianCalendar(year, month, day).getTime();
sendResult(Activity.RESULT_OK, date);
}
})
.create();
}
private void sendResult(int resultCode, Date date) {
if (getTargetFragment() == null) {
return;
}
Intent intent = new Intent();
intent.putExtra(EXTRA_DATE, date);
getTargetFragment().onActivityResult(getTargetRequestCode(), resultCode,intent);
}
}
Login
package wengxiaoyang.personalfinanceassistant;
import java.util.UUID;
public class Login {
private UUID mId;
private String mAccount;
private String mPassword;
public Login() {
this(UUID.randomUUID());
}
public Login(UUID id) {
mId = id;
}
public UUID getId() {
return mId;
}
public String getAccount() {
return mAccount;
}
public void setAccount(String account) {
mAccount = account;
}
public String getPassword() {
return mPassword;
}
public void setPassword(String password) {
mPassword = password;
}
}
LoginActivity
package wengxiaoyang.personalfinanceassistant;
import android.content.Context;
import android.content.Intent;
import android.support.v4.app.Fragment;
public class LoginActivity extends SingleFragmentActivity {
@Override
protected Fragment createFragment() {
return new LoginFragment();
}
public static Intent newIntent(Context packageContext) {
Intent intent = new Intent(packageContext, LoginActivity.class);
return intent;
}
}
LoginFragment
package wengxiaoyang.personalfinanceassistant;
import android.support.v4.app.Fragment;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.annotation.TargetApi;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.inputmethod.EditorInfo;
import android.widget.AutoCompleteTextView;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
public class LoginFragment extends Fragment {
// UI
private AutoCompleteTextView mEmailView;
private EditText mPasswordView;
private Button mRegisterButton;
private View mProgressView;
private View mLoginFormView;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
//onCreateView是创建该fragment的视图,并返回给调用者。
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_login, container, false);
// 建立视图
mEmailView = (AutoCompleteTextView) view.findViewById(R.id.email);
mPasswordView = (EditText) view.findViewById(R.id.password);
mPasswordView.setOnEditorActionListener(new TextView.OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView textView, int id, KeyEvent keyEvent) {//输入密码之后监听哪个按钮的触发
if (id == EditorInfo.IME_ACTION_DONE || id == EditorInfo.IME_NULL) {//对应“完成”按钮和回车按钮,说明选择的是登录而不是注册
attemptLogin();
return true;
}
return false;
}
});
Button mEmailSignInButton = (Button) view.findViewById(R.id.email_sign_in_button);//登录按钮
mEmailSignInButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
attemptLogin();
}
});//设置监听,调用attemplogin方法判断邮箱和密码是否正确
mRegisterButton = view.findViewById(R.id.register_button);//注册按钮
mRegisterButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {//跳转到注册界面
Intent intent = new Intent(getActivity(), RegisterActivity.class);
startActivity(intent);
}
});
mLoginFormView = view.findViewById(R.id.login_form);
mProgressView = view.findViewById(R.id.login_progress);
return view;
}
private void attemptLogin() {
//判断邮箱和密码是否能和数据库里面的数据匹配
// 重置,不能记住密码
mEmailView.setError(null);
mPasswordView.setError(null);
// 获取登录的信息
String email = mEmailView.getText().toString();
String password = mPasswordView.getText().toString();
boolean cancel = false;
View focusView = null;
// 校验账号和密码
if (login(email, password)) {//调用下面的login方法进行邮箱密码比对,比对在loginlab中进行
mEmailView.setError(getString(R.string.error_error_acpw));
focusView = mEmailView;
cancel = true;
//比对不成功则提示报错
}
if (cancel) {
// 聚焦到错误发生地
focusView.requestFocus();
} else {
// 成功登录
showProgress(true);
// 跳转到ManageListActivity
Intent intent = ManageListActivity.newIntent(getActivity());
startActivity(intent);
}
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB_MR2)
// 动画
private void showProgress(final boolean show) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) {
int shortAnimTime = getResources().getInteger(android.R.integer.config_shortAnimTime);
mLoginFormView.setVisibility(show ? View.GONE : View.VISIBLE);
mLoginFormView.animate().setDuration(shortAnimTime).alpha(
show ? 0 : 1).setListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
mLoginFormView.setVisibility(show ? View.GONE : View.VISIBLE);
}
});
mProgressView.setVisibility(show ? View.VISIBLE : View.GONE);
mProgressView.animate().setDuration(shortAnimTime).alpha(
show ? 1 : 0).setListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
mProgressView.setVisibility(show ? View.VISIBLE : View.GONE);
}
});
} else {
// 若API不支持,则简单显示
mProgressView.setVisibility(show ? View.VISIBLE : View.GONE);
mLoginFormView.setVisibility(show ? View.GONE : View.VISIBLE);
}
}
public boolean login(String account, String password) {//验证此账号密码是否正确
Login login = LoginLab.get(getActivity()).getAccountAndPassword(account, password);
if (login != null) {
return false;
} else
return true;
}
}
LoginLab
package wengxiaoyang.personalfinanceassistant;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import database.ManageDbSchema.ManageTable2;
import database.ManageCursorWrapper;
import database.ManageBaseHelper;
public class LoginLab {
private static LoginLab sLoginLab;
private Context mContext;
private SQLiteDatabase mDatabase;
// 构造方法
private LoginLab(Context context) {
mContext = context.getApplicationContext();
mDatabase = new ManageBaseHelper(mContext).getWritableDatabase();//获得可读写操作对象
}
// 注册界面添加账号密码,创建contentvalues对象,调用mdatabase的insert方法将数据插入到数据库里面
public void addLogin(Login l) {
ContentValues values = getContentValues(l);
mDatabase.insert(ManageTable2.NAME2, null, values);
}
// 在数据库中找到Login表,也就是table2
private ManageCursorWrapper queryLogin(String whereClause, String[] whereArgs) {
Cursor cursor = mDatabase.query(
ManageTable2.NAME2,
null,// null selects all columns
whereClause,
whereArgs,
null,
null,
null
);
return new ManageCursorWrapper(cursor);
}
// 根据返回的参数cursor,在找到的login表里面再根据账号密码查找对应的用户
public Login getAccountAndPassword(String account, String password) {
ManageCursorWrapper cursor = queryLogin(
ManageTable2.Cols2.ACCOUNT + " = ? and " + ManageTable2.Cols2.PASSWORD+ " = ?",
new String[] { account, password }
);
try {
if (cursor.getCount() == 0) {//此用户不存在
return null;
}
cursor.moveToFirst();//从表的第一个用户开始查找
return cursor.getLogin();
} finally {
cursor.close();
}
}
// 获得Login数据,后一个参数的值赋给前面的一个参数,返回的login的值进行对比
private static ContentValues getContentValues(Login login) {
ContentValues values = new ContentValues();
values.put(ManageTable2.Cols2.UUID, login.getId().toString());
values.put(ManageTable2.Cols2.ACCOUNT, login.getAccount());
values.put(ManageTable2.Cols2.PASSWORD, login.getPassword());
return values;
}
// 根据上下文获取LoginLab
public static LoginLab get(Context context) {
if (sLoginLab == null) {
sLoginLab = new LoginLab(context);
}
return sLoginLab;
}
}
Manage
package wengxiaoyang.personalfinanceassistant;
import java.util.Date;
import java.util.UUID;
public class Manage {
private UUID mId;
private String mTitle;
private String mMoney;
private Date mDate;
private int mPayMethod;
private String mRemark;
public Manage() {
this(UUID.randomUUID());
}
public Manage(UUID id) {
mId = id;
mDate = new Date();
}
public UUID getId() {
return mId;
}
public String getTitle() {
return mTitle;
}
public void setTitle(String title) {
mTitle = title;
}
public String getMoney() {
return mMoney;
}
public void setMoney(String money) {
mMoney = money;
}
public Date getDate() {
return mDate;
}
public void setDate(Date date) {
mDate = date;
}
public int getPayMethod() {
return mPayMethod;
}
public void setPayMethod(int payMethod) {
mPayMethod = payMethod;
}
public String getRemark() {
return mRemark;
}
public void setRemark(String remark) {
mRemark = remark;
}
public String getPhotoFilename() {
return "IMG_" + getId().toString() + ".jpg";
}
}
ManageFragment
package wengxiaoyang.personalfinanceassistant;
import android.app.Activity;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.ShareCompat;
import android.support.v4.content.FileProvider;
import android.text.Editable;
import android.text.TextWatcher;
import android.text.format.DateFormat;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import java.io.File;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.UUID;
//manager的总布局
public class ManageFragment extends Fragment {
private static final String ARG_MANAGE_ID = "manage_id";
private static final String DIALOG_DATE = "dialogDate";
private static final String DIALOG_TIME = "dialogTime";
private static final String DIALOG_PHOTO = "dialogPhoto";
private static final int REQUEST_DATE = 0;
private static final int REQUEST_TIME = 0;
private static final int REQUEST_PHOTO = 3;
private Manage mManage;
private File mPhotoFile;
private EditText mTitleField;
private EditText mMoneyField;
private Button mDateButton;
private RadioGroup mRadioGroup;
private RadioButton mRadioButton_cash;
private RadioButton mRadioButton_card;
private EditText mRemarkField;
private Button mTimeButton;
private Button mReportButton;
private ImageButton mPhotoButton;
private ImageView mPhotoView;
//根据ID创建实例
public static ManageFragment newInstance(UUID manageId) {
Bundle args = new Bundle();
args.putSerializable(ARG_MANAGE_ID, manageId);
ManageFragment fragment = new ManageFragment();
fragment.setArguments(args);
return fragment;
}
// 保存部分数据
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
UUID manageId = (UUID) getArguments().getSerializable(ARG_MANAGE_ID);
mManage = ManageLab.get(getActivity()).getManage(manageId);
setHasOptionsMenu(true);
mPhotoFile = ManageLab.get(getActivity()).getPhotoFile(mManage);
}
@Override
public void onPause() {
super.onPause();
// 更新数据库数据
ManageLab.get(getActivity()).updateManage(mManage);
}
// UI
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_manage, container, false);
// 标题
mTitleField = v.findViewById(R.id.manage_title);
mTitleField.setText(mManage.getTitle());
mTitleField.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
mManage.setTitle(s.toString());
}
@Override
public void afterTextChanged(Editable s) {
}
});
// 金额
mMoneyField = v.findViewById(R.id.manage_money);
mMoneyField.setText(mManage.getMoney());
mMoneyField.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
mManage.setMoney(s.toString());
}
@Override
public void afterTextChanged(Editable s) {
}
});
// 日期
mDateButton = v.findViewById(R.id.manage_date);
Date date = mManage.getDate();
updateDate();
mDateButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
FragmentManager manager = getFragmentManager();
DatePickerFragment dialog = DatePickerFragment.newInstance(mManage.getDate());
dialog.setTargetFragment(ManageFragment.this, REQUEST_DATE);
dialog.show(manager, DIALOG_DATE);
}
});
// 时间
mTimeButton = v.findViewById(R.id.manage_time);
String dateString2 = (String) DateFormat.format("h:mm a", date);
updateTime(dateString2);
mTimeButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
FragmentManager manager = getFragmentManager();
TimePickerFragment dialog = TimePickerFragment.newInstance(mManage.getDate());
dialog.setTargetFragment(ManageFragment.this, REQUEST_TIME);
dialog.show(Objects.requireNonNull(manager), DIALOG_TIME); //第二个参数是tag
}
});
// 支付方式
mRadioGroup = v.findViewById(R.id.manage_pay_method);
mRadioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener(){
@Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
Manage manage = new Manage();
switch (checkedId) {
case R.id.manage_cash:
manage.setPayMethod(1);
break;
case R.id.manage_card:
manage.setPayMethod(2);
break;
default:
break;
}
}
});
System.out.println(mManage.getPayMethod());
mRadioButton_cash = v.findViewById(R.id.manage_cash);
mRadioButton_card = v.findViewById(R.id.manage_card);
int PayMethod = mManage.getPayMethod();
if (PayMethod == 1) {
mRadioButton_cash.setChecked(true);
} else if (PayMethod == 2) {
mRadioButton_card.setChecked(true);
}
// 备注
mRemarkField = v.findViewById(R.id.manage_remark);
mRemarkField.setText(mManage.getRemark());
mRemarkField.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
mManage.setRemark(s.toString());
}
@Override
public void afterTextChanged(Editable s) {
}
});
// 发送报告
mReportButton = v.findViewById(R.id.manage_report);
mReportButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
ShareCompat.IntentBuilder i = ShareCompat.IntentBuilder.from(getActivity());
i.setType("text/plain");
i.setText(getManageReport());
i.setSubject(getString(R.string.manage_report_subject));
i.createChooserIntent();
i.startChooser();
}
});
PackageManager packageManager = getActivity().getPackageManager();
// 拍照
mPhotoButton = v.findViewById(R.id.manage_camera);
final Intent captureImage = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
// 如果不能拍照就禁用按钮
boolean canTakePhoto = mPhotoFile != null &&
captureImage.resolveActivity(packageManager) != null;
mPhotoButton.setEnabled(canTakePhoto);
// 跳转到相机
mPhotoButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Uri uri = FileProvider.getUriForFile(getActivity(),
"wengxiaoyang.personalfinanceassistant.fileprovider", mPhotoFile);
captureImage.putExtra(MediaStore.EXTRA_OUTPUT, uri);
List<ResolveInfo> cameraActivities = getActivity().getPackageManager()
.queryIntentActivities(captureImage, PackageManager.MATCH_DEFAULT_ONLY);
for (ResolveInfo activity : cameraActivities) {
getActivity().grantUriPermission(activity.activityInfo.packageName, uri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
}
startActivityForResult(captureImage, REQUEST_PHOTO);
}
});
// 显示照片
mPhotoView = v.findViewById(R.id.manage_photo);
mPhotoView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (mPhotoFile == null || !mPhotoFile.exists()) {
mPhotoView.setImageDrawable(null);
} else {
FragmentManager manager = getFragmentManager();
PhotoDetailFragment dialog = PhotoDetailFragment.newInstance(mPhotoFile);
dialog.setTargetFragment(ManageFragment.this, REQUEST_PHOTO);
dialog.show(manager, DIALOG_PHOTO);
}
}
});
ViewTreeObserver mPhotoObserver = mPhotoView.getViewTreeObserver();
mPhotoObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
updatePhotoView(mPhotoView.getWidth(), mPhotoView.getHeight());
}
});
return v;
}
// 根据需求更新视图
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode != Activity.RESULT_OK) {
return;
}
if (requestCode == REQUEST_DATE) {
Date date = (Date) data.getSerializableExtra(DatePickerFragment.EXTRA_DATE);
mManage.setDate(date);
updateDate();
}
if (requestCode == REQUEST_TIME) {
Date date = mManage.getDate();
String dateString2 = (String) DateFormat.format("h:mm a", date);
updateTime(dateString2);
}
else if (requestCode == REQUEST_PHOTO) {
Uri uri = FileProvider.getUriForFile(getActivity(),
"wengxiaoyang.personalfinanceassistant.fileprovider", mPhotoFile);
getActivity().revokeUriPermission(uri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
updatePhotoView(mPhotoView.getWidth(), mPhotoView.getHeight());
}
}
// 创建菜单
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
inflater.inflate(R.menu.fragment_manage, menu);
}
// 根据选择响应
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.delete_manage:
ManageLab.get(getActivity()).removeManage(mManage);
getActivity().finish();
return true;
case android.R.id.home: //向上导航时保证子标题可见状态
getActivity().finish();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
private void updateDate() {
mDateButton.setText(mManage.getDate().toString());
}
private void updateTime(String s) {
mTimeButton.setText(s);
}
// 发送报告
private String getManageReport() {
String payString = null;
if (mManage.getPayMethod() == 1) {
payString = getString(R.string.manage_report_cash);
} else if (mManage.getPayMethod() == 2){
payString = getString(R.string.manage_report_card);
}
String dateString = (String) DateFormat.format("EEE, MMM dd, yyyy", mManage.getDate());
String report = getString(R.string.manage_report,
mManage.getTitle(), dateString, payString, mManage.getRemark());
return report;
}
// 更新照片视图
private void updatePhotoView(int width, int height) {
if (mPhotoFile == null || !mPhotoFile.exists()) {
mPhotoView.setImageDrawable(null);
} else {
Bitmap bitmap = PictureUtils.getScaledBitmap(mPhotoFile.getPath(), width, height);
mPhotoView.setImageBitmap(bitmap);
}
}
}
ManageLab
package wengxiaoyang.personalfinanceassistant;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import java.io.File;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import database.ManageDbSchema.ManageTable;
import database.ManageCursorWrapper;
import database.ManageBaseHelper;
//对每一条记录的操作:增加、删除、修改、查找
public class ManageLab {
private static ManageLab sManageLab;
private Context mContext;
private SQLiteDatabase mDatabase;
private ManageLab(Context context) {
mContext = context.getApplicationContext();
mDatabase = new ManageBaseHelper(mContext).getWritableDatabase();
}
// 添加记录
public void addManage(Manage m) {
ContentValues values = getContentValues(m);
mDatabase.insert(ManageTable.NAME, null, values);
}
// 删除记录
public void removeManage(Manage c) {
String uuidString = c.getId().toString();
mDatabase.delete(ManageTable.NAME, ManageTable.Cols.UUID + " = ?", new String[]{uuidString});
}
// 得到照片
public File getPhotoFile(Manage manage) {
File filesDir = mContext.getFilesDir();
return new File(filesDir, manage.getPhotoFilename());
}
// 更新记录
public void updateManage(Manage manage) {
String uuidString = manage.getId().toString();
ContentValues values = getContentValues(manage);
mDatabase.update(ManageTable.NAME, values, ManageTable.Cols.UUID + " = ?", new String[]{uuidString});
}
// 查找记录
private ManageCursorWrapper queryManages(String whereClause, String[] whereArgs) {
Cursor cursor = mDatabase.query(
ManageTable.NAME,
null,// null selects all columns
whereClause,
whereArgs,
null,
null,
null
);
return new ManageCursorWrapper(cursor);
}
// 得到Manages集合
public List<Manage> getManages() {
List<Manage> manages = new ArrayList<>();
ManageCursorWrapper cursor = queryManages(null,null);
try {
cursor.moveToFirst();
while (!cursor.isAfterLast()) {
manages.add(cursor.getManage());
cursor.moveToNext();
}
}finally {
cursor.close();
}
return manages;
}
// 根据ID获取Manage
public Manage getManage(UUID id) {
ManageCursorWrapper cursor = queryManages(
ManageTable.Cols.UUID + " = ?",
new String[] { id.toString() }
);
try {
if (cursor.getCount() == 0) {
return null;
}
cursor.moveToFirst();
return cursor.getManage();
} finally {
cursor.close();
}
}
// 获得数据库数据
private static ContentValues getContentValues(Manage manage) {
ContentValues values = new ContentValues();
values.put(ManageTable.Cols.UUID, manage.getId().toString());
values.put(ManageTable.Cols.TITLE, manage.getTitle());
values.put(ManageTable.Cols.MONEY, manage.getMoney());
values.put(ManageTable.Cols.DATE, manage.getDate().getTime());
values.put(ManageTable.Cols.PAYMETHOD, manage.getPayMethod());
values.put(ManageTable.Cols.REMARK, manage.getRemark());
return values;
}
public static ManageLab get(Context context) {
if (sManageLab == null) {
sManageLab = new ManageLab(context);
}
return sManageLab;
}
}
ManageListActivity
package wengxiaoyang.personalfinanceassistant;
import android.content.Context;
import android.content.Intent;
import android.support.v4.app.Fragment;
public class ManageListActivity extends SingleFragmentActivity {
@Override
protected Fragment createFragment() {
return new ManageListFragment();
}
public static Intent newIntent(Context packageContext) {
Intent intent = new Intent(packageContext, ManageListActivity.class);
return intent;
}
}
ManageFragment
package wengxiaoyang.personalfinanceassistant;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.Fragment;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
//显示消费记录
public class ManageListFragment extends Fragment {
private RecyclerView mManageRecyclerView;
private ManageAdapter mAdapter;
private static int mManageIndex;
private boolean mSubtitleVisible;
private TextView mNullManageListTextView;
private Button mAddManageButton;
private static final String SAVED_SUBTITLE_VISIBLE = "subtitle";
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
// UI
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_manage_list, container, false);
mManageRecyclerView = view.findViewById(R.id.manage_recycler_view);
mManageRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
mNullManageListTextView = view.findViewById(R.id.null_manage_list);
mAddManageButton = view.findViewById(R.id.add_manage);
mAddManageButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Manage manage = new Manage();
ManageLab.get(getActivity()).addManage(manage);//下面的两个按钮
Intent intent = ManagePagerActivity.newIntent(getActivity(), manage.getId());
startActivity(intent);
}
});
// 保持记录条数可见
if (savedInstanceState != null) {
mSubtitleVisible = savedInstanceState.getBoolean(SAVED_SUBTITLE_VISIBLE);
}
updateUI();
return view;
}
@Override
public void onResume() {
super.onResume();
updateUI();
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putBoolean(SAVED_SUBTITLE_VISIBLE, mSubtitleVisible);
}
// 创建菜单
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
inflater.inflate(R.menu.fragment_manage_list, menu);
MenuItem subtitleItem = menu.findItem(R.id.show_subtitle);
if (mSubtitleVisible) {
subtitleItem.setTitle(R.string.hide_subtitle);
} else {
subtitleItem.setTitle(R.string.show_subtitle);
}
}
// 响应菜单点击
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.new_manage: // 创建新记录
Manage manage = new Manage();
ManageLab.get(getActivity()).addManage(manage);
Intent intent = ManagePagerActivity.newIntent(getActivity(), manage.getId());
startActivity(intent);
return true;
case R.id.search_manage: //搜索
intent = SearchActivity.newIntent(getActivity());
startActivity(intent);
return true;
case R.id.statistic_manage: //统计
intent = new Intent(getActivity(), StatisticActivity.class);
startActivity(intent);
return true;
case R.id.show_subtitle: //显示记录条数
mSubtitleVisible = !mSubtitleVisible;
getActivity().invalidateOptionsMenu();
updateSubtitle();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
// 更新记录条数
private void updateSubtitle() {
ManageLab manageLab = ManageLab.get(getActivity());
int manageCount = manageLab.getManages().size();
String subtitle = getString(R.string.subtitle_format, manageCount);
if (!mSubtitleVisible) {
subtitle = null;
}
AppCompatActivity activity = (AppCompatActivity) getActivity();
activity.getSupportActionBar().setSubtitle(subtitle);
}
// 更新UI界面
private void updateUI() {
ManageLab manageLab = ManageLab.get(getActivity());
List<Manage> manages = manageLab.getManages();
if (mAdapter == null) {
mAdapter = new ManageAdapter(manages);
mManageRecyclerView.setAdapter(mAdapter);
} else {
//重绘当前可见区域
//mAdapter.notifyDataSetChanged();
//部分重绘
mAdapter.setManages(manages);
mAdapter.notifyItemChanged(mManageIndex);
}
if (manages.size() != 0) {
mNullManageListTextView.setVisibility(View.INVISIBLE);
mAddManageButton.setVisibility(View.INVISIBLE);
} else {
mNullManageListTextView.setVisibility(View.VISIBLE);
mAddManageButton.setVisibility(View.VISIBLE);
}
updateSubtitle();
}
private class ManageHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
private TextView mTitleTextView;
private TextView mDateTextView;
private Manage mManage;
public ManageHolder(LayoutInflater inflater, ViewGroup parent) {
super(inflater.inflate(R.layout.list_item_manage, parent, false));
itemView.setOnClickListener(this);
mTitleTextView = itemView.findViewById(R.id.manage_title);
mDateTextView = itemView.findViewById(R.id.manage_date);
}
public void bind(Manage manage) {
mManage = manage;
mTitleTextView.setText(mManage.getTitle());
Date date = manage.getDate();
mDateTextView.setText(date.toString());
}
@Override
public void onClick(View view) {
Intent intent = ManagePagerActivity.newIntent(getActivity(), mManage.getId());
mManageIndex = getAdapterPosition(); //返回数据在adapter中的位置
startActivity(intent);
}
}
private class ManageAdapter extends RecyclerView.Adapter {
private List<Manage> mManages;
public ManageAdapter(List<Manage> manages) {
mManages = manages;
}
//视图类别功能
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
//先建立LayoutInflater
LayoutInflater layoutInflater = LayoutInflater.from(getActivity());
return new ManageHolder(layoutInflater, parent);
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
Manage manage = mManages.get(position);
((ManageHolder)holder).bind(manage);
}
@Override
public int getItemCount() {
return mManages.size();
}
public void setManages(List<Manage> manages) {
mManages = manages;
}
}
}
怕你们还没有弄清楚,现在将工程目录再进行截图:
怕你们还没有弄清楚,现在将工程目录再进行截图: