小工具知识网

当前位置: 首页 > 行业知识 > Android Studio 实现小熊记账本 (功能多,简单)

行业知识

Android Studio 实现小熊记账本 (功能多,简单)

2026-10-31 18:57:57 来源:互联网转载

一、高质量源码(非开源,白嫖低价勿扰)

关注公众号:《编程乐学》

后台回复:24010601

目录

前言

一、运行演示

二、开发环境

三、完成步骤

步骤 1:创建项目

步骤 2:创建包名

步骤 3:实现启动页

步骤 5:实现用户注册

步骤 6:实现用户登录

步骤 7:实现主页面编写

步骤 8:记账页面编写

步骤 9:历史记录页面编写

步骤10:我的页面的编写

步骤11:账单搜索页面的编写

步骤12:统计页面的编写

四、获取源码


前言

       本次实现的Android Studio 小熊记账本 (功能多,简单)项目,核心功能是可以记录收支情况,可以给收支选择各种分类选项,比如“餐饮”、“零食”、“购物”等等,还可以添加备注和修改日期。然后会在首页展示你的本月支持和收入信息,还可以选择隐藏信息保护隐私。通过【账单记录】可以查看自己的所有账单记录,通过【账单详情】可以看到用柱状图显示的账单情况,在设置里面可以清空所有数据,长按可以删除单条数据,功能非常全面丰富。


一、运行演示

我们先来看下运行演示效果

Android Studio 实现小熊记账本App

二、开发环境

        我的开发环境如下,大家的AS版本不需要和我相同,只要是近两年从官网下载的版本,都是比4.0.0 (2020)高的,是可以满足运行和开发要求的。

三、完成步骤

步骤 1:创建项目

        打开 Android studio 开发工具后,进行项目创建,左上角 File—>New Project、填写后点击 Finish 完成创建!

步骤 2:创建包名

        选中com.example.note包 名 右 键 New — >package 并按需求依次 activity(存放各类 Activity)、adapter(存放各类适配器) 等包名,后续代码将按对应包名去创建,并将 MainActivity.java 移动到 activity包 下

步骤 3:实现启动页

        在 activity包上右键创建 New—>Activity—>Empty Activity 选项创建 Activity 后弹 出对话框,输入相关信息,即可创建 Activity.

启动页页面布局背景放置一张自己喜欢的logo即可

这里我们直接看java部分代码:

