Android安卓实战项目(13)—记账APP详细记录每天的收入和支出并且分类统计【生活助手类APP】强烈推荐自己也在用!!!(源码在文末)【可用于安卓毕设或安卓课设作业】

一.项目运行介绍

B站视频链接: 【Android安卓实战项目(13)—记账APP详细记录每天的收入和支出并且分类统计【生活助手类APP】强烈推荐自己也在用!!!(源码在文末)】 https://www.bilibili.com/video/BV1tH4y1Q7kX/?share_source=copy_web&vd_source=b2e9b9ed746acda34f499009647748ed

1.开机动画

2.主页面展示

3.支出记录页面展示

4.收入记录页面展示

5.总交易流程展示

6.显示余额

7.添加备注

二.具体实现

1.MainActivity.java

package com.yuukidach.ucount;

import android.content.DialogInterface;

import android.content.Intent;

import android.content.res.Resources;

import android.net.Uri;

import androidx.drawerlayout.widget.DrawerLayout;

import androidx.appcompat.app.AlertDialog;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;

import androidx.recyclerview.widget.DividerItemDecoration;

import androidx.recyclerview.widget.LinearLayoutManager;

import androidx.recyclerview.widget.RecyclerView;

import androidx.recyclerview.widget.ItemTouchHelper;

import android.util.Log;

import android.view.View;

import android.widget.Button;

import android.widget.EditText;

import android.widget.ImageButton;

import android.widget.ImageView;

import android.widget.LinearLayout;

import android.widget.TextView;

import android.widget.Toast;

import com.yuukidach.ucount.view.adapter.BookItemAdapter;

import com.yuukidach.ucount.view.adapter.MoneyItemAdapter;

import com.yuukidach.ucount.callback.BookItemCallback;

import com.yuukidach.ucount.callback.MainItemCallback;

import com.yuukidach.ucount.model.BookItem;

import com.yuukidach.ucount.model.ImgUtils;

import com.yuukidach.ucount.model.MoneyItem;

import com.yuukidach.ucount.presenter.MainPresenter;

import com.yuukidach.ucount.view.MainView;

import java.text.DecimalFormat;

import java.util.List;

import at.markushi.ui.CircleButton;

public class MainActivity extends AppCompatActivity implements MainView {

private final ImgUtils imgUtils = new ImgUtils(this);

private final MainPresenter mainPresenter = new MainPresenter(this, imgUtils);

private Button showBtn;

private ImageButton statsBtn;

private TextView monthlyCost;

private TextView monthlyEarn;

private ImageView headerImg;

private RecyclerView MoneyItemRecyclerView;

// parameter for drawer

private DrawerLayout drawerLayout;

private LinearLayout bookLinearLayout;

private RecyclerView bookItemRecyclerView;

private ImageView drawerBanner;

public static String PACKAGE_NAME;

public static Resources resources;

public DecimalFormat decimalFormat = new DecimalFormat("0.00");

private static final String TAG = "MainActivity";

@Override

protected void onCreate(Bundle savedInstanceState) {

setTheme(R.style.AppTheme);

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

// 获得包名和资源,方便后面的程序使用

PACKAGE_NAME = getApplicationContext().getPackageName();

resources = getResources();

showBtn = (Button) findViewById(R.id.show_money_button);

statsBtn = (ImageButton) findViewById(R.id.stats_button);

monthlyCost = (TextView) findViewById(R.id.monthly_cost_money);

monthlyEarn = (TextView) findViewById(R.id.monthly_earn_money);

headerImg = (ImageView) findViewById(R.id.header_img);

CircleButton addBtn = (CircleButton) findViewById(R.id.add_button);

ImageButton addBookButton = (ImageButton) findViewById(R.id.add_book_button);

MoneyItemRecyclerView = (RecyclerView) findViewById(R.id.in_and_out_items);

// drawer

drawerLayout = (DrawerLayout) findViewById(R.id.drawer_of_books);

bookItemRecyclerView = (RecyclerView) findViewById(R.id.book_list);

bookLinearLayout = (LinearLayout) findViewById(R.id.left_drawer);

drawerBanner = (ImageView) findViewById(R.id.drawer_banner);

showBtn.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

String str = showBtn.getText().toString();

mainPresenter.onShowBalanceClick(str);

}

});

// start activity to add cost or earning item

addBtn.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

navigateToAddItem();

}

});

