10分钟手把手教你用Android手撸一个简易的个人记账App

您所在的位置:网站首页 android记事本 10分钟手把手教你用Android手撸一个简易的个人记账App

10分钟手把手教你用Android手撸一个简易的个人记账App

2023-08-15 11:53| 来源: 网络整理| 查看: 265

「本文已参与好文召集令活动,点击查看:后端、大前端双赛道投稿,2万元奖池等你挑战!」

⛱️序言

前段时间期末周,这学期有一门课叫移动应用开发,这门课的期末作业是用 Android 写一个个人记账管理系统。 Android 的前台是用 xml 实现,后台是用 java 实现。于是,对这两门语言不太熟悉的周一,开始了漫漫长路的摸索之旅。

接下来就来讲解,如何从0到1实现一个简易的个人记账系统。

一起来学习⑧~🙃

温馨小提示: 第二部分的编码阶段代码较多,可直接滑到第三部分看运行效果,并到第四部分克隆github仓库代码,阅读体验更加~

📋一、系统结构设计Design 1. 需求分析

首先我们先来看下老师的需求👇

设计和实现一个类似个人财务管理的 Android APP ,数据库采用 SQLite (也可以直接访问 Web 端 MySQL 数据库、或提供 Web 接口访问 MySQL 数据库)。

APP应具备以下功能:

用户注册和登录(这类 APP 一般面对个人,用户不需要分类别); 收入和支出管理(单条收支记录的添加、删除和修改,收入和支出每一条记录至少包括日期、类型、金额和说明。) 收入和支出查询(根据时间段、类别等进行查询) 收入和支出统计(例如某个月、某个星期或指定时间段的总收支) 其他要求:界面设计应尽量美观,可以添加一些图片或背景。

基于以上需求,周一对所要实现的功能进行了整理。请看下方思维导图:

需求分析

2. 数据库设计

分析完成之后,接下来开始设计数据库。详情见下方思维导图:

数据库设计

因为功能较为简单,所以数据库只设计了两张表。

3. 界面设计

设计完数据库之后,开始楷模润色该 APP 的界面。基于本次课题需求,周一设计了5个界面。接下来先来看 App 的具体界面设计:

界面设计

看完五个界面所需要的内容之后,接下来,我们来对它进行原型绘制。请看下图:

原型图

现在,原型图设计完毕。我们接着设计高保真 App 界面。请看下图:

高保真界面1

高保真界面2

4. 过程设计

好了,看完原型图之后,我们是不是该来想想页面与页面之间,是怎么进行交互的呢?

因此,现在我们来对整个过程进行设计。详情见下方思维导图:

过程设计

📘二、编码阶段Coding 1. 项目结构🗂️ (1)文件目录

先来看项目的文件目录,详情看下图👇

项目文件结构

(2)AndroidManifest.xml

接下来附上 AndroidManifest.xml 的代码,具体代码如下:

复制代码 (3)Activity类解读

看完上面两个内容之后,接下来是Activity类的解读时间。详情见下表👇

文件名作用MainActivity用户登录页面Activity,用户可以进行登录。RegisterActivity用户注册页面Activity,用户可以进行注册。UserCenterActivity个人中心Activity,对应用户个人中心的4个按钮进行功能编写,实现用户收支管理、查看收支、收支统计、退出登录四大功能。ManageActivity收支管理Activity,对用户的收入和支出进行管理。SearchRecordActivity查询收支Activity,通过条件对数据库中的数据进行查询,得出用户想要查询的收支结果。DBHelper创建数据库表和数据库数据,同时实现与数据库操作相关的登录和注册方法。User用户类Activity,用于获取用户ID以及密码。 (4)XML解读

解读完 Activity 类之后,现在来对 XML 的各个文件进行介绍。详情见下表👇

文件名作用activity_main.xml用户登录页面,用户通过输入账号和密码,进行登录操作。activity_register.xml用户注册页面,用户通过输入账号和密码,进行注册操作。activity_user_center.xml个人中心页面,当用户登录成功以后,进行个人中心页面。个人中心实现收支管理、查看收支、收支统计、退出登录四大功能。activity_search_record.xml通过选择年份月份来进行查询该年该月份的各个收入支出详情,并且计算总金额以及根据类别来计算该类别的总金额。activity_manage.xml用户对自己的日常开销进行收支管理,可以进行添加、删除和修改等操作。record_item_layout.xml用来存储列表的传输数据

