ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

安卓——家庭记账本9

2022-02-08 09:33:00  阅读:185  来源: 互联网

标签:github int 安卓 家庭 month 记账 year import com


今天实现记账本的最后一个功能,账单详情页面的展示,点击账单详情之后,会出现如下界面

 

 

 

 这个布局由三部分组成,整体布局+下面的条目+表格。

首先来做整体布局,在Layout制作布局

<?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"
    android:background="@color/grey_f3f3f3"
    android:orientation="vertical">
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="50dp">
        <ImageView
            android:id="@+id/chart_iv_back"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:src="@mipmap/it_back"
            android:layout_marginLeft="10dp"
            android:onClick="onClick"/>
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:text="@string/chart_info"
            android:textSize="18sp"
            android:textStyle="bold"/>
        <ImageView
            android:id="@+id/chart_iv_rili"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:src="@mipmap/it_rili"
            android:layout_alignParentRight="true"
            android:layout_marginRight="10dp"
            android:onClick="onClick"/>
    </RelativeLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:background="@color/white"
        android:padding="10dp"
        android:layout_marginTop="20dp">
        <TextView
            android:id="@+id/chart_tv_date"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="2022年2月账单"
            android:textColor="@color/black"
            android:textStyle="bold"
            android:textSize="18sp"/>
        <TextView
            android:id="@+id/chart_tv_out"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="共1笔支出 ¥25.0"
            android:textColor="@color/black"
            android:textSize="15sp"/>
        <TextView
            android:id="@+id/chart_tv_in"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="共1笔收入 ¥3000.0"
            android:textColor="@color/black"
            android:textSize="15sp"/>
    </LinearLayout>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:layout_margin="10dp"
        android:gravity="center">
        <Button
            android:id="@+id/chart_btn_out"
            android:layout_width="wrap_content"
            android:layout_height="30dp"
            android:text="@string/out"
            android:background="@drawable/main_record_bg"
            android:textColor="@color/white"
            android:textStyle="bold"
            android:onClick="onClick"
            android:layout_marginRight="10dp"/>
        <Button
            android:id="@+id/chart_btn_in"
            android:layout_width="wrap_content"
            android:layout_height="30dp"
            android:text="@string/in"
            android:background="@drawable/dialog_btn_bg"
            android:textColor="@color/black"
            android:textStyle="bold"
            android:onClick="onClick"
            android:layout_marginLeft="10dp"/>
    </LinearLayout>
    <androidx.viewpager.widget.ViewPager
        android:id="@+id/chart_vp"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
</LinearLayout>

它主要显示某年某月的账单这一布局。同时这里面有返回和日历两个点击事件。

接下来实现记账条目的布局。

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent" android:layout_height="wrap_content"
    android:padding="10dp"
    android:background="@color/white">
    <ImageView
        android:id="@+id/item_chartfrag_iv"
        android:layout_width="35dp"
        android:layout_height="35dp"
        android:src="@mipmap/ic_yanjiu_fs"/>
    <TextView
        android:id="@+id/item_chartfrag_tv_type"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="烟酒茶"
        android:textSize="16sp"
        android:layout_toRightOf="@id/item_chartfrag_iv"
        android:layout_centerVertical="true"
        android:layout_marginLeft="10dp"
        android:textStyle="bold"/>
    <TextView
        android:id="@+id/item_chartfrag_tv_percent"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="25.0%"
        android:textSize="16sp"
        android:layout_centerInParent="true"/>
    <TextView
        android:id="@+id/item_chartfrag_tv_sum"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="¥150.0"
        android:textSize="16sp"
        android:layout_centerVertical="true"
        android:layout_alignParentRight="true"/>

</RelativeLayout>

这一布局展示账目的种类,钱数多少,以及其所占比。

最后一个布局是表格,布局如下,

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent" android:layout_height="wrap_content">
    <com.github.mikephil.charting.charts.BarChart
        android:id="@+id/item_chartfrag_chart"
        android:layout_width="match_parent"
        android:layout_height="300dp" />
    <TextView
        android:id="@+id/item_chartfrag_top_tv"
        android:layout_width="match_parent"
        android:layout_height="300dp"
        android:text="@string/notdata"
        android:textSize="20sp"
        android:textStyle="bold"
        android:gravity="center"
        android:visibility="gone"/>
</RelativeLayout>

表格布局制定完之后,还需要在后台代码中进行完善,定义x和y轴...

首先来完成返回和日历的点击事件,返回点击事件,直接finish(),日历的点击事件在上一篇博客中有详细记录。

加下来完成记账条目的后台代码。对于记账条目在DBManger中定义方法对其完成操作