// start activity to statistics

statsBtn.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

navigateToStatistics();

}

});

addBookButton.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

mainPresenter.onAddBookClick();

}

});

// 设置首页header图片长按以更换图片

headerImg.setOnLongClickListener(new View.OnLongClickListener() {

@Override

public boolean onLongClick(View v) {

mainPresenter.onImageLongClick(ImageType.HEADER);

return false;

}

});

drawerBanner.setOnLongClickListener(new View.OnLongClickListener() {

@Override

public boolean onLongClick(View v) {

mainPresenter.onImageLongClick(ImageType.DRAWER);

return false;

}

});

}

@Override

protected void onResume() {

super.onResume();

mainPresenter.onResume();

}

@Override

public void onBackPressed() {

Intent intent = new Intent(Intent.ACTION_MAIN); // ACTION_MAIN 作为Task中第一个Activity启动

intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

intent.addCategory(Intent.CATEGORY_HOME); // CATEGORY_HOME 设备启动时的第一个Activity

startActivity(intent);

}

@Override

protected void onActivityResult(int requestCode, int resultCode, Intent data) {

super.onActivityResult(requestCode, resultCode, data);

if (data == null) return;

Uri uri = data.getData();

mainPresenter.onActivityResult(uri, requestCode);

// get permanent permission to access the image

int takeFlags = data.getFlags()

& (Intent.FLAG_GRANT_READ_URI_PERMISSION

| Intent.FLAG_GRANT_WRITE_URI_PERMISSION);

getContentResolver().takePersistableUriPermission(uri, takeFlags);

}

@Override

public void openPicGallery(ImageType type) {

Log.d(TAG, "openPicGallery: " + type.ordinal());

Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);

intent.setType("image/*");

startActivityForResult(intent, type.ordinal());

}

@Override

public void updateHeaderImg(String uriStr) {

// If there is no picture in SharedPreferences, then use default picture

if (uriStr.isEmpty()) return;

Uri uri = Uri.parse(uriStr);

this.headerImg.setImageURI(uri);

}

@Override

public void updateDrawerImg(String uriStr) {

// If there is no picture in SharedPreferences, then use default picture

if (uriStr.isEmpty()) return;

Uri uri = Uri.parse(uriStr);

this.drawerBanner.setImageURI(uri);

}

@Override

public void showBalance(String numStr) {

showBtn.setText(numStr);

}

@Override

public void hideBalance() {

showBtn.setText(R.string.show_balance);

}

@Override

public void updateMonthlyEarn(String numStr) {

monthlyEarn.setText(numStr);

}

@Override

public void updateMonthlyCost(String numStr) {

monthlyCost.setText(numStr);

}

@Override

public void navigateToAddItem() {

Intent intent = new Intent(MainActivity.this, AddItemActivity.class);

Bundle bundle = new Bundle();

// tell addItemActivity which book is on

bundle.putInt("bookId", mainPresenter.getCurBookId());

intent.putExtras(bundle);

startActivity(intent);

}

@Override

public void setMainItemRecycler(List list) {

LinearLayoutManager layoutManager = new LinearLayoutManager(this);

layoutManager.setStackFromEnd(true); // show from bottom to top

layoutManager.setReverseLayout(true); // reverse the layout

MoneyItemAdapter moneyItemAdapter = new MoneyItemAdapter(mainPresenter, list);

MoneyItemRecyclerView.setAdapter(moneyItemAdapter);

MoneyItemRecyclerView.setLayoutManager(layoutManager);

ItemTouchHelper ioTouchHelper = new ItemTouchHelper(

new MainItemCallback(this, MoneyItemRecyclerView, moneyItemAdapter)

);

ioTouchHelper.attachToRecyclerView(MoneyItemRecyclerView);

}

@Override

public void setBookItemRecycler(List list) {

LinearLayoutManager layoutManager = new LinearLayoutManager(this);

bookItemRecyclerView.setLayoutManager(layoutManager);

bookItemRecyclerView.addItemDecoration(

new DividerItemDecoration(this, DividerItemDecoration.VERTICAL)

);

BookItemAdapter bookAdapter = new BookItemAdapter(mainPresenter);

bookAdapter.setOnItemClickListener(new BookItemAdapter.OnItemClickListener() {

@Override

public void onItemClick(View view, int position) {

mainPresenter.updateBookItemView(position);

drawerLayout.closeDrawer(bookLinearLayout);

onResume();

}

});

bookItemRecyclerView.setAdapter(bookAdapter);

ItemTouchHelper bookTouchHelper = new ItemTouchHelper(

new BookItemCallback(this, bookItemRecyclerView, bookAdapter)

);

bookTouchHelper.attachToRecyclerView(bookItemRecyclerView);

}