package com.example.tallybook.Activity;import android.content.Intent;import android.os.Bundle;import android.os.CountDownTimer;import android.os.Handler;import androidx.appcompat.app.AppCompatActivity;import com.example.tallybook.R;public class StartActivity extends AppCompatActivity {    private Handler handler = new Handler();    private Runnable runnable = new Runnable() {        @Override        public void run() {            tomainActive();        }    };    // 进入主页面    private void tomainActive() {        startActivity(new Intent(this, LoginActivity.class));        // 跳转完成后注销        finish();    }    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_start);          }   }

步骤 5:实现用户注册

        在 activity包上右键创建 New—>Activity—>Empty Activity 选项创建 Activity 后弹 出对话框,输入相关信息,即可创建 Activity.

用户注册页面布局代码如下所示:

                                                    

编写 RegisterActivity.java 的代码为:

package com.example.tallybook.Activity;import android.content.Intent;import android.os.Bundle;import android.view.View;import android.widget.Button;import android.widget.EditText;import android.widget.TextView;import android.widget.Toast;import androidx.appcompat.app.AppCompatActivity;import com.example.tallybook.Data.DatabaseHelper;import com.example.tallybook.R;public class RegisterActivity extends AppCompatActivity {    private EditText mUserNameEditText;    private EditText mPasswordEditText,mRePasswordEditText;    private TextView tvLogin;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_register);        mUserNameEditText = findViewById(R.id.username_edittext);        mPasswordEditText = findViewById(R.id.password_edittext);        mRePasswordEditText = findViewById(R.id.repassword_edittext);        tvLogin = findViewById(R.id.tv_login);              // 跳转登陆页面        tvLogin.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                Intent intent = new Intent(RegisterActivity.this, LoginActivity.class);                startActivity(intent);                finish();            }        });        Button registerButton = findViewById(R.id.register_button);        registerButton.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                // 获取输入的账号密码                String username = mUserNameEditText.getText().toString().trim();                String password = mPasswordEditText.getText().toString().trim();                String repassword = mRePasswordEditText.getText().toString().trim();                if (username.isEmpty() || password.isEmpty()) {                    Toast.makeText(getApplicationContext(), "请输入账号或密码", Toast.LENGTH_SHORT).show();                    return;                }                if (!password.equals(repassword)) {                    Toast.makeText(getApplicationContext(), "密码不一致,请重新输入", Toast.LENGTH_SHORT).show();                    return;                }                boolean result = mDatabaseHelper.insertData(username, password);                if (result) {                    Toast.makeText(getApplicationContext(), "注册成功", Toast.LENGTH_SHORT).show();                    Intent intent = new Intent(RegisterActivity.this, LoginActivity.class);                    startActivity(intent);                    finish();                } else {                    Toast.makeText(getApplicationContext(), "注册失败", Toast.LENGTH_SHORT).show();                }            }        });    }}

步骤 6:实现用户登录

        在 activity包上右键创建 New—>Activity—>Empty Activity 选项的对话框下输入 LoginActivity 创建,同时会在 res-layout 生成 activity_login.xml 文件.

activity_login.xml页面代码如下所示L:

                                                                            

对应的Java页面代码如下所示:

package com.example.tallybook.Activity;import android.content.Intent;import android.os.Bundle;import android.view.View;import android.widget.Button;import android.widget.EditText;import android.widget.TextView;import android.widget.Toast;import androidx.appcompat.app.AppCompatActivity;import com.example.tallybook.Data.DatabaseHelper;import com.example.tallybook.R;public class LoginActivity extends AppCompatActivity {    private EditText mUserNameEditText;    private EditText mPasswordEditText;    private Button mLoginButton;    private TextView rEgisterButton;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_login);        mUserNameEditText = findViewById(R.id.username_edittext);        mPasswordEditText = findViewById(R.id.password_edittext);        mLoginButton = findViewById(R.id.login_button);        rEgisterButton = findViewById(R.id.register_button);            // 跳转注册页面        rEgisterButton.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                Intent intent = new Intent(LoginActivity.this, RegisterActivity.class);                startActivity(intent);                finish();            }        });        // 登陆验证并跳转主页面        mLoginButton.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                // 获取输入的账号密码                String username = mUserNameEditText.getText().toString().trim();                String password = mPasswordEditText.getText().toString().trim();                if (username.isEmpty() || password.isEmpty()) {                    Toast.makeText(getApplicationContext(), "请输入账号或密码", Toast.LENGTH_SHORT).show();                    return;                }                boolean result = mDatabaseHelper.checkUser(username, password);                if (result) {                    Toast.makeText(getApplicationContext(), "登陆成功", Toast.LENGTH_SHORT).show();                    Intent intent = new Intent(LoginActivity.this, MainActivity.class);                    startActivity(intent);                    finish();                } else {                    Toast.makeText(getApplicationContext(), "账号或密码错误", Toast.LENGTH_SHORT).show();                }            }        });    }}

       

        编译代码启动 App,在登录页面(LoginActivity)的注册按钮中点击跳转注册 页面(RegisterActivity)进行注册,注册成功后自动返回登录页面进行登录 操作,登录成功之后正常跳转主页面(MainActivity)。

步骤 7:实现主页面编写

        我们先来看activity_main.xml代码,详情布局代码如下所示:

                                                                                                                                                

        接下来我们看逻辑代码,这里我们实现的是页面跳转功能,详情代码如下所示:

package com.example.tallybook.Activity;import android.graphics.Color;import android.os.Bundle;import android.view.View;import android.widget.FrameLayout;import android.widget.ImageView;import android.widget.TextView;import androidx.appcompat.app.AppCompatActivity;import com.example.tallybook.R;public class MainActivity extends AppCompatActivity {    private ImageView imgHome;    private ImageView imgRecords;    private ImageView imgBill;    private ImageView imgMine;    private TextView tvHome;    private TextView tvRecords;    private TextView tvBill;    private TextView tvMine;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        initView();        Navigation();        imgHome.callOnClick();//进入页面默认点击首页    }    // 点击控件进行页面转换    private void Navigation() {        // 首页        imgHome.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                                         }        });        // 记账页面        imgRecords.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                                          }        });        // 历史账单页面        imgBill.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                                      }        });        // 我的页面        imgMine.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                                      }        });    }     }    private void initView() {        imgHome = findViewById(R.id.img_home);        imgRecords = findViewById(R.id.img_records);        imgBill = findViewById(R.id.img_bill);        imgMine = findViewById(R.id.img_mine);        tvHome = findViewById(R.id.tv_home);        tvRecords = findViewById(R.id.tv_records);        tvBill = findViewById(R.id.tv_bill);        tvMine = findViewById(R.id.tv_mine);    }}

步骤 8:记账页面编写

        我们先来看布局代码,这里我们用到了ViewPAge列表来显示,详情代码如下所示:

                    

然后我们进行逻辑代码的编写,实现显示添加支出收入记录功能

package com.example.tallybook.Fragment;import android.os.Bundle;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import androidx.annotation.NonNull;import androidx.annotation.Nullable;import androidx.fragment.app.Fragment;import androidx.viewpager.widget.ViewPager;import com.example.tallybook.Adapter.RecordPagerAdapter;import com.google.android.material.tabs.TabLayout;import com.example.tallybook.R;import java.util.ArrayList;import java.util.List;public class RecordsFragment extends Fragment {    private TabLayout tabLayout;    private ViewPager viewPager;    @Nullable    @Override    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {        // Inflate the layout for this fragment        View view = inflater.inflate(R.layout.fragment_records, container, false);        //1.查找控件        tabLayout = view.findViewById(R.id.record_tabs);        viewPager = view.findViewById(R.id.record_vp);        //2.设置ViewPager加载页面        initPager();        return view;    }    private void initPager() {//        创建适配器        RecordPagerAdapter pagerAdapter = new RecordPagerAdapter(getChildFragmentManager(), fragmentList);//        设置适配器        viewPager.setAdapter(pagerAdapter);        //将TabLayout和ViwePager进行关联        tabLayout.setupWithViewPager(viewPager);    }}

步骤 9:历史记录页面编写

        这里直使用listview列表显示内容:

                                            

然后对应的逻辑代码如下所示:

package com.example.tallybook.Fragment;import android.app.AlertDialog;import android.content.DialogInterface;import android.os.Bundle;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.AdapterView;import android.widget.ImageView;import android.widget.ListView;import android.widget.TextView;import com.example.tallybook.R;import androidx.annotation.NonNull;import androidx.annotation.Nullable;import androidx.fragment.app.Fragment;import com.example.tallybook.Adapter.AccountAdapter;import com.example.tallybook.Bean.AccountBean;import com.example.tallybook.Data.DBManager;import com.example.tallybook.utils.CalendarDialog;import java.util.ArrayList;import java.util.Calendar;import java.util.List;public class BillFragment extends Fragment {    ListView historyLv;    TextView timeTv;private ImageView riliIv;    List mDatas;    AccountAdapter adapter;    int year, month;    int dialogSelPos = -1;    int dialogSelMonth = -1;    @Nullable    @Override    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {        View view = inflater.inflate(R.layout.fragment_bill, container, false);        historyLv = view.findViewById(R.id.history_lv);        timeTv = view.findViewById(R.id.history_tv_time);        riliIv = view.findViewById(R.id.history_iv_rili);              mDatas = new ArrayList();        // 设置适配器        adapter = new AccountAdapter(getActivity(), mDatas);        historyLv.setAdapter(adapter);        initTime();        timeTv.setText(year + "年" + month + "月");        loadData(year, month);        setLVClickListener();        return view;    }    /*设置ListView每一个item的长按事件*/    private void setLVClickListener() {        historyLv.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {            @Override            public boolean onItemLongClick(AdapterView parent, View view, int position, long id) {                AccountBean accountBean = mDatas.get(position);                deleteItem(accountBean);                return false;            }        });    }      /* 获取指定年份月份收支情况的列表*/    private void loadData(int year, int month) {        List list = DBManager.getAccountListOneMonthFromAccounttb(year, month);        mDatas.clear();        mDatas.addAll(list);        adapter.notifyDataSetChanged();    }    private void initTime() {        Calendar calendar = Calendar.getInstance();        year = calendar.get(Calendar.YEAR);        month = calendar.get(Calendar.MONTH) + 1;    }}

步骤10:我的页面的编写

       页面布局代码如下所示:

                                                                                                                                                                                                                            

       

         MineFragment是一个用于显示用户个人信息和提供个人设置功能的Android Fragment类。它包含了清空账单、搜索账单、账单统计、设置预算、修改密码和退出软件等功能。

        通过点击不同的按钮,用户可以执行相应的操作,例如删除所有记录、跳转到搜索账单界面、跳转到账单统计界面、设置预算金额、修改密码和退出软件。此外,MineFragment还使用了DatabaseHelper类和SharedPreferences类来进行数据库操作和存储预算金额。

package com.example.tallybook.Fragment;import android.app.AlertDialog;import android.content.Context;import android.content.DialogInterface;import android.content.Intent;import android.content.SharedPreferences;import android.os.Bundle;import android.text.TextUtils;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.EditText;import android.widget.LinearLayout;import android.widget.Toast;import androidx.fragment.app.Fragment;import com.example.tallybook.Activity.LoginActivity;import com.example.tallybook.Activity.SearchActivity;import com.example.tallybook.Activity.StatisticsActivity;import com.example.tallybook.Data.DBManager;import com.example.tallybook.Data.DatabaseHelper;import com.example.tallybook.R;import com.example.tallybook.utils.BudgetDialog;public class MineFragment extends Fragment {    private LinearLayout llEdit, llChangePassword, llStatistics, llClear, llSs, llBudget;    private DatabaseHelper mDatabaseHelper;    SharedPreferences preferences;    int year,month,day;    @Override    public View onCreateView(LayoutInflater inflater, ViewGroup container,                             Bundle savedInstanceState) {        View view = inflater.inflate(R.layout.fragment_mine, container, false);        initView(view);        clear();        ss();        statistics();        budget();        changePassword();        edit();        mDatabaseHelper = new DatabaseHelper(getContext());        preferences = getActivity().getSharedPreferences("budget", Context.MODE_PRIVATE);        return view;    }    // 清空账单    private void clear() {        llClear.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                AlertDialog.Builder builder = new AlertDialog.Builder(getContext());                builder.setTitle("清空提示:")                        .setMessage("您确定要删除所有记录么?\n* 删除后无法恢复,请慎重选择!")                        .setPositiveButton("取消", null)                        .setNegativeButton("确定", new DialogInterface.OnClickListener() {                            @Override                            public void onClick(DialogInterface dialog, int which) {                                DBManager.deleteAllAccount();                                preferences.edit().clear().apply();                                Toast.makeText(getActivity(), "删除成功!", Toast.LENGTH_SHORT).show();                            }                        });                builder.create().show();            }        });    }    // 搜索账单    private void ss() {        llSs.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                Intent it = new Intent(getActivity(), SearchActivity.class);  //跳转界面                startActivity(it);            }        });    }    // 账单统计    private void statistics() {        llStatistics.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                Intent intent = new Intent(getActivity(), StatisticsActivity.class);                startActivity(intent);            }        });    }      private void initView(View view) {        llClear = view.findViewById(R.id.ll_clear);        llStatistics = view.findViewById(R.id.ll_statistics);        llChangePassword = view.findViewById(R.id.ll_changePassword);        llEdit = view.findViewById(R.id.ll_edit);        llSs = view.findViewById(R.id.ll_ss);        llBudget = view.findViewById(R.id.ll_budget);    }}

步骤11:账单搜索页面的编写

         这个页面比较简单,使用listview列表和数据库查询显示完成,我们先来看布局文件代码

                                        

        通过用户输入关键词进行搜索,并将搜索结果显示在ListView中。该类使用了DBManager类来进行数据库操作,并使用了AccountAdapter类来显示搜索结果。通过点击不同的按钮,用户可以执行返回和搜索操作。

package com.example.tallybook.Activity;import android.os.Bundle;import android.text.TextUtils;import android.view.View;import android.widget.EditText;import android.widget.ListView;import android.widget.TextView;import android.widget.Toast;import androidx.appcompat.app.AppCompatActivity;import com.example.tallybook.Adapter.AccountAdapter;import com.example.tallybook.Bean.AccountBean;import com.example.tallybook.Data.DBManager;import com.example.tallybook.R;import java.util.ArrayList;import java.util.List;public class SearchActivity extends AppCompatActivity {    ListView searchLv;    EditText searchEt;    TextView emptyTv;    List mDatas;   //数据源    AccountAdapter adapter;    //适配器对象    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_search);        initView();        searchLv.setEmptyView(emptyTv);   //设置无数局时,显示的控件    }    private void initView() {        searchEt = findViewById(R.id.search_et);        searchLv = findViewById(R.id.search_lv);        emptyTv = findViewById(R.id.search_tv_empty);    }}

步骤12:统计页面的编写

这里我们还是先进行页面布局对的编写

                                                            

        该活动包含了收入和支出的按钮、日期显示、统计数据显示以及ViewPager等控件。通过点击不同的按钮,用户可以切换显示收入或支出的统计数据。该活动还包含了初始化控件、初始化时间、初始化Fragment、统计数据的初始化和显示、返回按钮的点击事件、显示日历对话框等方法。通过使用DBManager类进行数据库操作,获取收入和支出的统计数据,并使用ChartVPAdapter适配器类将Fragment添加到ViewPager中进行显示。用户可以通过点击日历图标选择不同的日期进行统计。

package com.example.tallybook.Activity;import androidx.appcompat.app.AppCompatActivity;import androidx.fragment.app.Fragment;import androidx.viewpager.widget.ViewPager;import android.graphics.Color;import android.os.Bundle;import android.view.View;import android.widget.Button;import android.widget.ImageView;import android.widget.TextView;import com.example.tallybook.Adapter.ChartVPAdapter;import com.example.tallybook.Data.DBManager;import com.example.tallybook.Fragment.IncomChartFragment;import com.example.tallybook.Fragment.OutcomChartFragment;import com.example.tallybook.R;import com.example.tallybook.utils.CalendarDialog;import java.util.ArrayList;import java.util.Calendar;import java.util.List;public class StatisticsActivity extends AppCompatActivity {    Button inBtn, outBtn;    TextView dateTv, inTv, outTv;    ViewPager chartVp;    int year;    int month;    int selectPos = -1, selectMonth = -1;    List chartFragList;    private IncomChartFragment incomChartFragment;    private OutcomChartFragment outcomChartFragment;    private ChartVPAdapter chartVPAdapter;    private ImageView chartIV, chartBack;    private float inMoneyOneMonth, outMoneyOneMonth;    private int incountItemOneMonth, outcountItemOneMonth;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_statistics);        initView();        initTime();         }    // 显示日历    private void rili() {        chartIV.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                showCalendarDialog();            }        });    }    // 返回    private void back() {        chartBack.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                finish();            }        });    }    private void setVPSelectListener() {        chartVp.addOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {            @Override            public void onPageSelected(int position) {                setButtonStyle(position);            }        });    }    /* 统计某年某月的收支情况数据*/    private void initStatistics(int year, int month) {        inMoneyOneMonth = DBManager.getSumMoneyOneMonth(year, month, 1);  //收入总钱数        outMoneyOneMonth = DBManager.getSumMoneyOneMonth(year, month, 0); //支出总钱数        incountItemOneMonth = DBManager.getCountItemOneMonth(year, month, 1);  //收入多少笔        outcountItemOneMonth = DBManager.getCountItemOneMonth(year, month, 0); //支出多少笔        dateTv.setText(year + "年" + month + "月账单统计");        // 收入        inBtn.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                setButtonStyle(1);                chartVp.setCurrentItem(1);                outTv.setText("共收入" + incountItemOneMonth + "笔,合计");                inTv.setText(String.valueOf(inMoneyOneMonth));            }        });        // 支出        outBtn.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                setButtonStyle(0);                chartVp.setCurrentItem(0);                outTv.setText("共支出" + outcountItemOneMonth + "笔支出,合计");                inTv.setText(String.valueOf(outMoneyOneMonth));            }        });    }    /**     * 初始化时间的方法     */    private void initTime() {        Calendar calendar = Calendar.getInstance();        year = calendar.get(Calendar.YEAR);        month = calendar.get(Calendar.MONTH) + 1;    }    /**     * 初始化控件     */    private void initView() {        inBtn = findViewById(R.id.chart_btn_in);        outBtn = findViewById(R.id.chart_btn_out);        dateTv = findViewById(R.id.chart_tv_date);        inTv = findViewById(R.id.chart_tv_in);        outTv = findViewById(R.id.chart_tv_out);        chartVp = findViewById(R.id.chart_vp);        chartIV = findViewById(R.id.chart_iv_rili);        chartBack = findViewById(R.id.chart_iv_back);    }    /* 设置按钮样式的改变  支出-0  收入-1*/    private void setButtonStyle(int kind) {        if (kind == 0) {            outBtn.setBackgroundResource(R.drawable.main_recordbtn_bg);            outBtn.setTextColor(Color.WHITE);            inBtn.setBackgroundResource(R.drawable.dialog_btn_bg);            inBtn.setTextColor(Color.BLACK);        } else if (kind == 1) {            inBtn.setBackgroundResource(R.drawable.main_recordbtn_bg);            inBtn.setTextColor(Color.WHITE);            outBtn.setBackgroundResource(R.drawable.dialog_btn_bg);            outBtn.setTextColor(Color.BLACK);        }    }}

         至此,完整的小熊记账本项目就创建完成了。

四、获取源码

关注公众号《编程乐学》,后台回复:24010601

快捷获取方式

上一篇:vue中websocket的使用---详解

下一篇:Swoole入门秘籍,解锁高效网络通信的力量之源