/*
    查询指定年份和月份的收入或支出每一种类型的总钱数
    **/
    public static List<ChartItemBean> getChartListFromAccounttb(int year,int month,int kind){
        List<ChartItemBean> list = new ArrayList<>();
        float sumMoneyOneMonth = getSumMoneyOneMonth(year, month, kind);//求出支出或收入总钱数
        String sql = "select typename,simageId,sum(money)as total from accounttb where year=? and month=? and kind=?" +
                "group by typename order by total desc";
        Cursor cursor = db.rawQuery(sql,new String[]{year+"",month+"",kind+""});
        while(cursor.moveToNext()){
            int simageId = cursor.getInt(cursor.getColumnIndex("simageId"));
            String typename = cursor.getString(cursor.getColumnIndex("typename"));
            float total = cursor.getFloat(cursor.getColumnIndex("total"));
            //计算所占百分比 total/sumMonth
            float ratio = FloatUtils.div(total,sumMoneyOneMonth);
            ChartItemBean bean = new ChartItemBean(simageId,typename,ratio,total);
            list.add(bean);
        }
        return list;
    }

由于需要计算百分比,所以将除法计算包装成一个类

import java.math.BigDecimal;

public class FloatUtils {
    /**
     * 进行除法运算
     * **/
    public static float div(float v1,float v2){
        float v3 = v1/v2;
        BigDecimal b1 = new BigDecimal(v3);
        float val = b1.setScale(4,4).floatValue();
        return val;
    }

    //将浮点数转换成百分比显示
    public static String ratioToPercent(float val){
        float v = val*100;
        BigDecimal b1 = new BigDecimal(v);
        float v1 = b1.setScale(2,4).floatValue();
        String per = v1+"%";
        return per;
    }
}

设置完这些之后,设置内容显示,同时柱状图的设置也在这里完成。

import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ListView;
import android.widget.TextView;

import androidx.fragment.app.Fragment;

import com.example.bookeep.R;
import com.example.bookeep.adaptor.ChartItemAdapter;
import com.example.bookeep.db.ChartItemBean;
import com.example.bookeep.db.DBManger;
import com.github.mikephil.charting.charts.BarChart;
import com.github.mikephil.charting.components.AxisBase;
import com.github.mikephil.charting.components.XAxis;
import com.github.mikephil.charting.formatter.IAxisValueFormatter;

import java.util.ArrayList;
import java.util.List;

/**
 * A simple {@link Fragment} subclass.
 */
abstract public class BaseFragment extends Fragment {
    ListView chartLv;
    public int year;
    public int month;
    List<ChartItemBean> mDatas;//数据源
    private ChartItemAdapter itemAdapter;
    BarChart barChart;//柱状图控件
    TextView chartTv;//如果没有收支情况,显示的文本

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View view = inflater.inflate(R.layout.fragment_income, container, false);
        chartLv = view.findViewById(R.id.frag_chart_lv);
        //获取Activity传递的数据
        Bundle bundle = getArguments();
        year = bundle.getInt("year");
        month = bundle.getInt("month");
        //设置数据源
        mDatas = new ArrayList<>();
        //设置适配器
        itemAdapter = new ChartItemAdapter(getContext(), mDatas);
        chartLv.setAdapter(itemAdapter);
        //添加头布局
        addLVHeaderView();
        return view;
    }

    protected void addLVHeaderView(){
        //将布局转换成View对象
        View headerView = getLayoutInflater().inflate(R.layout.item_chartfrag_top,null);
        //将ew添加到ListView的头布局
        chartLv.addHeaderView(headerView);
        //查找头布局当中包含的控件
        barChart = headerView.findViewById(R.id.item_chartfrag_chart);
        chartTv = headerView.findViewById(R.id.item_chartfrag_top_tv);
        //设定柱状图不显示描述
        barChart.getDescription().setEnabled(false);
        //设置柱状图的内边距
        barChart.setExtraOffsets(20,20,20,20);
        setAxis(year,month);
        //设置坐标轴显示的数据
        setAxisData(year,month);
    }

    //设置坐标轴显示的数据
    protected abstract void setAxisData(int year, int month);

    //设置柱状图坐标轴的显示,方法必须重新
    protected void setAxis(int year, final int month){
        //设置x轴
        XAxis xAxis = barChart.getXAxis();
        xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);//设置X轴显示在下方
        xAxis.setDrawGridLines(true);//设置绘制该轴的网格线
        //设置x轴标签的个数
        xAxis.setLabelCount(31);
        xAxis.setTextSize(12f);//x轴标签大小

        //设置X轴显示值的格式
        xAxis.setValueFormatter(new IAxisValueFormatter() {
            @Override
            public String getFormattedValue(float value, AxisBase axis) {
                int val = (int) value;
                if (val == 0) {
                    return month + "-1";
                }
                if (val == 14) {
                    return month + "-15";
                }

                //根据不同月份,显示最后一天
                if (month == 2) {
                    if (val == 27) {
                        return month + "-28";
                    }
                }else if (month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12) {
                    if (val == 30) {
                        return month + "-31";
                    }
                } else if (month == 4 || month == 6 || month == 9 || month == 11) {
                    if (val == 29) {
                        return month + "-30";
                    }
                }
                return "";
            }
        });
        xAxis.setYOffset(10);//设置标签对x轴的偏移量,垂直方向
        //y轴在子类的设置
        setYAxis(year,month);
    }

    //设置y轴,高度不统一,在子类实现
    protected abstract void setYAxis(int year,int month);

    public void setDate(int year,int month){
        this.year = year;
        this.month = month;
        //清空柱状图当中的数据
        barChart.clear();
        barChart.invalidate();//重新绘制柱状图
        setAxis(year,month);
        setAxisData(year, month);
    }

    public void loadData(int year, int month, int kind) {
        List<ChartItemBean> list = DBManger.getChartListFromAccounttb(year, month, kind);
        mDatas.clear();
        mDatas.addAll(list);
        itemAdapter.notifyDataSetChanged();
    }
}