@Override

public void setNewBook() {

final EditText book_title = new EditText(MainActivity.this);

// 弹窗输入

AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);

builder.setMessage(R.string.new_book_prompt);

builder.setView(book_title);

builder.setPositiveButton(R.string.confirm, new DialogInterface.OnClickListener() {

@Override

public void onClick(DialogInterface dialog, int which) {

if (!book_title.getText().toString().isEmpty()) {

mainPresenter.onAddBookConfirmClick(book_title.getText().toString());

onResume();

} else {

// TODO: use strings.xml

Toast.makeText(getApplicationContext(), "没有输入新账本名称哦", Toast.LENGTH_SHORT).show();

}

}

}).setNegativeButton(R.string.cancle, new DialogInterface.OnClickListener() {

@Override

public void onClick(DialogInterface dialog, int which) {

}

}).show();

}

@Override

public void navigateToStatistics() {

Intent intent = new Intent(MainActivity.this, StatisticsActivity.class);

Bundle bundle = new Bundle();

// tell StatisticsActivity which book is on

bundle.putInt("bookId", mainPresenter.getCurBookId());

intent.putExtras(bundle);

startActivity(intent);

}

}

onCreate 方法: 这是活动的主要入口点,在活动创建时调用。在这里,活动的布局文件被加载,界面上的视图元素被初始化,并设置了各种点击事件的监听器。

setTheme(R.style.AppTheme):设置活动的主题样式。setContentView(R.layout.activity_main):加载布局文件以显示界面。初始化各个视图元素,如 showBtn、statsBtn、monthlyCost 等。 按钮点击事件:

showBtn.setOnClickListener:设置 “显示余额” 按钮的点击事件监听器。点击按钮会触发 onShowBalanceClick 方法,该方法会调用 mainPresenter 的相应方法来处理逻辑。addBtn.setOnClickListener:设置 “添加” 按钮的点击事件监听器。点击按钮会打开一个新的界面以添加记账项。statsBtn.setOnClickListener:设置 “统计” 按钮的点击事件监听器。点击按钮会打开一个统计界面。 图片长按事件:

headerImg.setOnLongClickListener:设置头部图片的长按事件监听器。长按图片会触发更换图片的操作。drawerBanner.setOnLongClickListener:设置侧边栏图片的长按事件监听器。长按图片会触发更换侧边栏图片的操作。 onResume 方法: 当活动从暂停状态恢复时(例如从后台返回前台),onResume 方法会被调用。在这里,调用了 mainPresenter.onResume(),用于处理活动的恢复逻辑。 onBackPressed 方法: 当用户按下后退按钮时,该方法会被调用。在这里,创建一个意图以返回到设备的主屏幕。 onActivityResult 方法: 当从其他活动返回结果时,onActivityResult 方法会被调用。在这里,根据返回的数据,调用了 mainPresenter 的相应方法来处理图片操作。 openPicGallery 方法: 用于打开图片库以选择图片。 图片更新方法:

updateHeaderImg:用于更新头部图片。updateDrawerImg:用于更新侧边栏图片。 showBalance 和 hideBalance 方法: 用于显示和隐藏余额。 余额和统计信息更新方法:

updateMonthlyEarn:用于更新每月收入信息。updateMonthlyCost:用于更新每月支出信息。 导航方法:

navigateToAddItem:用于导航到添加记账项的界面。navigateToStatistics:用于导航到统计界面。 setMainItemRecycler 和 setBookItemRecycler 方法: 用于设置记账项列表和账本列表的适配器和布局管理器。 setNewBook 方法: 弹出对话框,允许用户输入新的账本名称,并在确认后创建一个新账本。

以上是对主要部分的详细解释,这段代码涵盖了Android应用程序中常见的UI交互和逻辑处理。它包含了处理点击事件、图片操作、界面导航以及适配器和布局管理器的使用等内容。

2.AddItemActivity.java

package com.yuukidach.ucount;

import android.content.Intent;

import android.graphics.Typeface;