到这里,大家先对待会要编写的 Activity 类和 XML 文件所要展示的功能先进行一番了解。

2. 静态页面⌛

现在,我们到了真正的编码阶段啦!如果是按照我的编码习惯的话,我一般会先把静态页面进行构建,并把一些需要预留的id等等信息给先处理好,方便后面写业务逻辑时可以直接进行绑定。

针对以上6个静态页面,下面将进行代码编写。

(1)用户登录页面activity_main.xml

activity_main.xml 是用户登录页面,当用户通过输入账号和密码时,可以进行登录操作。具体代码如下:

复制代码 (2)用户注册页面activity_register.xml

activity_register.xml 是用户注册页面,用户通过输入账号和密码,可以进行注册操作。具体代码如下:

复制代码 (3)用户个人中心页面activity_user_center.xml

现在,来到了个人中心页面。在个人中心页面当中,将会显示具体的用户名。同时, 有四个按钮入口,分别是:收支管理,查看收支,退出登录和收支统计。来看下具体代码实现:

复制代码 (4)用户搜索记录页面activity_search_record.xml

用户可以通过选择年份月份和筛选类型,点击搜索,来查询该年该月份的各个收入和支出的详情,同时在该时间点和该筛选类型下,点击计算可以对总金额进行计算。下面附上具体代码实现:

复制代码 (5)收支管理页面activity_manage.xml

对于收支管理页面来说,用户可以对自己的日常开销进行收支管理,同时也可以进行添加、删除和修改等操作。具体代码如下:

复制代码 (6)列表数据记录record_item_layout.xml

record_item_layout.xml 主要用途是存储列表的传输数据。具体代码如下:

复制代码 3. 逻辑结构💡

写完静态页面之后,接下来我们要对每个页面的逻辑进行编写。现在我们来看一下各个 Activity 类所实现的内容都有些什么呢?

(1)DBHelper类

DBHelper 类用于创建数据库表和数据库数据,同时实现与数据库操作相关的登录和注册方法。具体代码实现如下:

