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

先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7

深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新大数据全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上大数据知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以添加V获取:vip204888 (备注大数据)
img

正文

    <LinearLayout

android:layout_width=“match_parent”
android:layout_height=“wrap_content”
android:orientation=“horizontal”
android:layout_marginVertical=“20dp”
android:layout_marginHorizontal=“20dp”>

        <TextView

android:id=“@+id/textView29”
android:layout_width=“wrap_content”
android:layout_height=“wrap_content”
android:layout_weight=“1”
android:text=“序号”
android:textColor=“#6290c8”
android:textStyle=“bold”
android:textSize=“18sp”
android:gravity=“center_horizontal”/>

        <TextView

android:id=“@+id/textView26”
android:layout_width=“wrap_content”
android:layout_height=“wrap_content”
android:layout_weight=“1”
android:text=“日期”
android:textColor=“#6290c8”
android:textStyle=“bold”
android:textSize=“18sp”
android:gravity=“center_horizontal”/>

        <TextView

android:id=“@+id/textView25”
android:layout_width=“wrap_content”
android:layout_height=“wrap_content”
android:layout_weight=“1”
android:text=“类型”
android:textColor=“#6290c8”
android:textStyle=“bold”
android:textSize=“18sp”
android:gravity=“center_horizontal”/>

        <TextView

android:id=“@+id/textView27”
android:layout_width=“wrap_content”
android:layout_height=“wrap_content”
android:layout_weight=“1”
android:text=“金额”
android:textColor=“#6290c8”
android:textStyle=“bold”
android:textSize=“18sp”
android:gravity=“center_horizontal”/>

        <TextView

android:id=“@+id/textView28”
android:layout_width=“wrap_content”
android:layout_height=“wrap_content”
android:layout_weight=“1”
android:text=“说明”
android:textColor=“#6290c8”
android:textStyle=“bold”
android:textSize=“18sp”
android:gravity=“center_horizontal”/>

    <ListView

android:id=“@+id/searchlistview”
android:layout_width=“match_parent”
android:layout_height=“500dp”
android:layout_weight=“0”
android:layout_marginHorizontal=“20dp”/>

</androidx.constraintlayout.widget.ConstraintLayout>


#### (5)收支管理页面activity\_manage.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=“.ManageActivity”>

<LinearLayout

android:layout_width=“match_parent”
android:layout_height=“match_parent”
android:gravity=“center_horizontal”
android:orientation=“vertical”
app:layout_constraintBottom_toBottomOf=“parent”
app:layout_constraintLeft_toLeftOf=“parent”
app:layout_constraintTop_toTopOf=“parent”>

    <LinearLayout

android:layout_width=“match_parent”
android:layout_height=“200dp”
android:gravity=“center”
android:orientation=“vertical”>

        <ImageView

android:id=“@+id/imageView2”
android:layout_width=“150dp”
android:layout_height=“150dp”
android:layout_marginTop=“20dp”
app:srcCompat=“@drawable/income_1” />

        <TextView

android:id=“@+id/textView20”
android:layout_width=“wrap_content”
android:layout_height=“30dp”
android:text=“收支管理”
android:textColor=“#3F51B5”
android:textSize=“20dp” />

    <LinearLayout

android:layout_width=“match_parent”
android:layout_height=“50dp”
android:gravity=“center_vertical”
android:orientation=“horizontal”>

        <TextView

android:id=“@+id/textView36”
android:layout_width=“wrap_content”
android:layout_height=“wrap_content”
android:layout_marginHorizontal=“20dp”
android:text=“您选择的序号是:”
android:textColor=“#152029”
android:textSize=“18sp”
android:textStyle=“bold” />

        <TextView

android:id=“@+id/tv_test”
android:layout_width=“match_parent”
android:layout_height=“wrap_content”
android:hint=“暂未选择”
android:textColor=“#4CAF50”
android:textSize=“18sp” />

    </LinearLayout>

    <LinearLayout