import android.os.Bundle;

import androidx.fragment.app.FragmentManager;

import androidx.fragment.app.FragmentTransaction;

import androidx.appcompat.app.AppCompatActivity;

import android.util.Log;

import android.view.View;

import android.widget.Button;

import android.widget.ImageButton;

import android.widget.ImageView;

import android.widget.TextView;

import android.widget.Toast;

import com.yuukidach.ucount.model.MoneyItem;

import com.yuukidach.ucount.presenter.AddItemPresenter;

import com.yuukidach.ucount.view.AddItemView;

import java.text.DecimalFormat;

import java.text.SimpleDateFormat;

import java.util.Locale;

public class AddItemActivity extends AppCompatActivity implements AddItemView {

private final int REQUEST_DESCRIPTION = 1;

private AddItemPresenter presenter;

private static final String TAG = "AddItemActivity";

private FragmentManager manager;

private FragmentTransaction transaction;

private Button addCostBtn;

private Button addEarnBtn;

private Button clearBtn;

private ImageButton addFinishBtn;

private ImageButton addDescription;

private ImageView bannerImage;

private TextView bannerText;

private TextView moneyText;

private TextView words;

private SimpleDateFormat formatItem = new SimpleDateFormat("yyyy年MM月dd日", Locale.CHINA);

private SimpleDateFormat formatSum = new SimpleDateFormat("yyyy年MM月", Locale.CHINA);

private DecimalFormat decimalFormat = new DecimalFormat("0.00");

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_add_item);

addCostBtn = (Button) findViewById(R.id.add_cost_button);

addEarnBtn = (Button) findViewById(R.id.add_earn_button);

addFinishBtn = (ImageButton) findViewById(R.id.add_finish);

addDescription = (ImageButton) findViewById(R.id.add_description);

clearBtn = (Button) findViewById(R.id.clear);

words = (TextView) findViewById(R.id.anime_words);

// 设置字体颜色

Typeface typeface = Typeface.createFromAsset(getAssets(), "fonts/chinese_character.ttf");

clearBtn.setTypeface(typeface);

words.setTypeface(typeface);

Bundle bundle = getIntent().getExtras();

presenter = new AddItemPresenter(this, bundle.getInt("bookId"));

bannerText = (TextView) findViewById(R.id.chosen_title);

bannerImage = (ImageView) findViewById(R.id.chosen_image);

moneyText = (TextView) findViewById(R.id.input_money_text);

presenter.onCreate();

addCostBtn.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

presenter.onAddCostButtonClick();

}

});

addEarnBtn.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

presenter.onAddEarnButtonClick();

}

});

addFinishBtn.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

presenter.onAddFinishButtonClick();

finish();

}

});

clearBtn.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

presenter.onClearButtonClick();

}

});

addDescription.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

presenter.onDescriptionButtonClick();

}

});

}

// 数字输入按钮

public void calculatorNumOnclick(View v) {

presenter.OnNumPadNumClick(v);

}

// 小数点处理工作

public void calculatorPushDot(View view) {

presenter.onNumPadDotClock();

}

@Override

protected void onActivityResult(int requestCode, int resultCode, Intent data) {

super.onActivityResult(requestCode, resultCode, data);

if (requestCode == REQUEST_DESCRIPTION) {

if (resultCode == RESULT_OK) {

presenter.setDescription(data.getStringExtra(Intent.EXTRA_TEXT));

}

}

}

@Override

public void highlightEarnButton() {

addCostBtn.setTextColor(0xff908070); // set cost button as gray

addEarnBtn.setTextColor(0xffff8c00); // set earn button as orange

}

@Override

public void highlightCostButton() {

addEarnBtn.setTextColor(0xff908070); // set earn button as gray

addCostBtn.setTextColor(0xffff8c00); // set cost button as orange

}

@Override

public void setAmount(String numStr) {

moneyText.setText(numStr);

}

@Override

public void useEarnFragment() {

transaction.replace(R.id.item_fragment, new EarnFragment());

}

@Override

public void useCostFragment() {

transaction.replace(R.id.item_fragment, new CostFragment());

}

@Override

public void setupTransaction() {

manager = getSupportFragmentManager();

beginTransaction();

transaction.replace(R.id.item_fragment, new CostFragment());

endTransaction();

}

@Override

public void beginTransaction() {

transaction = manager.beginTransaction();

}