package com.financial.management; import android.content.ContentValues; import android.content.Context; import android.database.Cursor; import android.database.SQLException; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; public class DBHelper extends SQLiteOpenHelper { public static final String DB_NAME = "Test.db"; public static final String TABLE_NAME = "userinfo"; public static final String COLUMN_USERID = "uid"; public static final String COLUMN_USERPWD = "upwd"; //创建数据库语句 private static final String CREATE_TABLE = "create table if not exists " + TABLE_NAME + "(" + COLUMN_USERID + " text not null primary key," + COLUMN_USERPWD + " text not null)"; public DBHelper(Context context) { super(context, DB_NAME, null, 1); } //创建数据库方法 @Override public void onCreate(SQLiteDatabase db) { try { db.execSQL(CREATE_TABLE); db.execSQL("insert into " + TABLE_NAME + " values('11','11')"); } catch (SQLException e) { e.printStackTrace(); } } //重置数据库方法(先删表,再建表) @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { db.execSQL("drop table if exists " + TABLE_NAME); db.execSQL(CREATE_TABLE); } //登录方法 public User userlogin(String userId, String userPwd) { User user = null; SQLiteDatabase db = getReadableDatabase(); Cursor cursor = db.query(TABLE_NAME, new String[]{COLUMN_USERID, COLUMN_USERPWD}, COLUMN_USERID + "=? and " + COLUMN_USERPWD + "=?", new String[]{userId, userPwd}, null, null, null); if (cursor.getCount() > 0) { cursor.moveToFirst(); user = new User(); user.setUserId(cursor.getString(cursor.getColumnIndex(COLUMN_USERID))); user.setUserPwd(cursor.getString(cursor.getColumnIndex(COLUMN_USERPWD))); } return user; } //注册方法 public long registerUser(User user) { SQLiteDatabase db = getWritableDatabase(); ContentValues contentValues = new ContentValues(); contentValues.put(COLUMN_USERID, user.getUserId()); contentValues.put(COLUMN_USERPWD, user.getUserPwd()); return db.insert(TABLE_NAME, null, contentValues); } } 复制代码 (2)MainActivity类

MainActivity 类是用户登录页面的Activity,主要编写用户登录页面的代码逻辑。具体代码实现如下:

package com.financial.management; import androidx.appcompat.app.AppCompatActivity; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.Toast; import java.util.ArrayList; //登录页面逻辑 public class MainActivity extends AppCompatActivity { EditText edt_id,edt_pwd; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); edt_id = findViewById(R.id.edt_uid); edt_pwd =findViewById(R.id.edt_upwd); Button btn_login = findViewById(R.id.btn_login); //登录按键 btn_login.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { try { String userId=edt_id.getText().toString(); String userPwd=edt_pwd.getText().toString(); DBHelper dbuserHelper=new DBHelper(getApplicationContext()); User user = dbuserHelper.userlogin(userId,userPwd); //登录成功跳转对应类型界面 if(user!=null) { Toast.makeText(getApplicationContext(), user.getUserId() + "登录成功", Toast.LENGTH_SHORT).show(); Intent intent; ArrayList list = new ArrayList(); list.add(user); intent = new Intent(getApplicationContext(), UserCenterActivity.class); intent.putParcelableArrayListExtra("LoginUser", list); startActivity(intent); }else{ Toast.makeText(getApplicationContext(),"登录失败,密码错误或账号不存在!",Toast.LENGTH_SHORT).show(); } } catch (Exception e) { e.printStackTrace(); Toast.makeText(getApplicationContext(),"数据库异常",Toast.LENGTH_SHORT).show(); } } }); //注册按键 Button btn_register=findViewById(R.id.btn_register); btn_register.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent=new Intent(getApplicationContext(),RegisterActivity.class); startActivity(intent); } }); } } 复制代码 (3)RegisterActivity类

RegisterActivity 类是用户注册页面的Activity,主要编写用户注册页面的业务逻辑。具体代码实现如下:

package com.financial.management; import androidx.appcompat.app.AppCompatActivity; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.Toast; import java.util.ArrayList; //注册页面逻辑 public class RegisterActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_register); final EditText edt_rid =findViewById(R.id.edt_rid); final EditText edt_rpwd =findViewById(R.id.edt_rpwd); //注册按键 Button btn_registerf=findViewById(R.id.btn_registeruser); btn_registerf.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { User user = new User(); user.setUserId(edt_rid.getText().toString()); user.setUserPwd(edt_rpwd.getText().toString()); DBHelper dbUserHelper = new DBHelper(getApplicationContext()); if (dbUserHelper.registerUser(user) > 0) { Toast.makeText(getApplicationContext(), "注册成功", Toast.LENGTH_SHORT).show(); Intent intent; ArrayList list = new ArrayList(); list.add(user); intent = new Intent(getApplicationContext(), MainActivity.class); startActivity(intent); }else{ Toast.makeText(getApplicationContext(), "您已经注册过此账户,请返回登录", Toast.LENGTH_SHORT).show(); } } }); } } 复制代码 (4)UserCenterActivity类

UserCenterActivity 类是个人中心页面的Activity,主要编写个人中心各种按钮跳转的业务逻辑。具体代码实现如下:

package com.financial.management; import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AppCompatActivity; import android.content.DialogInterface; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.widget.ImageView; import android.widget.TextView; import java.util.ArrayList; //用户个人中心页面逻辑 public class UserCenterActivity extends AppCompatActivity { ArrayList list; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_user_center); Intent intent=getIntent(); list =intent.getParcelableArrayListExtra("LoginUser"); User user=list.get(0); final String username=user.getUserId(); TextView tv_welcome=findViewById(R.id.tv_welcome); tv_welcome.setText("欢迎您 ,用户"+username); //收支管理 ImageView btn_recordmanage =findViewById(R.id.btn_recordmanage); btn_recordmanage.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent1=new Intent(getApplicationContext(), ManageActivity.class); startActivity(intent1); } }); //收支查询 ImageView btn_searchrecord=findViewById(R.id.btn_searchrecord); btn_searchrecord.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent2=new Intent(getApplicationContext(),SearchRecordActivity.class); startActivity(intent2); } }); //收支统计 ImageView btn_calcmoney=findViewById(R.id.btn_calcmoney); btn_calcmoney.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent3=new Intent(getApplicationContext(),SearchRecordActivity.class); startActivity(intent3); } }); //退出按键 ImageView btn_exit=findViewById(R.id.btn_exit); btn_exit.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { AlertDialog dialog = new AlertDialog.Builder(UserCenterActivity.this).setTitle("退出操作") .setMessage("确定退出,不继续玩玩?") .setPositiveButton("确定", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { Intent intent=new Intent(getApplicationContext(), MainActivity.class); startActivity(intent); } }).setNegativeButton("继续留下!", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { } }).create(); dialog.show(); } }); } } 复制代码 (5)SearchRecordActivity类

SearchRecordActivity 类是搜索记录页面的Activity,主要编写我的收支页面的业务逻辑。具体代码实现如下:

package com.financial.management; import androidx.appcompat.app.AppCompatActivity; import android.database.Cursor; import android.database.SQLException; import android.database.sqlite.SQLiteDatabase; import android.os.Bundle; import android.text.TextUtils; import android.view.View; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.Button; import android.widget.ListView; import android.widget.SimpleAdapter; import android.widget.Spinner; import android.widget.TextView; import android.widget.Toast; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; //收支记录页面业务逻辑 public class SearchRecordActivity extends AppCompatActivity { //定义spinner中的数据 private String[] date_data= {"", "202101", "202102", "202103", "202104", "202105","202106","202107","202108","202109","202110","202111","202112"}; private String[] type_data = {"", "收入", "支出"}; Spinner spin_date, spin_type; ListView listView; TextView tv_show; float sum=0; //数据库 private String selectDate, selectType; private static final String DATABASE_NAME = "Test.db"; private static final String TABLE_NAME = "record"; private static final String COLUMN_ID = "id"; private static final String COLUMN_DATE = "date"; private static final String COLUMN_TYPE = "type"; private static final String COLUMN_MONEY = "money"; private static final String COLUMN_STATE = "state"; private SQLiteDatabase sqLiteDatabase = null; private void selectSumMoney() { //自定义查询的sql语句 String sql; //如果查询时间和查询类型都为空,则查询整个表 if (TextUtils.isEmpty(selectDate) && TextUtils.isEmpty(selectType)) { sql = "select * from " + TABLE_NAME; //如果有查询时间,没有查询类型,查询指定内容 } else if (!TextUtils.isEmpty(selectDate) && TextUtils.isEmpty(selectType)) { sql = "select * from " + TABLE_NAME + " where date='" + selectDate + "'"; //如果没有查询时间,有查询类型,查询指定内容 } else if (TextUtils.isEmpty(selectDate) && !TextUtils.isEmpty(selectType)) {//如果没有查询时间,有查询类型 sql = "select * from " + TABLE_NAME + " where type='" + selectType+"'"; } else {//否则,查询条件都不为空,查询指定内容 sql ="select * from " + TABLE_NAME + " where date='" + selectDate + "' and type='" + selectType+"'"; } Cursor cursor = sqLiteDatabase.rawQuery(sql, null); while (cursor.moveToNext()) { float money = cursor.getFloat(cursor.getColumnIndex(COLUMN_MONEY)); sum=sum+money; //list.add(map); } String money2=String.valueOf(sum); tv_show.setText(money2); sum=0; } //选择数据 private void selectData() { //自定义查询的sql语句 String sql; //如果查询时间和查询类型都为空,则查询整个表 if (TextUtils.isEmpty(selectDate) && TextUtils.isEmpty(selectType)) { sql = "select * from " + TABLE_NAME; //如果有查询时间,没有查询类型,查询指定内容 } else if (!TextUtils.isEmpty(selectDate) && TextUtils.isEmpty(selectType)) { sql = "select * from " + TABLE_NAME + " where date='" + selectDate + "'"; //如果没有查询时间,有查询类型,查询指定内容 } else if (TextUtils.isEmpty(selectDate) && !TextUtils.isEmpty(selectType)) {//如果没有查询时间,有查询类型 sql = "select * from " + TABLE_NAME + " where type='" + selectType+"'"; } else {//否则,查询条件都不为空,查询指定内容 sql = "select * from " + TABLE_NAME + " where date='" + selectDate + "' and type='" + selectType+"'"; } //将查询到的数据封装到Cursor Cursor cursor = sqLiteDatabase.rawQuery(sql, null); ArrayList list = new ArrayList(); if (cursor.getCount() == 0) { //查无数据则怒不显示列表 // listView.setVisibility(View.GONE); Toast.makeText(getApplicationContext(), "无数据", Toast.LENGTH_SHORT).show(); } else { //查有数据则显示列表 listView.setVisibility(View.VISIBLE); while (cursor.moveToNext()) { int id = cursor.getInt(cursor.getColumnIndex(COLUMN_ID)); String date = cursor.getString(cursor.getColumnIndex(COLUMN_DATE)); String type = cursor.getString(cursor.getColumnIndex(COLUMN_TYPE)); float money = cursor.getFloat(cursor.getColumnIndex(COLUMN_MONEY)); String state = cursor.getString(cursor.getColumnIndex(COLUMN_STATE)); Map map = new HashMap(); map.put("id", String.valueOf(id)); map.put("date", date); map.put("type", type); map.put("money", String.valueOf(money)); map.put("state", state); list.add(map); } //创建SimpleAdapter SimpleAdapter simpleAdapter = new SimpleAdapter(getApplicationContext(), list, R.layout.record_item_layout, new String[]{"id", "date", "type", "money", "state"}, new int[]{R.id.list_id, R.id.list_date, R.id.list_type, R.id.list_money, R.id.list_state}); listView.setAdapter(simpleAdapter); } } //时间和类别spinner点击事件 private void initClick() { //时间事件 spin_date.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { @Override public void onItemSelected(AdapterView parent, View view, int position, long id) { selectDate = date_data[position]; } @Override public void onNothingSelected(AdapterView parent) { } }); //类别事件 spin_type.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { @Override public void onItemSelected(AdapterView parent, View view, int position, long id) { selectType = type_data[position]; } @Override public void onNothingSelected(AdapterView parent) { } }); findViewById(R.id.btn_search).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { selectData(); } }); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_search_record); tv_show=findViewById(R.id.tv_show); try { //打开数据库,如果是第一次会创建该数据库,模式为MODE_PRIVATE sqLiteDatabase = openOrCreateDatabase(DATABASE_NAME, MODE_PRIVATE, null); //执行创建表的sql语句,虽然每次都调用,但只有首次才创建表 //执行查询 listView = findViewById(R.id.searchlistview);//绑定列表 selectData(); } catch (SQLException e) { Toast.makeText(this, "数据库异常!", Toast.LENGTH_LONG).show(); e.printStackTrace(); } ArrayAdapter adapter = new ArrayAdapter(this, android.R.layout.simple_spinner_item, date_data); adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); spin_date = findViewById(R.id.spin_date); spin_date.setAdapter(adapter); ArrayAdapter adapter1 = new ArrayAdapter(this, android.R.layout.simple_spinner_item, type_data); adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); spin_type = findViewById(R.id.spin_type); spin_type.setAdapter(adapter1); initClick(); Button btn_calc=findViewById(R.id.btn_calc); btn_calc.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { selectSumMoney(); } }); } } 复制代码 (6)ManageActivity类

ManageActivity 类是收支管理页面的Activity,主要编写用户的收入和支出的业务逻辑,实现收支的增删改查。具体代码实现如下:

package com.financial.management; import androidx.appcompat.app.AppCompatActivity; import android.content.DialogInterface; import android.database.Cursor; import android.database.SQLException; import android.database.sqlite.SQLiteDatabase; import android.os.Bundle; import android.view.View; import android.widget.AdapterView; import android.widget.Button; import android.widget.EditText; import android.widget.ListView; import android.widget.SimpleAdapter; import android.widget.TextView; import android.widget.Toast; import androidx.appcompat.app.AlertDialog; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; public class ManageActivity extends AppCompatActivity { private SQLiteDatabase sqLiteDatabase = null; private int selectId = -1; EditText edt_date, edt_type, edt_money, edt_state; TextView tv_test; private static final String DATABASE_NAME = "Test.db"; private static final String TABLE_NAME = "record"; private static final String COLUMN_ID = "id"; private static final String COLUMN_DATE = "date"; private static final String COLUMN_TYPE = "type"; private static final String COLUMN_MONEY = "money"; private static final String COLUMN_STATE = "state"; //创建表 private static final String CREATE_TABLE = "create table if not exists " + TABLE_NAME + "(" + COLUMN_ID + " integer primary key autoincrement," + COLUMN_DATE + " text," + COLUMN_TYPE + " text," + COLUMN_MONEY + " float," + COLUMN_STATE + " text)"; //自定义的查询方法 private void selectData() { //遍历整个表 String sql = "select * from " + TABLE_NAME ; //把查询数据封装到Cursor Cursor cursor = sqLiteDatabase.rawQuery(sql, null); ArrayList list = new ArrayList(); //用while循环遍历Cursor,再把它分别放到map中,最后统一存入list中,便于调用 while (cursor.moveToNext()) { int id = cursor.getInt(cursor.getColumnIndex(COLUMN_ID)); String date = cursor.getString(cursor.getColumnIndex(COLUMN_DATE)); String type = cursor.getString(cursor.getColumnIndex(COLUMN_TYPE)); float money = cursor.getFloat(cursor.getColumnIndex(COLUMN_MONEY)); String state = cursor.getString(cursor.getColumnIndex(COLUMN_STATE)); Map map = new HashMap(); map.put("id", String.valueOf(id)); map.put("date", date); map.put("type", type); map.put("money", String.valueOf(money)); map.put("state", state); list.add(map); } //创建SimpleAdapter SimpleAdapter simpleAdapter = new SimpleAdapter(getApplicationContext(), list, R.layout.record_item_layout, new String[]{"id", "date", "type", "money", "state"}, new int[]{R.id.list_id, R.id.list_date, R.id.list_type, R.id.list_money, R.id.list_state}); final ListView listView = findViewById(R.id.recordlistview); //绑定适配器 listView.setAdapter(simpleAdapter); //设置ListView单击事件 listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView parent, View view, int position, long id) { ListView tempList = (ListView) parent; View mView = tempList.getChildAt(position); TextView list_id = mView.findViewById(R.id.list_id); TextView list_date = mView.findViewById(R.id.list_date); TextView list_type = mView.findViewById(R.id.list_type); TextView list_money = mView.findViewById(R.id.list_money); TextView list_state = mView.findViewById(R.id.list_state); String rid = list_id.getText().toString(); String date = list_date.getText().toString(); String type = list_type.getText().toString(); String money = list_money.getText().toString(); String state = list_state.getText().toString(); tv_test.setText(rid); edt_date.setText(date); edt_type.setText(type); edt_money.setText(money); edt_state.setText(state); selectId = Integer.parseInt(rid); } }); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_manage); try { sqLiteDatabase = openOrCreateDatabase(DATABASE_NAME, MODE_PRIVATE, null); sqLiteDatabase.execSQL(CREATE_TABLE); //执行查询 selectData(); } catch (SQLException e) { Toast.makeText(this, "数据库异常!", Toast.LENGTH_LONG).show(); e.printStackTrace(); } tv_test = findViewById(R.id.tv_test); edt_date = findViewById(R.id.edt_date); edt_type = findViewById(R.id.edt_type); edt_money = findViewById(R.id.edt_money); edt_state = findViewById(R.id.edt_state); //新增按键 Button btn_add = findViewById(R.id.btn_add); btn_add.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (edt_date.getText().toString().equals("") | edt_type.getText().toString().equals("") | edt_money.getText().toString().equals("") | edt_state.getText().toString().equals("")) { Toast.makeText(ManageActivity.this, "数据不能为空!", Toast.LENGTH_LONG).show(); return; } String date = edt_date.getText().toString(); String type = edt_type.getText().toString(); String money = edt_money.getText().toString(); String state = edt_state.getText().toString(); //定义添加数据的sql语句 String sql = "insert into " + TABLE_NAME + "(" + COLUMN_DATE + "," + COLUMN_TYPE + "," + COLUMN_MONEY + "," + COLUMN_STATE + ") " + "values('" + date + "','" + type + "','" + money + "','" + state + "')"; //执行sql语句 sqLiteDatabase.execSQL(sql); Toast.makeText(getApplicationContext(), "新增数据成功!", Toast.LENGTH_LONG).show(); //刷新显示列表 selectData(); //消除数据 tv_test.setText(""); edt_date.setText(""); edt_type.setText(""); edt_money.setText(""); edt_state.setText(""); } }); //修改按键 Button btn_update = findViewById(R.id.btn_update); btn_update.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //无选择提示 if (selectId == -1) { Toast.makeText(getApplicationContext(), "请选择要修改的行!", Toast.LENGTH_LONG).show(); return; } //判断是否有空数据 if (edt_date.getText().toString().equals("") | edt_type.getText().toString().equals("") | edt_money.getText().toString().equals("") | edt_state.getText().toString().equals("")) { Toast.makeText(getApplicationContext(), "数据不能为空!", Toast.LENGTH_LONG).show(); return; } String date = edt_date.getText().toString(); String type = edt_type.getText().toString(); String money = edt_money.getText().toString(); String state = edt_state.getText().toString(); //定义修改数据的sql语句 String sql = "update " + TABLE_NAME + " set " + COLUMN_DATE + "='" + date + "',type='" + type + "',money='" + money + "',state='" + state + "' where id=" + selectId; //执行sql语句 sqLiteDatabase.execSQL(sql); Toast.makeText(getApplicationContext(), "修改数据成功!", Toast.LENGTH_LONG).show(); //刷新显示列表 selectData(); selectId = -1; //消除数据 tv_test.setText(""); edt_date.setText(""); edt_type.setText(""); edt_money.setText(""); edt_state.setText(""); } }); //删除按键 Button btn_delete = findViewById(R.id.btn_delete); btn_delete.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //无选择提示 if (selectId == -1) { Toast.makeText(ManageActivity.this, "请选择要删除的行!", Toast.LENGTH_LONG).show(); return; } //定义删除对话框 AlertDialog dialog = new AlertDialog.Builder(ManageActivity.this).setTitle("删除操作") .setMessage("确定删除?此操作不可逆,请慎重选择!") .setPositiveButton("确定", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { //定义删除的sql语句 String sql = "delete from " + TABLE_NAME + " where id=" + selectId; //执行sql语句 sqLiteDatabase.execSQL(sql); //刷新显示列表 Toast.makeText(getApplicationContext(), "删除数据成功!", Toast.LENGTH_LONG).show(); selectData(); selectId = -1; //清除数据 tv_test.setText(""); edt_date.setText(""); edt_type.setText(""); edt_money.setText(""); edt_state.setText(""); } }).setNegativeButton("取消", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { } }).create(); dialog.show(); } }); } } 复制代码 (7)User类

User 类是用户类Activity,用于获取用户ID以及密码。具体代码实现如下:

package com.financial.management; import android.os.Parcel; import android.os.Parcelable; public class User implements Parcelable { private String userId=""; private String userPwd=""; public String getUserId() { return userId; } public void setUserId(String userId) { this.userId = userId; } public String getUserPwd() { return userPwd; } public void setUserPwd(String userPwd) { this.userPwd = userPwd; } @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel dest, int flags) { dest.writeString(this.userId); dest.writeString(this.userPwd); } public User() { } protected User(Parcel in) { this.userId = in.readString(); this.userPwd = in.readString(); } public static final Creator CREATOR = new Creator() { @Override public User createFromParcel(Parcel source) { return new User(source); } @Override public User[] newArray(int size) { return new User[size]; } }; } 复制代码 🎵三、运行结果Result

到这里,整个系统的设计就差不多要结束啦!现在我们用一段视频来演示整个系统的运行效果🌈

9ymwr-kzz8i.gif

如想看BGM版本,可点击此链接进入观看~

📈四、结束语

在拿到这个课题呢,周一首先对课题进行了系统结构设计,结构设计完成之后就到了编码阶段。编码阶段分为两部分进行,先是进行静态页面的楷模,而后到了业务逻辑的编写。

讲到这里,整个系统从设计阶段到编码阶段的整个过程讲解就结束啦!这也算是我学习Android的第一个小作品,作品不完美之处较多,后续还将会继续改进~

本文代码已上传至github,戳此链接可下载代码~

🐣彩蛋 One More Thing (:不合理设计 年月份数据写的太固定了,没有可扩展性 日期应该用日期选择器来做,而不应该是以文本的形式 收入和支出应该以单选框来进行选择,而不应该是文本的形式 …… (:番外篇 关注公众号星期一研究室,第一时间关注学习干货,更多精选专栏待你解锁~ 如果这篇文章对你有用,记得留个脚印jio再走哦~ 以上就是本文的全部内容!我们下期见!👋👋👋


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3