android:layout_width=“match_parent”
android:layout_height=“wrap_content”
android:layout_marginHorizontal=“20dp”
android:layout_marginVertical=“10dp”
android:gravity=“center”
android:orientation=“horizontal”>

        <TextView

android:id=“@+id/textView29”
android:layout_width=“wrap_content”
android:layout_height=“wrap_content”
android:layout_gravity=“center”
android:layout_weight=“1”
android:text=“序号”
android:textColor=“#111819”
android:textSize=“18sp” />

        <TextView

android:id=“@+id/textView26”
android:layout_width=“wrap_content”
android:layout_height=“wrap_content”
android:layout_weight=“1”
android:text=“日期”
android:textColor=“#111819”
android:textSize=“18sp” />

        <TextView

android:id=“@+id/textView25”
android:layout_width=“wrap_content”
android:layout_height=“wrap_content”
android:layout_weight=“1”
android:text=“类型”
android:textColor=“#111819”
android:textSize=“18sp” />

        <TextView

android:id=“@+id/textView27”
android:layout_width=“wrap_content”
android:layout_height=“wrap_content”
android:layout_weight=“1”
android:text=“金额”
android:textColor=“#111819”
android:textSize=“18sp” />

        <TextView

android:id=“@+id/textView28”
android:layout_width=“wrap_content”
android:layout_height=“wrap_content”
android:layout_weight=“1”
android:text=“说明”
android:textColor=“#111819”
android:textSize=“18sp” />

    </LinearLayout>

    <ImageView

android:layout_width=“380dp”
android:layout_height=“0.5dp”
android:background=“#D8D3D3”
android:paddingHorizontal=“20dp” />

    <ListView

android:id=“@+id/recordlistview”
android:layout_width=“wrap_content”
android:layout_height=“120dp”
android:layout_weight=“1”>

    <LinearLayout

android:layout_width=“match_parent”
android:layout_height=“wrap_content”
android:layout_marginHorizontal=“14dp”
android:orientation=“horizontal”>

        <TextView

android:id=“@+id/textView18”
android:layout_width=“wrap_content”
android:layout_height=“wrap_content”
android:text=“日期: "
android:textColor=”#101112"
android:textSize=“18sp” />

        <EditText

android:id=“@+id/edt_date”
android:layout_width=“wrap_content”
android:layout_height=“wrap_content”
android:layout_weight=“1”
android:ems=“10”
android:hint=“填写日期,如:202107表示2021年7月”
android:inputType=“textPersonName” />

    <LinearLayout

android:layout_width=“match_parent”
android:layout_height=“wrap_content”
android:layout_marginHorizontal=“14dp”
android:orientation=“horizontal”>

        <TextView

android:id=“@+id/textView21”
android:layout_width=“wrap_content”
android:layout_height=“wrap_content”
android:text=“类型: "
android:textColor=”#101112"
android:textSize=“18sp” />

        <EditText

android:id=“@+id/edt_type”
android:layout_width=“wrap_content”
android:layout_height=“wrap_content”
android:layout_weight=“1”
android:ems=“10”
android:hint=“类型为收入或支出”
android:inputType=“textPersonName” />

    <LinearLayout

android:layout_width=“match_parent”
android:layout_height=“wrap_content”
android:layout_marginHorizontal=“14dp”
android:orientation=“horizontal”>

        <TextView

android:id=“@+id/textView30”
android:layout_width=“wrap_content”
android:layout_height=“wrap_content”
android:text=“金额: "
android:textColor=”#101112"
android:textSize=“18sp” />

        <EditText

android:id=“@+id/edt_money”
android:layout_width=“wrap_content”
android:layout_height=“wrap_content”
android:layout_weight=“1”
android:ems=“10”
android:hint=“请输入金额”
android:inputType=“textPersonName” />

    <LinearLayout