@Override

public void endTransaction() {

transaction.commit();

}

@Override

public String getMoney() {

return moneyText.getText().toString();

}

@Override

public void navigateToDescription() {

Intent intent = new Intent(AddItemActivity.this, DescriptionActivity.class);

Bundle bundle = new Bundle();

bundle.putString("description", presenter.getDescription());

intent.putExtras(bundle);

startActivityForResult(intent, REQUEST_DESCRIPTION);

}

@Override

public void alarmNoMoneyInput() {

Toast.makeText(getApplicationContext(),"唔姆,你还没输入金额",Toast.LENGTH_SHORT).show();

}

@Override

public void alarmCanNotContinueToInput() {

Toast.makeText(getApplicationContext(), "唔,已经不能继续输入了", Toast.LENGTH_SHORT).show();

}

@Override

public void alarmAlreadyHasDot() {

Toast.makeText(getApplicationContext(), "已经输入过小数点了 ━ω━●", Toast.LENGTH_SHORT).show();

}

@Override

public String getTypeName() {

return bannerText.getText().toString();

}

@Override

public String getTypeImgResourceName() {

return bannerText.getTag().toString();

}

@Override

public MoneyItem.InOutType getInOutFlag() {

Log.d(TAG, "getInOutFlag: " + (MoneyItem.InOutType)bannerImage.getTag());

return (MoneyItem.InOutType) bannerImage.getTag();

}

@Override

public String getPressedNumPadValue(View view) {

Button button = (Button) view;

return button.getText().toString();

}

}

逐步详细地介绍这段代码:

导入必要的类和库:代码一开始通过 import 语句导入了许多类,这些类用于构建Android应用界面、处理数据和逻辑等。其中一些重要的类包括 android.content.Intent 用于活动间的数据传递,androidx.fragment.app.FragmentManager 和 androidx.fragment.app.FragmentTransaction 用于管理Fragment,android.widget.* 用于处理各种UI元素,以及自定义的类如 com.yuukidach.ucount.model.MoneyItem 和 com.yuukidach.ucount.presenter.AddItemPresenter。 定义常量和变量:在代码中定义了一些常量和实例变量,如 REQUEST_DESCRIPTION 是一个用于识别意图的请求代码,AddItemPresenter 是一个处理视图和数据之间交互的Presenter,还有各种按钮、图像、文本视图等。 设置界面布局:在 onCreate 方法中,通过 setContentView 方法将活动的界面布局设置为 “activity_add_item.xml”。这个布局文件描述了活动的用户界面,定义了各种UI元素的位置和交互方式。 初始化UI元素:接下来,通过 findViewById 方法获取在布局文件中定义的各种UI元素,如按钮、图像、文本视图等。然后对这些UI元素进行一些设置,例如:

setTypeface 方法用于为按钮设置自定义字体样式,增加了一些视觉效果。setTextColor 方法用于设置按钮文本的颜色,以区分不同的按钮状态。 获取传递的数据:通过 getIntent().getExtras() 获取从前一个活动传递过来的额外数据,这里通过键名 “bookId” 获取一个整数值,然后用这个值初始化了 AddItemPresenter。 设置按钮点击事件:通过监听按钮的点击事件,为按钮添加了点击响应的逻辑。例如,addCostBtn 按钮点击时会调用 presenter.onAddCostButtonClick() 方法。 实现接口方法:这个活动实现了一个接口 AddItemView,这个接口定义了一系列用于与Presenter交互的方法。这些方法用于更新界面、处理用户输入等操作。 其他方法:代码中还有一些其他方法,用于处理数字输入、小数点操作、启动其他活动、显示提示信息等。

总之,这段代码实现了一个用于记录金钱交易的Android活动。它通过获取用户输入、点击按钮、调用Presenter等方式,交互地在界面上显示交易细节,并将数据传递给Presenter进行进一步处理。

3.StatisticsActivity.java

package com.yuukidach.ucount;

import android.database.Cursor;

import android.graphics.Color;

import android.os.Bundle;

import android.util.Log;

import android.view.View;

import android.widget.ImageButton;

import android.widget.TextView;

import androidx.appcompat.app.AppCompatActivity;

import com.github.mikephil.charting.charts.PieChart;

import com.github.mikephil.charting.components.Legend;

import com.github.mikephil.charting.data.PieData;