对于收入和支出,直接继承该类即可

import android.graphics.Color;
import android.os.Bundle;

import androidx.fragment.app.Fragment;

import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ListView;

import com.example.bookeep.R;
import com.example.bookeep.adaptor.ChartItemAdapter;
import com.example.bookeep.db.BarChartItemBean;
import com.example.bookeep.db.ChartItemBean;
import com.example.bookeep.db.DBManger;
import com.github.mikephil.charting.components.Legend;
import com.github.mikephil.charting.components.YAxis;
import com.github.mikephil.charting.data.BarData;
import com.github.mikephil.charting.data.BarDataSet;
import com.github.mikephil.charting.data.BarEntry;
import com.github.mikephil.charting.data.Entry;
import com.github.mikephil.charting.formatter.IValueFormatter;
import com.github.mikephil.charting.interfaces.datasets.IBarDataSet;
import com.github.mikephil.charting.utils.ViewPortHandler;

import java.util.ArrayList;
import java.util.List;

/**
 * A simple {@link Fragment} subclass.
 */
public class IncomeFragment extends BaseFragment {
    int kind = 1;
    @Override
    public void onResume() {
        super.onResume();
        loadData(year,month,kind);
    }

    @Override
    protected void setAxisData(int year, int month) {
        List<IBarDataSet> sets = new ArrayList<>();
        //获取这个月每天的支出总金额
        List<BarChartItemBean> list = DBManger.getSumMoneyOneDayInMonth(year,month,kind);
        if (list.size()==0) {
            barChart.setVisibility(View.GONE);
            chartTv.setVisibility(View.VISIBLE);
        }else{
            barChart.setVisibility(View.VISIBLE);
            chartTv.setVisibility(View.GONE);

            //设置有多少根柱子
            List<BarEntry> barEntries1 = new ArrayList<>();
            for (int i = 0; i <31 ; i++) {
                //初始化没一根柱子,添加到柱状图中
                BarEntry entry = new BarEntry(i,0.0f);
                barEntries1.add(entry);
            }
            for (int i = 0; i <list.size() ; i++) {
                BarChartItemBean itemBean = list.get(i);
                int day = itemBean.getDay();//获取日期
                //根据天数获取x轴的位置
                int xIndex = day-1;
                BarEntry barEntry = barEntries1.get(xIndex);
                barEntry.setY(itemBean.getSummoney());
            }
            BarDataSet barDataSet1 = new BarDataSet(barEntries1, "");
            barDataSet1.setValueTextColor(Color.BLACK); // 值的颜色
            barDataSet1.setValueTextSize(8f); // 值的大小
            barDataSet1.setColor(Color.parseColor("#006400")); // 柱子的颜色

            // 设置柱子上数据显示的格式
            barDataSet1.setValueFormatter(new IValueFormatter() {
                @Override
                public String getFormattedValue(float value, Entry entry, int dataSetIndex, ViewPortHandler viewPortHandler) {
                    // 此处的value默认保存一位小数
                    if (value==0) {
                        return "";
                    }
                    return value + "";
                }
            });

            sets.add(barDataSet1);
            BarData barData = new BarData(sets);
            barData.setBarWidth(0.2f); // 设置柱子的宽度
            barChart.setData(barData);
        }
    }

    @Override
    protected void setYAxis(int year, int month) {
        //获取本月收入最高的一天为多少,设为最大值
        float maxMoney = DBManger.getMaxMoneyOneDayInMonth(year,month,kind);
        float max = (float) Math.ceil(maxMoney);
        //设置y轴
        YAxis yAxis_right = barChart.getAxisRight();
        yAxis_right.setAxisMaximum(max);  // 设置y轴的最大值
        yAxis_right.setAxisMinimum(0f);  // 设置y轴的最小值
        yAxis_right.setEnabled(false);  // 不显示右边的y轴

        YAxis yAxis_left = barChart.getAxisLeft();
        yAxis_left.setAxisMaximum(max);
        yAxis_left.setAxisMinimum(0f);
        yAxis_left.setEnabled(false);

        //设置不显示图例
        Legend legend = barChart.getLegend();
        legend.setEnabled(false);
    }