android:layout_width=“match_parent”
android:layout_height=“wrap_content”
android:layout_marginHorizontal=“14dp”
android:orientation=“horizontal”>

        <TextView

android:id=“@+id/tv_state”
android:layout_width=“wrap_content”
android:layout_height=“wrap_content”
android:text=“说明: "
android:textColor=”#101112"
android:textSize=“18sp” />

        <EditText

android:id=“@+id/edt_state”
android:layout_width=“wrap_content”
android:layout_height=“wrap_content”
android:layout_weight=“1”
android:ems=“10”
android:hint=“阐述说明”
android:inputType=“textPersonName” />

    <LinearLayout

android:layout_width=“wrap_content”
android:layout_height=“wrap_content”
android:layout_marginVertical=“30dp”>

        <Button

android:id=“@+id/btn_add”
android:layout_width=“wrap_content”
android:layout_height=“wrap_content”
android:layout_marginHorizontal=“10dp”
android:layout_weight=“1”
android:text=“添加”
app:backgroundTint=“#78C6A3” />

        <Button

android:id=“@+id/btn_update”
android:layout_width=“wrap_content”
android:layout_height=“wrap_content”
android:layout_marginHorizontal=“10dp”
android:layout_weight=“1”
android:text=“修改”
app:backgroundTint=“#56AB91” />

        <Button

android:id=“@+id/btn_delete”
android:layout_width=“wrap_content”
android:layout_height=“wrap_content”
android:layout_marginHorizontal=“10dp”
android:layout_weight=“1”
android:text=“删除”
app:backgroundTint=“#358F80” />


</androidx.constraintlayout.widget.ConstraintLayout>


#### (6)列表数据记录record\_item\_layout.xml


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



<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android=“http://schemas.android.com/apk/res/android”
android:layout_width=“match_parent”
android:layout_height=“match_parent”>

<LinearLayout

android:layout_width=“match_parent”
android:layout_height=“match_parent”
android:orientation=“horizontal”
android:layout_marginHorizontal=“20dp”
android:gravity=“center_horizontal”
android:paddingVertical=“2dp”>

    <TextView

android:id=“@+id/list_id”
android:layout_width=“40dp”
android:layout_height=“24dp”
android:layout_weight=“1”
android:textSize=“18sp”
android:gravity=“center_horizontal” />

    <TextView

android:id=“@+id/list_date”
android:layout_width=“90dp”
android:layout_height=“24dp”
android:layout_weight=“1”
android:textSize=“18sp”
android:gravity=“center_horizontal” />

    <TextView

android:id=“@+id/list_type”
android:layout_width=“70dp”
android:layout_height=“24dp”
android:layout_weight=“1”
android:textSize=“18sp”
android:gravity=“center_horizontal” />

    <TextView

android:id=“@+id/list_money”
android:layout_width=“70dp”
android:layout_height=“24dp”
android:layout_weight=“1”
android:textSize=“18sp”
android:gravity=“center_horizontal” />

    <TextView

android:id=“@+id/list_state”
android:layout_width=“90dp”
android:layout_height=“24dp”
android:layout_weight=“1”
android:textSize=“18sp”
android:gravity=“center_horizontal” />

</LinearLayout>