import com.github.mikephil.charting.data.PieDataSet;

import com.github.mikephil.charting.data.PieEntry;

import com.yuukidach.ucount.model.MoneyItem;

import com.yuukidach.ucount.presenter.StatisticsPresenter;

import com.yuukidach.ucount.view.StatisticsView;

import org.litepal.LitePal;

import java.text.SimpleDateFormat;

import java.util.ArrayList;

import java.util.Calendar;

import java.util.List;

import java.util.Locale;

public class StatisticsActivity extends AppCompatActivity implements StatisticsView {

private static final String TAG = "StatisticsActivity";

private StatisticsPresenter presenter;

private TextView selectText;

private Calendar calendar;

private String yearMonth;

private SimpleDateFormat fmtYM;

private final int[] PIE_COLORS={

Color.rgb(181, 194, 202), Color.rgb(129, 216, 200), Color.rgb(241, 214, 145),

Color.rgb(108, 176, 223), Color.rgb(195, 221, 155), Color.rgb(251, 215, 191),

Color.rgb(237, 189, 189), Color.rgb(172, 217, 243)

};

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_statistics);

ImageButton prevBtn = (ImageButton) findViewById(R.id.prev_month);

ImageButton nextBtn = (ImageButton) findViewById(R.id.next_month);

selectText = (TextView) findViewById(R.id.selected_month);

Bundle bundle = getIntent().getExtras();

presenter = new StatisticsPresenter(this, bundle.getInt("bookId"));

presenter.onCreate();

fmtYM = new SimpleDateFormat("yyyy-MM", Locale.getDefault());

calendar = Calendar.getInstance();

yearMonth = fmtYM.format(calendar.getTime());

selectText.setText(yearMonth);

Log.d("calendar", "format:"+ yearMonth);

drawPieChart();

prevBtn.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

presenter.onPrevButtonClick();

}

});

nextBtn.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

presenter.onNextButtonClick();

}

});

}

@Override

public void prevMonth() {

calendar.add(Calendar.MONTH, -1);

yearMonth = fmtYM.format(calendar.getTime());

Log.d("calendar", "format:"+ fmtYM.format(calendar.getTime()));

selectText.setText(yearMonth);

}

@Override

public void nextMonth() {

calendar.add(Calendar.MONTH, 1);

yearMonth = fmtYM.format(calendar.getTime());

Log.d("calendar", "format:"+ fmtYM.format(calendar.getTime()));

selectText.setText(yearMonth);

}

@Override

public void selectMonth() {

}

@Override