    @Override
    public void setDate(int year, int month) {
        super.setDate(year, month);
        loadData(year,month,kind);
    }
}
import android.graphics.Color;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import androidx.fragment.app.Fragment;

import com.example.bookeep.R;
import com.example.bookeep.db.BarChartItemBean;
import com.example.bookeep.db.DBManger;
import com.github.mikephil.charting.components.Legend;
import com.github.mikephil.charting.components.YAxis;
import com.github.mikephil.charting.data.BarData;
import com.github.mikephil.charting.data.BarDataSet;
import com.github.mikephil.charting.data.BarEntry;
import com.github.mikephil.charting.data.Entry;
import com.github.mikephil.charting.formatter.IValueFormatter;
import com.github.mikephil.charting.interfaces.datasets.IBarDataSet;
import com.github.mikephil.charting.utils.ViewPortHandler;

import java.util.ArrayList;
import java.util.List;

/**
 * A simple {@link Fragment} subclass.
 */
public class OutcomeFragment extends BaseFragment {
    int kind = 0;
    @Override
    public void onResume() {
        super.onResume();
        loadData(year,month,kind);
    }

    @Override
    protected void setAxisData(int year, int month) {
        List<IBarDataSet> sets = new ArrayList<>();
        //获取这个月每天的支出总金额
        List<BarChartItemBean> list = DBManger.getSumMoneyOneDayInMonth(year,month,kind);
        if (list.size()==0) {
            barChart.setVisibility(View.GONE);
            chartTv.setVisibility(View.VISIBLE);
        }else{
            barChart.setVisibility(View.VISIBLE);
            chartTv.setVisibility(View.GONE);

            //设置有多少根柱子
            List<BarEntry> barEntries1 = new ArrayList<>();
            for (int i = 0; i <31 ; i++) {
                //初始化没一根柱子,添加到柱状图中
                BarEntry entry = new BarEntry(i,0.0f);
                barEntries1.add(entry);
            }
            for (int i = 0; i <list.size() ; i++) {
                BarChartItemBean itemBean = list.get(i);
                int day = itemBean.getDay();//获取日期
                //根据天数获取x轴的位置
                int xIndex = day-1;
                BarEntry barEntry = barEntries1.get(xIndex);
                barEntry.setY(itemBean.getSummoney());
            }
            BarDataSet barDataSet1 = new BarDataSet(barEntries1, "");
            barDataSet1.setValueTextColor(Color.BLACK); // 值的颜色
            barDataSet1.setValueTextSize(8f); // 值的大小
            barDataSet1.setColor(Color.RED); // 柱子的颜色

            // 设置柱子上数据显示的格式
            barDataSet1.setValueFormatter(new IValueFormatter() {
                @Override
                public String getFormattedValue(float value, Entry entry, int dataSetIndex, ViewPortHandler viewPortHandler) {
                    // 此处的value默认保存一位小数
                    if (value==0) {
                        return "";
                    }
                    return value + "";
                }
            });

            sets.add(barDataSet1);
            BarData barData = new BarData(sets);
            barData.setBarWidth(0.2f); // 设置柱子的宽度
            barChart.setData(barData);
        }
    }

    @Override
    protected void setYAxis(int year, int month) {
        //获取本月收入最高的一天为多少,设为最大值
        float maxMoney = DBManger.getMaxMoneyOneDayInMonth(year,month,kind);
        float max = (float) Math.ceil(maxMoney);
        //设置y轴
        YAxis yAxis_right = barChart.getAxisRight();
        yAxis_right.setAxisMaximum(max);  // 设置y轴的最大值
        yAxis_right.setAxisMinimum(0f);  // 设置y轴的最小值
        yAxis_right.setEnabled(false);  // 不显示右边的y轴

        YAxis yAxis_left = barChart.getAxisLeft();
        yAxis_left.setAxisMaximum(max);
        yAxis_left.setAxisMinimum(0f);
        yAxis_left.setEnabled(false);

        //设置不显示图例
        Legend legend = barChart.getLegend();
        legend.setEnabled(false);
    }


    @Override
    public void setDate(int year, int month) {
        super.setDate(year, month);
        loadData(year,month,kind);
    }
}

最终将这些代码进行组装,这个小程序就做好了。

明天将对这个程序做一个总结。

 

标签:github,int,安卓,家庭,month,记账,year,import,com
来源: https://www.cnblogs.com/jzz-111jy/p/15867991.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有