献给热爱编程的朋友,安装包下载地址(提取码:qswm): https://pan.baidu.com/s/1crmrR1YC2EbnfwPz8Xbfcw
源代码下载地址:https://gitee.com/landzy/Accounting-offline.git
前言
本人自学编程,从优快云学习了很多编程知识,第一次整理、记录、分享学习编程的内容,希望自己能持之以恒,通过这种形式学习和提升自己,同时回馈优快云,给热爱编程的朋友提带来帮助。如有技术错误,欢迎大神指正。
一、软件介绍
本应用使用安卓studio,java语言开发,功能极简,仅包括显示余额、收入、支出、收支明细和记录收入与支出。
主页面效果图:
记账页面效果图:
二、源代码
4个java类:Account.java(Javabeen,用于封装各项属性),AccountDBHelper.java(用于处理SQLite数据库的增删改查),MainActivity.java(主界面的功能实现),AddAccount.java(记账界面的功能实现)。
4个layout文件:activity_main.xml(主界面布局文件),activity_add_account.xml(记账界面布局文件),date_dialog.xml(选择日期布局文件),list_layout_account.xml(账单记录显示布局文件)。
3个drawable文件:btn_normal.xml(按钮常规样式),btn_selector.xml(按钮选择样式),text_view_shape.xml(编辑框边框样式)。
1.java类
1.1 Account.java(Javabeen,用于封装各项属性)
package com.zyjcy.accounting;
public class Account {
private int id;
private String date;
private String item;
private String type;
private Double amount;
private String remark;
public Account() {
}
public Account(int id, String date, String item, String type, Double amount, String remark) {
this.id = id;
this.date = date;
this.item = item;
this.type = type;
this.amount = amount;
this.remark = remark;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getDate() {
return date;
}
public void setDate(String date) {
this.date = date;
}
public String getItem() {
return item;
}
public void setItem(String item) {
this.item = item;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public Double getAmount() {
return amount;
}
public void setAmount(Double amount) {
this.amount = amount;
}
public String getRemark() {
return remark;
}
public void setRemark(String remark) {
this.remark = remark;
}
public String toString() {
return "Account{id = " + id + ", date = " + date + ", item = " + item + ", type = " + type + ", amount = " + amount + ", remark = " + remark + "}";
}
}
1.2 AccountDBHelper.java(用于处理SQLite数据库的增删查)
package com.zyjcy.accounting;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import java.util.ArrayList;
import java.util.List;
public class AccountDBHelper extends SQLiteOpenHelper {
private static final String DB_NAME = "account.db";
private static final String TABLE_NAME = "table_account";
private static final int DB_VERSION = 1;
private static AccountDBHelper mHelper = null;
private SQLiteDatabase mRDB = null;
private SQLiteDatabase mWDB = null;
private Cursor cursor;
private List<Account> list = new ArrayList<>();
private AccountDBHelper(Context context) {
super(context, DB_NAME, null, DB_VERSION);
}
//利用单例模式获取数据库帮助器的唯一实例
public static AccountDBHelper getInstance(Context context) {
if (mHelper == null) {
mHelper = new AccountDBHelper(context);
}
return mHelper;
}
//打开数据库的读连接
public SQLiteDatabase openReadLink() {
if (mRDB == null || !mRDB.isOpen()) {
mRDB = mHelper.getReadableDatabase();
}
return mRDB;
}
//打开数据库的读连接
public SQLiteDatabase openWriteLink() {
if (mWDB == null || !mWDB.isOpen()) {
mWDB = mHelper.getWritableDatabase();
}
return mWDB;
}
//关闭数据库连接
public void closeLink() {
if (mRDB != null && mRDB.isOpen()) {
mRDB.close();
mRDB = null;
}
if (mWDB != null && mWDB.isOpen()) {
mWDB.close();
mWDB = null;
}
}
//创建数据库表
@Override
public void onCreate(SQLiteDatabase db) {
String sql = "CREATE TABLE IF NOT EXISTS " + TABLE_NAME + " (" +
"id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL," +
"date VARCHAR," +
"item VARCHAR,"+
"type VARCHAR,"+
"amount DOUBLE,"+
"remark VARCHAR);";
db.execSQL(sql);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
//增加一条数据
public long insert(Account account) {
ContentValues values = new ContentValues();
//此处可以不用插入id,id让数据库自动生成
values.put("date", account.getDate());
values.put("item", account.getItem());
values.put("type", account.getType());
values.put("amount", account.getAmount());
values.put("remark", account.getRemark());
return mWDB.insert(TABLE_NAME, null, values);
}
//删除一条数据
public long deleteById(int id){
return mWDB.delete(TABLE_NAME,"id=?",new String[]{String.valueOf(id)});
}
//查询所有数据
public List<Account> queryAll() {
list.clear();
cursor = mRDB.query(TABLE_NAME, null, null, null,
null, null, "id desc");//asc是从小到大排序
while (cursor.moveToNext()) {
Account account = new Account();
account.setId(cursor.getInt(0));
account.setDate(cursor.getString(1));
account.setItem(cursor.getString(2));
account.setType(cursor.getString(3));
account.setAmount(cursor.getDouble(4));
account.setRemark(cursor.getString(5));
list.add(account);
}
return list;
}
//通过收支类型type查询”收入“”支出“的情况
public double querySUM(String type) {
//通过type筛选数据,然后对金额求和,然后将数据返回
cursor = mRDB.query(TABLE_NAME, new String[] {"SUM(amount)"}, "type=?",
new String[]{type}, null, null,null );
double d = 0.00;
while (cursor.moveToNext()) {
d=cursor.getDouble(0);
}
return d;
}
//获得数据库的元数据(列名称)
public String[] getColumnNames(){
return cursor.getColumnNames();
}
}
1.3 MainActivity.java(主界面的功能实现)
package com.zyjcy.accounting;
import androidx.appcompat.app.AppCompatActivity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
TextView balanceTV;
TextView incomeTV;
TextView expenditureTV;
Button AddAccountBT;
private AccountDBHelper mHelper;
List<Map<String, Object>> listMap = new ArrayList<Map<String, Object>>();
List<Account> list;
//从数据库中取出来的列名称放入该数组
private String[] columnNames;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//初始化控件
initView();
}
//初始化控件
public void initView() {
balanceTV = findViewById(R.id.balance);
incomeTV = findViewById(R.id.income);
expenditureTV = findViewById(R.id.expenditure);
AddAccountBT = findViewById(R.id.addAccount);
AddAccountBT.setOnClickListener(this);
}
//按钮监听
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.addAccount: {
//跳转到记账页面
Intent intent = new Intent(MainActivity.this, AddAccount.class);
startActivity(intent);
}
break;
}
}
//并将查询数据展示在listview中
private void refresh() {
//查询数据库中所有数据
list = mHelper.queryAll();
//拿到元数据(列名称)的数组
columnNames = mHelper.getColumnNames();
//刷新账户数据
double incomeMoney = mHelper.querySUM("收入");
double takeOutMoney = mHelper.querySUM("支出");
balanceTV.setText(incomeMoney - takeOutMoney + "");
incomeTV.setText(incomeMoney + "");
expenditureTV.setText(takeOutMoney + "");
//先清空历史数据
listMap.clear();
//遍历集合,将每一个Account对象中的数据取出来,以key-value的形式放入map集合,然后将每一个account对应的map放入listMap中
for (int i = 0; i < list.size(); i++) {
//LinkedHashMap装入和取出的顺序不会变
Map<String, Object> map = new LinkedHashMap<String, Object>();
//columnNames[]数组代表的是从数据库中取出来的列名称
map.put(columnNames[0], list.get(i).getId());
map.put(columnNames[1], list.get(i).getDate());
map.put(columnNames[2], list.get(i).getItem());
map.put(columnNames[3], list.get(i).getType());
map.put(columnNames[4], list.get(i).getAmount());
map.put(columnNames[5], list.get(i).getRemark());
listMap.add(map);
}
showResult(listMap);
}
//显示查询数据的列表,并对列表设置监听事件
private void showResult(List<Map<String, Object>> listMap) {
//用适配器将list里面的每一个map与listview形成绑定关系,并将其展示。
//此处的columnNames[]对应的是列名称, 装入new String[]中是将listMap其对应的名字取出来放在listview中
SimpleAdapter simpleAdapter = new SimpleAdapter(this, listMap, R.layout.list_layout_account,
new String[]{columnNames[1], columnNames[2], columnNames[3], columnNames[4], columnNames[5]},
new int[]{R.id.date, R.id.item, R.id.type, R.id.amount, R.id.remark});
ListView listView = (ListView) findViewById(R.id.lv_information);
listView.setAdapter(simpleAdapter);
//给listView设置点击监听
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
//拿到被点击位置对应的map
Map<String, Object> map = (Map<String, Object>) parent.getItemAtPosition(position);
//拿到这组数据的id
int id1 = (int) map.get("id");
//创建弹窗方法对象
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
//用对象调用方法,设置弹窗信息(先拿到listMap里面被点击那个对象)
builder.setMessage("删除后不能恢复,您确定删除本条记录吗?\n\n")
//设置弹窗中文字按钮的点击监听事件
.setPositiveButton("狠心删除", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
//通过id删除该组数据
mHelper.deleteById(id1);
//刷新显示界面的数据和列表数据
refresh();
}
})
.setNegativeButton("算了算了", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
});
//创建弹窗并展示
builder.create().show();
}
});
}
//activity启动时的操作
@Override
protected void onStart() {
super.onStart();
//获取数据库帮助器的实例
mHelper = AccountDBHelper.getInstance(this);
//打开数据库读写连接
mHelper.openWriteLink();
mHelper.openReadLink();
//查询数据库中所有数据,并刷新列表和余额数据。
refresh();
}
//activity关闭时的操作
@Override
protected void onDestroy() {
super.onDestroy();
//关闭数据库连接
mHelper.closeLink();
}
}
1.4 AddAccount.java(记账界面的功能实现)
package com.zyjcy.accounting;
import androidx.appcompat.app.AppCompatActivity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.text.InputType;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;
import android.widget.DatePicker;
import android.widget.EditText;
import android.widget.RadioGroup;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
public class AddAccount extends AppCompatActivity implements View.OnClickListener,
RadioGroup.OnCheckedChangeListener, View.OnTouchListener {
EditText amountET;
EditText itemET;
EditText dateET;
EditText remarkET;
Button submitBT;
Button cancelBT;
RadioGroup typeRG;
Account account = new Account();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_add_account);
//初始化控件
initView();
}
//初始化控件
private void initView() {
amountET = findViewById(R.id.amount);
itemET = findViewById(R.id.item);
dateET = findViewById(R.id.dateET);
dateET.setText(getTodayYmd());
dateET.setOnTouchListener(this);
remarkET = findViewById(R.id.remark);
submitBT = findViewById(R.id.submit);
submitBT.setOnClickListener(this);
cancelBT = findViewById(R.id.cancel);
cancelBT.setOnClickListener(this);
typeRG = findViewById(R.id.type);
typeRG.setOnCheckedChangeListener(this);
//设置RadioGroup默认值为存钱
typeRG.check(R.id.income);
}
//获取今天的日期
public static String getTodayYmd() {
Date now = new Date();
Calendar calendar = Calendar.getInstance();
calendar.setTime(now);
// 将时分秒,毫秒域清零
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
return formatter.format(calendar.getTime());
}
//选择日期组件
@Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
View view = View.inflate(this, R.layout.date_dialog, null);
final DatePicker datePicker = (DatePicker) view.findViewById(R.id.date_picker);
builder.setView(view);
Calendar cal = Calendar.getInstance();
cal.setTimeInMillis(System.currentTimeMillis());
datePicker.init(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH), cal.get(Calendar.DAY_OF_MONTH), null);
if (v.getId() == R.id.dateET) {
final int inType = dateET.getInputType();
dateET.setInputType(InputType.TYPE_NULL);
dateET.onTouchEvent(event);
dateET.setInputType(inType);
dateET.setSelection(dateET.getText().length());
/*builder.setTitle("请选择开台时间");*/
builder.setPositiveButton("确 定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
//因为当选择的时间是小于10的话回填的时间只是一位,跟我数据库的时间不符
//所以判断小于10的在前面拼接0(如01)
//拼接所有选择的时间(最后拼接的:00是秒钟,为了跟数据库类型相同而拼接上的,可根据自己的需求拼接)
StringBuffer sb = new StringBuffer();
sb.append(String.format("%d-%02d-%02d",
datePicker.getYear(),
datePicker.getMonth() + 1,
datePicker.getDayOfMonth()));
dateET.setText(sb);//把拼接好的数据回填
dialog.cancel();//取消dialog
}
});
}
Dialog dialog = builder.create();
dialog.show();
}
return true;
}
//按钮监听事件
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.submit: {
//拿到录入的数据,并赋值给account对象的对应属性
account.setDate(String.valueOf(dateET.getText()));
account.setItem(String.valueOf(itemET.getText()));
account.setAmount(Double.valueOf(amountET.getText().toString()));
account.setRemark(String.valueOf(remarkET.getText()));
//执行插入数据操作
AccountDBHelper.getInstance(this).insert(account);
//结束当前activity
finish();
}
break;
case R.id.cancel: {
//取消按钮,结束当前activity
finish();
}
}
}
//RadioGroup切换时的操作
@Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
if (checkedId == R.id.income) {
account.setType("收入");
}
if (checkedId == R.id.takeOut) {
account.setType("支出");
}
}
}
2.layout文件
2.1 activity_main.xml(主界面布局文件)
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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"
tools:context=".MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="start"
android:orientation="vertical"
tools:ignore="MissingConstraints">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="30dp"
android:background="@drawable/btn_normal"
android:gravity="left"
android:orientation="vertical"
android:padding="20dp"
tools:ignore="MissingConstraints"
tools:layout_editor_absoluteX="44dp"
tools:layout_editor_absoluteY="46dp">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="left"
android:orientation="vertical"
tools:ignore="MissingConstraints">
<TextView
android:id="@+id/ti_balance"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/ti_balance"
android:textSize="30dp" />
<TextView
android:id="@+id/balance"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="40dp"
android:textColor="@color/yellow"
android:textStyle="bold" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="30dp"
android:gravity="center"
android:orientation="horizontal"
tools:ignore="MissingConstraints">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="left"
android:orientation="horizontal"
tools:ignore="MissingConstraints">
<TextView
android:id="@+id/ti_income"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/ti_income"
android:textSize="20dp" />
<TextView
android:id="@+id/income"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:textColor="@color/red"
android:textSize="20dp"
android:textStyle="bold" />
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="left"
android:orientation="horizontal"
tools:ignore="MissingConstraints">
<TextView
android:id="@+id/ti_expenditure"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/ti_expenditure"
android:textSize="20dp" />
<TextView
android:id="@+id/expenditure"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/red"
android:layout_marginLeft="10dp"
android:textSize="20dp"
android:textStyle="bold" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="horizontal"
tools:ignore="MissingConstraints">
<Button
android:id="@+id/addAccount"
android:layout_width="140dp"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:background="@drawable/btn_normal"
android:padding="10dp"
android:text="@string/writeANote"
android:textColor="@drawable/btn_selector"
android:textSize="20dp"
android:textStyle="bold" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="horizontal">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="8"
android:text="日期"
android:textStyle="bold"
android:gravity="center"
android:padding="5dp"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="10"
android:gravity="center"
android:text="项目"
android:textStyle="bold"
android:padding="5dp"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="10"
android:gravity="center"
android:text="类型"
android:textStyle="bold"
android:padding="5dp"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="9"
android:gravity="center"
android:text="金额"
android:textStyle="bold"
android:padding="5dp" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="9"
android:gravity="center"
android:text="备注"
android:textStyle="bold"
android:padding="5dp"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:ignore="MissingConstraints">
<ListView
android:id="@+id/lv_information"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
2.2 activity_add_account.xml(记账界面布局文件)
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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"
tools:context=".AddAccount">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="30dp"
android:gravity="center_horizontal"
android:orientation="vertical"
tools:ignore="MissingConstraints">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="20dp"
android:gravity="left"
android:orientation="vertical"
android:padding="20dp"
tools:ignore="MissingConstraints"
tools:layout_editor_absoluteX="44dp"
tools:layout_editor_absoluteY="46dp">
<RadioGroup
android:id="@+id/type"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="horizontal">
<RadioButton
android:id="@+id/income"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/ti_income"
android:textSize="30dp" />
<RadioButton
android:id="@+id/takeOut"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="50dp"
android:text="@string/ti_expenditure"
android:textSize="30dp" />
</RadioGroup>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center|bottom"
android:orientation="horizontal"
tools:ignore="MissingConstraints">
<TextView
android:id="@+id/title_amount"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/ti_amount"
android:textSize="20dp" />
<EditText
android:id="@+id/amount"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:gravity="center"
android:textColor="@color/purple_500"
android:inputType="numberDecimal"
android:textSize="50dp"
android:textStyle="bold" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:gravity="center"
android:orientation="horizontal"
tools:ignore="MissingConstraints">
<TextView
android:id="@+id/title_item"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/ti_item"
android:textSize="20dp" />
<EditText
android:id="@+id/item"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:gravity="center"
android:background="@drawable/text_view_shape"
android:textSize="20dp"
android:textStyle="bold" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:gravity="center"
android:orientation="horizontal"
tools:ignore="MissingConstraints">
<TextView
android:id="@+id/title_date"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/ti_date"
android:textSize="20dp" />
<EditText
android:id="@+id/dateET"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:gravity="center"
android:background="@drawable/text_view_shape"
android:inputType="number"
android:textSize="20dp"
android:textStyle="bold" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:gravity="center"
android:orientation="horizontal"
tools:ignore="MissingConstraints">
<TextView
android:id="@+id/title_remark"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/ti_remark"
android:textSize="20dp" />
<EditText
android:id="@+id/remark"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:background="@drawable/text_view_shape"
android:textSize="20dp"
android:gravity="center"
android:textStyle="bold" />
</LinearLayout>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="horizontal"
tools:ignore="MissingConstraints">
<Button
android:id="@+id/cancel"
android:layout_width="120dp"
android:layout_height="wrap_content"
android:background="@drawable/btn_normal"
android:padding="15dp"
android:text="@string/cancel"
android:textColor="@drawable/btn_selector"
android:textSize="20dp"
android:textStyle="bold" />
<Button
android:id="@+id/submit"
android:layout_width="120dp"
android:layout_height="wrap_content"
android:layout_marginLeft="50dp"
android:background="@drawable/btn_normal"
android:padding="15dp"
android:text="@string/submit"
android:textColor="@drawable/btn_selector"
android:textSize="20dp"
android:textStyle="bold" />
</LinearLayout>
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
2.3 date_dialog.xml(选择日期布局文件)
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center">
<DatePicker
android:id="@+id/date_picker"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dip"
android:spinnersShown="false" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
2.4 list_layout_account.xml(账单记录显示布局文件)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:paddingTop="15dp"
android:orientation="horizontal">
<TextView
android:id="@+id/date"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="8"
android:gravity="center"
android:padding="5dp"/>
<TextView
android:id="@+id/item"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="10"
android:gravity="center"
android:padding="5dp"/>
<TextView
android:id="@+id/type"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="10"
android:gravity="center"
android:padding="5dp"/>
<TextView
android:id="@+id/amount"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="9"
android:gravity="center"
android:padding="5dp"/>
<TextView
android:id="@+id/remark"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="9"
android:gravity="center"
android:padding="5dp"/>
</LinearLayout>
</LinearLayout>
3.drawable文件
3.1 btn_normal.xml(按钮常规样式)
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<!-- 圆角的半径 -->
<corners android:radius="10dp" />
<!-- 填充颜色 -->
<solid android:color= "@color/purple_500"/>
<!-- 描边 -->
<stroke
android:color="@color/purple_500"
android:width="1dp"/>
</shape>
3.2btn_selector.xml(按钮选择样式)
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- 正常状态 -->
<item android:state_pressed="false" android:color="@color/white" />
<!-- 按下状态 -->
<item android:state_pressed="true" android:color="@color/black" />
</selector>
3.3 text_view_shape.xml(view边框样式)
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="2dp" />
<stroke
android:width="1dp"
android:color="@color/black" />
<padding
android:bottom="2dp"
android:left="4dp"
android:right="4dp"
android:top="2dp" />
</shape>