public void drawPieChart() {

PieChart chart_cost = (PieChart) findViewById(R.id.chart_cost);

PieChart chart_earn = (PieChart) findViewById(R.id.chart_earn);

List entries_cost = new ArrayList();

List entries_earn = new ArrayList();

Cursor cursor_cost = LitePal.findBySQL("select sum(money),typename from MoneyItem " +

"where bookId = ? and " +

"inOutType = ? and " +

"date like ? " +

"group by typename", String.valueOf(presenter.getBookId()), MoneyItem.InOutType.COST.toString(), yearMonth+"%");

Cursor cursor_earn = LitePal.findBySQL("select sum(money),typename from MoneyItem " +

"where bookId = ? and " +

"inOutType = ? and " +

"date like ? " +

"group by typename", String.valueOf(presenter.getBookId()), MoneyItem.InOutType.EARN.toString(), yearMonth+"%");

if (cursor_cost != null && cursor_cost.moveToFirst()) {

do {

Log.d("database", "#######"+cursor_cost.getString(1)+"########");

Log.d("database", "#######"+cursor_cost.getDouble(0)+"########");

entries_cost.add(new PieEntry((float) cursor_cost.getDouble(cursor_cost.getColumnIndex("sum(money)")),

cursor_cost.getString(cursor_cost.getColumnIndex("typename"))));

} while (cursor_cost.moveToNext());

}

if (cursor_earn != null && cursor_earn.moveToFirst()) {

do {

Log.d("database", "#######"+cursor_earn.getString(1)+"########");

Log.d("database", "#######"+cursor_earn.getDouble(0)+"########");

entries_earn.add(new PieEntry((float) cursor_earn.getDouble(cursor_earn.getColumnIndex("sum(money)")),

cursor_earn.getString(cursor_earn.getColumnIndex("typename"))));

} while (cursor_earn.moveToNext());

}

PieDataSet dataSet_cost = new PieDataSet(entries_cost, "");

dataSet_cost.setColors(PIE_COLORS);

dataSet_cost.setValueLinePart1OffsetPercentage(60f);

dataSet_cost.setYValuePosition(PieDataSet.ValuePosition.OUTSIDE_SLICE);

dataSet_cost.setValueLinePart1Length(0.4f);

dataSet_cost.setValueLinePart2Length(0.4f);

PieData pieData_cost = new PieData(dataSet_cost);

pieData_cost.setValueTextSize(18f);

Legend l = chart_cost.getLegend();

l.setTextSize(15f);

l.setFormSize(12f);

l.setXEntrySpace(10f);

chart_cost.setData(pieData_cost);

chart_cost.getDescription().setText("");

chart_cost.setExtraOffsets(10f, 0, 10f, 0);

chart_cost.setEntryLabelColor(0xff000000);

chart_cost.setEntryLabelTextSize(15f);

chart_cost.invalidate();

PieDataSet dataSet_earn = new PieDataSet(entries_earn, "");

dataSet_earn.setColors(PIE_COLORS);

dataSet_earn.setValueLinePart1OffsetPercentage(60f);

dataSet_earn.setYValuePosition(PieDataSet.ValuePosition.OUTSIDE_SLICE);

dataSet_earn.setValueLinePart1Length(0.4f);

dataSet_earn.setValueLinePart2Length(0.4f);

PieData pieData_earn = new PieData(dataSet_earn);

pieData_earn.setValueTextSize(18f);

l = chart_earn.getLegend();

l.setTextSize(15f);

l.setFormSize(12f);

l.setXEntrySpace(10f);

chart_earn.setData(pieData_earn);

chart_earn.getDescription().setText("");

chart_earn.setExtraOffsets(10f, 0, 10f, 0);

chart_earn.setEntryLabelColor(0xff000000);

chart_earn.setEntryLabelTextSize(15f);

chart_earn.invalidate();

}

}

这段代码是一个名为 “StatisticsActivity” 的 Android 应用程序组件,主要用于展示统计数据并绘制饼状图。我将逐步解释代码的各个部分:

导入包和库:

代码开始处导入了必要的 Android 类和第三方库,用于在应用中使用图表和数据库功能。 类定义和成员变量:

StatisticsActivity 类继承自 AppCompatActivity,表示这是一个与界面交互的 Activity。成员变量包括 TAG(用于日志输出)、presenter(用于处理界面逻辑和数据交互)、selectText(用于显示所选月份)、calendar(用于日期计算)、yearMonth(表示所选年月字符串)、fmtYM(日期格式化工具)以及 PIE_COLORS(饼图颜色数组)等。 onCreate 方法:

这是 Activity 的生命周期方法,会在创建时调用。设置布局和获取界面元素的引用。通过 getIntent().getExtras() 获取从上一个 Activity 传递的参数,并用该参数初始化 presenter。初始化日期格式化工具和当前日期,并在界面上显示。调用 drawPieChart 方法绘制饼图。为前进和后退按钮设置点击监听器,用于在不同月份之间切换。 接口方法的实现(StatisticsView 接口的实现):

prevMonth():向前切换一个月份,更新日期并在界面上显示。nextMonth():向后切换一个月份,更新日期并在界面上显示。selectMonth():暂时空实现,用于选择月份。drawPieChart():绘制两个饼图,分别用于显示支出和收入的数据。 绘制饼图方法 drawPieChart:

获取两个 PieChart 控件的引用,分别表示支出和收入饼图。通过 SQL 查询从数据库中获取特定月份、特定账本和特定类型(支出或收入)的数据,然后将查询结果存储到 entries_cost 和 entries_earn 列表中。创建 PieDataSet 对象,并将查询结果添加到数据集中。配置数据集的样式、值的位置等参数。创建 PieData 对象,并设置数据集。配置图例的样式,然后将数据集绑定到饼图控件上并刷新显示。

三.项目源码

链接:https://pan.baidu.com/s/1wlzPw6kJV_4kSHv-lQPyVw 提取码:****

创作不易,项目已加密,有偿(仅一杯奶茶钱,可做实验报告,代码讲解等…)

请私信作者或

(v)15135757306

文章来源

评论可见,请评论后查看内容,谢谢!!!评论后请刷新页面。