### 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<User> 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<User> 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<Map<String, String>> list = new ArrayList<Map<String, String>>();
    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<String, String> map = new HashMap<String, String>();
            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<String> adapter = new
            ArrayAdapter<String>(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<String> adapter1 = new
            ArrayAdapter<String>(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<Map<String, String>> list = new ArrayList<Map<String, String>>();
    //用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<String, String> map = new HashMap<String, String>();
        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<User> CREATOR = new Creator<User>() {
    @Override
    public User createFromParcel(Parcel source) {
        return new User(source);
    }

    @Override
    public User[] newArray(int size) {
        return new User[size];
    }
};

}


## 🎵三、运行结果Result


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








## 📈四、结束语


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


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


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


## 🐣彩蛋 One More Thing


### (:不合理设计


* 年月份数据写的太固定了,没有可扩展性
* 日期应该用日期选择器来做,而不应该是以文本的形式
* 收入和支出应该以单选框来进行选择,而不应该是文本的形式
* ……


### (:番外篇



> 
> * 关注公众号**星期一研究室**,第一时间关注学习干货,**更多精选专栏待你解锁**~
> * 如果这篇文章对你有用,记得**留个脚印jio**再走哦~
> * 以上就是本文的全部内容!我们下期见!👋👋👋
> 
> 
> 


**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**

**需要这份系统化的资料的朋友,可以添加V获取:vip204888 (备注大数据)**
![img](https://img-blog.csdnimg.cn/img_convert/658d4040a4fccfb474825bb350bb076b.png)

**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**

wd);
    }

    public User() {
    }

    protected User(Parcel in) {
        this.userId = in.readString();
        this.userPwd = in.readString();
    }

    public static final Creator<User> CREATOR = new Creator<User>() {
        @Override
        public User createFromParcel(Parcel source) {
            return new User(source);
        }

        @Override
        public User[] newArray(int size) {
            return new User[size];
        }
    };
}

🎵三、运行结果Result

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

📈四、结束语

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

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

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

🐣彩蛋 One More Thing

(:不合理设计

  • 年月份数据写的太固定了,没有可扩展性
  • 日期应该用日期选择器来做,而不应该是以文本的形式
  • 收入和支出应该以单选框来进行选择,而不应该是文本的形式
  • ……

(:番外篇

  • 关注公众号星期一研究室,第一时间关注学习干货,更多精选专栏待你解锁~
  • 如果这篇文章对你有用,记得留个脚印jio再走哦~
  • 以上就是本文的全部内容!我们下期见!👋👋👋

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip204888 (备注大数据)
[外链图片转存中…(img-KJhAUrLr-1713686932926)]

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 25
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
要使用Android Studio来制作一个手把手记账App,你可以按照以下步骤进行操作。 1. 下载和安装Android Studio:你可以从官方网站https://developer.android.com/studio下载Android Studio的最新版本。安装步骤可以参考官方文档或者提供的下载链接。 2. 创建新项目:打开Android Studio后,选择“Start a new Android Studio project”,然后按照向导的步骤输入项目名称和其他必要信息,如应用程序的最低支持版本和包名。 3. 设计用户界面:使用Android Studio的布局编辑器来设计你的记账App的用户界面。你可以使用各种布局组件,如LinearLayout、RelativeLayout和ConstraintLayout来构建你的界面。可以通过拖拽和放置组件的方式来创建你的界面。你可以参考提供的Android工具网站来查找一些辅助设计的工具。 4. 添加功能:在你的记账App中添加必要的功能,如录入收入和支出、显示收支明细、生成报表等。你可以使用Java或Kotlin来编写这些功能的代码。Android Studio提供了强大的代码编辑器和调试工具来帮助你完成这些任务。 5. 测试和调试:使用Android Studio的模拟器或将你的Android设备连接到计算机上进行测试和调试。你可以使用Android Studio内置的调试工具来检查代码中的错误和问题,并进行修复。 6. 构建和发布:完成开发和测试后,你可以使用Android Studio的构建功能来构建你的应用程序的APK文件。你可以将APK文件上传到Google Play商店或其他应用分发平台,以便用户下载和安装。 总结:使用Android Studio来制作一个手把手记账App,你需要下载和安装Android Studio,创建新项目,设计用户界面,添加功能,测试和调试,最后进行构建和发布。这个过程需要一些编程知识和经验,但是使用Android Studio的工具和功能可以帮助你更容易地完成这些任务。参考提供的Android Studio相关信息,你可以更好地理解和应用这些步骤。<span class="em">1</span><span class="em">2</span><span class="em">3</span><span class="em">4</span>
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值