android simpleBill 开发记录1 Addrecord页面
·
我开发了一个可以自动记账的app 取名为simpleBill
记录一下开发过程中遇到的一些知识点
在开发的过程中发现是java加上ui的xml界面,所以很快就上手了
首先是Addrecord页面
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".ui.addRecord.AddRecordActivity">
<!--<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"-->
<!-- android:layout_width="match_parent"-->
<!-- android:layout_height="match_parent">-->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="添加新账单"
android:textSize="40dp"
android:layout_gravity="center"
/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="50dp"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="金额:"
android:textSize="20dp"
android:layout_marginRight="20dp"
android:layout_marginTop="3dp"
/>
<EditText
android:id="@+id/count"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:hint="请输入金额"
android:inputType="numberDecimal"/>
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="50dp"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="20dp"
android:text="描述:"
android:textSize="20dp" />
<EditText
android:id="@+id/description"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:hint="请输入描述"/>
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="50dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="20dp"
android:text="类别:"
android:textSize="20dp" />
<EditText
android:id="@+id/leibie"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:hint="请输入描述" />
</LinearLayout>
<LinearLayout
android:layout_width="278dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="50dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="3dp"
android:layout_marginRight="20dp"
android:text="来源:"
android:textSize="20dp" />
<Spinner
android:id="@+id/source"
style="@style/Base.Widget.AppCompat.Spinner.Underlined"
android:layout_width="143dp"
android:layout_height="50dp"
android:layout_weight="1"/>
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="50dp"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="时间:"
android:textSize="20dp"
android:layout_marginRight="20dp"
/>
<EditText
android:id="@+id/createDate"
android:layout_width="200dp"
android:layout_height="wrap_content"
/>
</LinearLayout>
<LinearLayout
android:layout_width="278dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="50dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="3dp"
android:layout_marginRight="20dp"
android:text="收支:"
android:textSize="20dp" />
<Spinner
android:id="@+id/shouzhi"
style="@style/Base.Widget.AppCompat.Spinner.Underlined"
android:layout_width="143dp"
android:layout_height="50dp"
android:layout_weight="1"
android:entries="@array/spinner_shouzhi" />
</LinearLayout>
<Button
android:id="@+id/add_record_btn"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="40dp"
android:text="添加"
android:textSize="20dp" />
<Button
android:id="@+id/goback"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="40dp"
android:text="主页"
android:textSize="20dp" />
<Button
android:id="@+id/leibie_manage"
android:layout_width="215dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="40dp"
android:text="类别管理"
android:textSize="20dp" />
</LinearLayout>
</ScrollView>
首先设计了记录的字段,我设计的账单记录字段包括金额,描述,类别,来源,日期,收支。
- 金额可以手动填写 或者无障碍服务识别特定页面自动填写。
- 描述可以手动填写 或者无障碍服务识别特定页面自动填写。
- 类别需要选择,此处设计了弹窗进行选择。
首先我在程序内部存储生成了一个leibie.txt
File dir = AddRecordActivity.this.getFilesDir();
// 创建文件对象
File file = new File(dir, "leibie.txt");
// 如果文件不存在,则创建它
if (!file.exists()) {
try {
file.createNewFile();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
ArrayList<String> leibieArraylist = readFile("leibie.txt",AddRecordActivity.this);
if (leibieArraylist.size() <= 1){
writeToFile("添加...","leibie.txt",AddRecordActivity.this,false);
}
然后在点击类别时用popupwindow进行弹窗(收支用spinner,感觉spinner效果不太好,所以用了popupwindow)
leibieEdit.setOnClickListener(this);
leibieEdit.setOnFocusChangeListener(new View.OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
if (hasFocus) {
try {
showPopupLeibieList(v,leibieEdit,leibieListView);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
});
弹出pupupwindow的代码
private void showPopupLeibieList(View anchorView, EditText editText, ListView listView) throws IOException {
// 初始化ListView和适配器(这里使用ArrayAdapter作为示例)
leibieItems = readFile("leibie.txt",AddRecordActivity.this);
listView = new ListView(this);
ArrayAdapter<String> adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, leibieItems);//弹窗固定写法 具体原理没研究
listView.setAdapter(adapter);
// 设置ListView的高度(可选,根据你的需要)
int height = getResources().getDimensionPixelSize(R.dimen.list_popup_height);
ListView.LayoutParams params = new ListView.LayoutParams(ListView.LayoutParams.MATCH_PARENT, height);
listView.setLayoutParams(params);
// 初始化PopupWindow,并设置宽高和焦点等属性
popupWindow = new PopupWindow(listView, editText.getWidth() , height, true);
Drawable drawable = getResources().getDrawable(R.drawable.popupwindow_border);
popupWindow.setBackgroundDrawable(drawable);
popupWindow.showAsDropDown(anchorView);//在锚点的正下方显示
// 设置ListView的点击监听器
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
// 处理点击事件,例如更新输入框的值并关闭PopupWindow
if (position == leibieItems.size() -1 ){
showPopupAddLeibie();
popupWindow.dismiss();
}else{
editText.setText(leibieItems.get(position));
}
popupWindow.dismiss();
}
});
// 设置PopupWindow的触摸监听器(可选)
}
- 来源很简单,用spinner
ArrayList<String> laiyuanNames = (ArrayList<String>) accountHelper.getAllNames();
ArrayAdapter<String> adapter = new ArrayAdapter<>(this, android.R.layout.simple_spinner_item, laiyuanNames);
// 将适配器设置给Spinner
laiyuan.setAdapter(adapter);
- 时间用了日期选择器
private EditText dateEdit;
SimpleDateFormat customFormat = new SimpleDateFormat("yyyy-MM-dd");
String formattedDate = customFormat.format(new Date());
dateEdit.setText(formattedDate);
dateEdit.setOnFocusChangeListener(new View.OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
if (hasFocus) {
CommonUtils.showDatePickDlg(AddRecordActivity.this,dateEdit,dateEdit.getText().toString());
}
}
});
日期选择器弹窗是多用的,因此提取出来至CommonUtils类
public static void showDatePickDlg(Context context, EditText editText, String dateStr) {
Calendar calendar = Calendar.getInstance();
Date date = null;
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
try {
date = sdf.parse(dateStr);
}catch (Exception e){}
if (date!= null){
calendar.setTime(date);
}
DatePickerDialog datePickerDialog = new DatePickerDialog(context, new DatePickerDialog.OnDateSetListener() {
@Override
public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
editText.setText(year + "-" + String.format("%02d", monthOfYear+1) + "-" + String.format("%02d", dayOfMonth));//最终那个edittext里显示的格式 可在这里调整,monthOfYear从0开始
}
}, calendar.get(Calendar.YEAR),calendar.get(Calendar.MONTH),calendar.get(Calendar.DAY_OF_MONTH));
datePickerDialog.show();
}
- 来源用了spiiner
spinner的数据来源区数据库中读取所有accountName
ArrayList<String> laiyuanNames = (ArrayList<String>) accountHelper.getAllNames();
ArrayAdapter<String> adapter = new ArrayAdapter<>(this, android.R.layout.simple_spinner_item, laiyuanNames);
// 将适配器设置给Spinner
laiyuan.setAdapter(adapter);
- 收支
收支也用了spinner,选项只有“收入”“支出”,因此直接在xml中定义
<Spinner
android:id="@+id/shouzhi"
style="@style/Base.Widget.AppCompat.Spinner.Underlined"
android:layout_width="143dp"
android:layout_height="50dp"
android:layout_weight="1"
android:entries="@array/spinner_shouzhi" />
在values包中创建一个xml,名称随便 添加如下代码。
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="spinner_shouzhi">
<item>支出</item>
<item>收入</item>
</string-array>
</resources>
- 添加按钮
private void addRecord(){
//获取所有的字符串
String adesc = miaoshu.getText().toString();
adesc = validateDesc(adesc);//校验是否有英文逗号,便于后期导出数据的处理。如果有英文逗号换成中文逗号。因为导出数据功能使用了英文逗号祚分隔符。
String acount = jine.getText().toString();
String adate = dateEdit.getText().toString();
String ashouzhi = shouzhi.getSelectedItem().toString();
String asource = laiyuan.getSelectedItem().toString();
String aleibie = leibieEdit.getText().toString();
if(acount.equals("")){
Toast.makeText(this, "金额不能为空!", Toast.LENGTH_SHORT).show();
} else if (adesc.equals("")) {
Toast.makeText(this, "描述不能为空!", Toast.LENGTH_SHORT).show();
} else if (adate.equals("")) {
Toast.makeText(this, "日期不能为空!", Toast.LENGTH_SHORT).show();
}else if(ashouzhi.equals("")){
Toast.makeText(this, "收支不能为空!", Toast.LENGTH_SHORT).show();
}
else if(asource.equals("")){
Toast.makeText(this, "来源不能为空!", Toast.LENGTH_SHORT).show();
}
else if(aleibie.equals("")){
Toast.makeText(this, "类别不能为空!", Toast.LENGTH_SHORT).show();
}
else{
if (ashouzhi.equals("支出")){
acount = '-' + acount;
}
BillRecord record = new BillRecord();
record.setSource(asource);
record.setCount(acount);
record.setDescription(adesc);
record.setCreateDate(adate);
record.setShouzhi(ashouzhi);
record.setLeibie(aleibie);
long res = billRecordHelper.addRecord(record);
addButton.setEnabled(false);
addButton.setTextColor(0xFFD0EFC6);
if(res!=-1){
Toast.makeText(this, "添加成功", Toast.LENGTH_SHORT).show();
//如果是微信或支付宝跳转过来的 区分手动添加记录的情况
if (isfrom("accessibility.alipay") || isfrom("accessibility.wechat")){
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder
.setMessage("是否留在此地?")
.setPositiveButton("确定", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
go(AddRecordActivity.this, MainActivity.class);//点击确定后去到app的主页。
Intent intent = new Intent("REFRESH_ACTIVITY_ACTION");//发送这个action让主页刷新,否则主页不刷新。
sendBroadcast(intent);
finish();
}
}
)
.setNegativeButton("返回", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Intent intent1 = new Intent("REFRESH_ACTIVITY_ACTION");
sendBroadcast(intent1);
// 处理确定按钮点击事件
try{
Intent intent = new Intent();
if (isfrom("accessibility.wechat")){
intent = new Intent(Intent.ACTION_VIEW, Uri.parse("weixin://"));
}else if(isfrom("accessibility.alipay")){
intent = new Intent(Intent.ACTION_VIEW, Uri.parse("alipayqr://"));
}
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
finish();
}catch (Exception e){
e.printStackTrace();
}
}
});
AlertDialog dialog = builder.create();
dialog.show();
}else {
Intent intent = new Intent("REFRESH_ACTIVITY_ACTION");
sendBroadcast(intent);
intent = new Intent(AddRecordActivity.this,MainActivity.class);
startActivity(intent);
finish();
}
}else{
Toast.makeText(this, "添加失败!", Toast.LENGTH_SHORT).show();
}
}
}
- 回到主页按钮
没啥好说的,跳转至主页
Intent intent = new Intent(this,MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
startActivity(intent);
- 类被管理按钮
跳转至类别管理页面
Intent intent = new Intent(AddRecordActivity.this,LeibieManageActivity.class);
intent.putExtra("FROM_ACTIVITY", "AddRecordActivity");
startActivity(intent);
以上是手动添加记录的代码,如果是使用无障碍服务从微信/支付宝跳转过来的就直接读取数据
判断函数其实就是判断字符串相等
private boolean isfrom(String action){
if (formAction.equals(action)){
return true;
}
return false;
}
if (isfrom("accessibility.wechat") || isfrom("accessibility.alipay")){
//直接获取无障碍服务的Intent带过来的数据 StringExtra
String tempMiaoshu = getIntent().getStringExtra("miaoshu");
String tempJine = getIntent().getStringExtra("jine");
tempJine = tempJine.replace(",","");
String laiyuanStr = getIntent().getStringExtra("laiyuan");
String shijian = getIntent().getStringExtra("shijian");
String shouzhiStr = getIntent().getStringExtra("shouzhi");
double jineNum = Double.valueOf(tempJine);
jine.setText(String.valueOf(Math.abs(jineNum)));
miaoshu.setText(tempMiaoshu);
ArrayList<String> shouzhiItemList = new ArrayList<>();
shouzhiItemList.add("收入");
shouzhiItemList.add("支出");
ArrayAdapter<String> adapter1 = new ArrayAdapter<>(this, android.R.layout.simple_spinner_item, shouzhiItemList);
shouzhi.setAdapter(adapter1);
shouzhi.setSelection(shouzhiItemList.indexOf(shouzhiStr));
dateEdit.setText(shijian);
dateEdit.setOnFocusChangeListener(new View.OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
if (hasFocus) {
CommonUtils.showDatePickDlg(AddRecordActivity.this,dateEdit,dateEdit.getText().toString());
}
}
});
File dir = AddRecordActivity.this.getFilesDir();
// 创建文件对象
File file = new File(dir, "leibie.txt");
// 如果文件不存在,则创建它
if (!file.exists()) {
try {
file.createNewFile();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
ArrayList<String> leibieArraylist = readFile("leibie.txt",AddRecordActivity.this);
if (leibieArraylist.size() <= 1){
writeToFile("添加...","leibie.txt",AddRecordActivity.this,false);
}
leibieEdit.setOnClickListener(this);
leibieEdit.setOnFocusChangeListener(new View.OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
if (hasFocus) {
try {
showPopupLeibieList(v,leibieEdit,leibieListView);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
});
//来源
ArrayList<String> laiyuanNames = (ArrayList<String>) accountHelper.getAllNames();
if (laiyuanStr!=null && !laiyuanNames.contains(laiyuanStr)){
showAlertAddAccount(laiyuanStr);
}else {
laiyuanNames =(ArrayList<String>) accountHelper.getAllNames();
ArrayAdapter<String> adapter = new ArrayAdapter<>(this, android.R.layout.simple_spinner_item, laiyuanNames);
// 设置下拉列表的显示样式
// adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
// 将适配器设置给Spinner
laiyuan.setAdapter(adapter);
laiyuan.setSelection(laiyuanNames.indexOf(laiyuanStr));
}
}
今天先写到这里 后面慢慢更新
更多推荐



所有评论(0)