Android——一个简单的记账本APP

一个简单的记账本APP

  • 视频效果预览
  • 添加账目记录
    • 效果预览
    • 添加账目记录实现
      • 简述
      • 实现
        • 获取日期
          • 字符串时间戳转Date
          • Date转星期
          • 获取时间
          • Switch控制显示和隐藏
            • 更改Switch样式
            • 事件监听
            • 保存至SQLite数据库
            • 标签选择实现
              • 效果预览
              • 实现
                • 状态改变
                  • 事件监听
                  • 状态监听
                  • 导航界面
                    • 创建menu
                    • 创建Fragment
                    • 绑定Fragment
                    • 账单记录显示
                      • 效果预览
                      • 简述
                      • RecyclerView显示
                        • 建立适配器
                        • 获取数据源
                          • 保留两位小数
                          • 概览
                            • 效果预览
                            • 简述
                            • 分类显示
                              • 创建适配器
                              • 获取数据源
                              • 前三甲
                                • 创建适配器
                                • 获取数据源
                                • 单标签总价以及总金额
                                • 可视化概览
                                  • 效果预览
                                  • 简述
                                    • 折线图
                                      • 获取数据源
                                      • 南丁格尔玫瑰图
                                        • 获取数据源
                                        • 记录删除
                                          • 效果图
                                          • 尾言

                                            视频效果预览

                                            添加账目记录

                                            效果预览

                                            添加账目记录实现

                                            简述

                                            日期选择采用CalendarView控件,时间选择采用TimePicker控件,然后通过switch控件控制其VISIBLE和GONE属性,类型通过PopUpWindows弹窗显示,标签通过SharedPreferences进行传递。最后插入SQLite数据库中。

                                            实现

                                            获取日期

                                            因为获取的日历控件的月份要比实际少一个月,故因此需要把月份加上一。

                                            然后将获取的年月日字符串数据转为Date格式,最后将Date格式转为当时的星期

                                            字符串时间戳转Date
                                             public static Date getStringToDate(String str){
                                                    mSimpleDateFormat = new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault());
                                                    try {
                                                        Date date = mSimpleDateFormat.parse(str);
                                                        return date;
                                                    } catch (ParseException e) {
                                                        e.printStackTrace();
                                                    }
                                                    return null;
                                                }
                                            
                                            Date转星期
                                            public static String getWeekOfDate(Date date) {
                                                    String[] weekDays = {"星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"};
                                                    Calendar cal = Calendar.getInstance();
                                                    cal.setTime(date);
                                                    int w = cal.get(Calendar.DAY_OF_WEEK) - 1;
                                                    if (w < 0)
                                                        w = 0;
                                                    return weekDays[w];
                                                }
                                            

                                            最后将获取的日期、星期进行保存

                                             /**
                                                 * 显示选择的年月日,并将选择的年月日转为星期
                                                 */
                                                private void getDate() {
                                                    mCalendarView.setOnDateChangeListener(new CalendarView.OnDateChangeListener() {
                                                        @Override
                                                        public void onSelectedDayChange(@NonNull CalendarView view, int year, int month, int dayOfMonth) {
                                                            month = month + 1;
                                                            CNDate = year + "年" + month + "月" + dayOfMonth + "日";
                                                            String date = year + "-" + month + "-" + dayOfMonth;
                                                            Log.d(TAG, "date=" + date);
                                                            Log.d(TAG, "CNdate=" + CNDate);
                                                            //string日期转date日期,在转为星期
                                                            String week = DateUtils.getWeekOfDate(DateUtils.getStringToDate(date));
                                                            Log.d(TAG, "week=" + week);
                                                            SelectDate.setText(CNDate + " " + week);
                                                        }
                                                    });
                                                }
                                            
                                            获取时间

                                            直接对TimePicker控件进行事件监听,然后将获取的时间进行保存即可

                                             private void getTime() {
                                                    mTimePicker.setOnTimeChangedListener(new TimePicker.OnTimeChangedListener() {
                                                        @Override
                                                        public void onTimeChanged(TimePicker view, int hourOfDay, int minute) {
                                                            String time = hourOfDay + ":" + minute;
                                                            SelectTime.setText(time);
                                                            Log.d(TAG, time);
                                                        }
                                                    });
                                                }
                                            
                                            Switch控制显示和隐藏
                                            更改Switch样式

                                            建立thumb.xml和track.xml两个选择器

                                            thumb.xml如下

                                            track.xml如下

                                              

                                            然后分别建立两个选择器的不同状态下的效果文件

                                            open_thumb.xml

                                             

                                            shut_thumb.xml

                                            open_track.xml

                                                   

                                            shut_track.xml

                                                

                                            最后应用于switch效果如下

                                             
                                            事件监听

                                            通过监听Switch事件,判断false和true两种状态,分别对应控件的隐藏和显示

                                             class SwitchListener implements CompoundButton.OnCheckedChangeListener {
                                                    @Override
                                                    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                                                        switch (buttonView.getId()) {
                                                            case R.id.DateSwitch:
                                                                if (isChecked)
                                                                    DateLayout.setVisibility(View.VISIBLE);
                                                                else
                                                                    DateLayout.setVisibility(View.GONE);
                                                                break;
                                                            case R.id.TimeSwitch:
                                                                if (isChecked)
                                                                    TimeLayout.setVisibility(View.VISIBLE);
                                                                else
                                                                    TimeLayout.setVisibility(View.GONE);
                                                                break;
                                                        }
                                                    }
                                                }
                                            
                                            保存至SQLite数据库
                                             /**
                                                 * 账单记录保存到SQLite中
                                                 */
                                                public void SaveMessage(View view) {
                                                    String date = SelectDate.getText().toString().trim();
                                                    String time = SelectTime.getText().toString().trim();
                                                    String type = TypeText.getText().toString();
                                                    String label = TextLabel.getText().toString();
                                                    String name = GoodsName.getText().toString();
                                                    String price = GoodsPrice.getText().toString().trim();
                                                    if (TextUtils.isEmpty(type) || type.equals("支出or收入")){
                                                        toastUtils.ShowFail("类型错误!");
                                                        return;
                                                    }
                                                    if (TextUtils.isEmpty(label) || label.equals("暂未选择")){
                                                        toastUtils.ShowFail("标签错误!");
                                                        return;
                                                    }
                                                    if (TextUtils.isEmpty(name) || TextUtils.isEmpty(price)){
                                                        toastUtils.ShowFail("商品信息或者商品价格格式!");
                                                        return;
                                                    }
                                                    int t = type.equals("支出") ? 1 : 0;
                                                    Record record = new Record(date,time,t,label,name,price);
                                                    int flag = dao.Insert(record);
                                                    if (flag == 1){
                                                        toastUtils.ShowSuccess("保存成功!");
                                                    }else {
                                                        toastUtils.ShowFail("保存失败!");
                                                    }
                                                }
                                            

                                            标签选择实现

                                            效果预览

                                            实现

                                            状态改变

                                            每一个标签有两种状态,选择和不被选择状态,分别对应两种样式效果,一种呈灰色,另一种呈高亮,在进行选择时可以同时点亮多个标签,但最后进行保存时,只能选择一个标签,若条件不满足,系统给予错误提示。

                                            事件监听
                                             class TypeListener implements View.OnClickListener{
                                                    @Override
                                                    public void onClick(View v) {
                                                        switch (v.getId()){
                                                            case R.id.type_1:
                                                                setTag(type_1,getTag(type_1));
                                                                setBG(type_1,1);
                                                                break;
                                                            case R.id.type_2:
                                                                setTag(type_2,getTag(type_2));
                                                                setBG(type_2,2);
                                                                break;
                                                            case R.id.type_3:
                                                                setTag(type_3,getTag(type_3));
                                                                setBG(type_3,3);
                                                                break;
                                                            case R.id.type_4:
                                                                setTag(type_4,getTag(type_4));
                                                                setBG(type_4,4);
                                                                break;
                                                            case R.id.type_5:
                                                                setTag(type_5,getTag(type_5));
                                                                setBG(type_5,5);
                                                                break;
                                                            case R.id.type_6:
                                                                setTag(type_6,getTag(type_6));
                                                                setBG(type_6,6);
                                                                break;
                                                            case R.id.type_7:
                                                                setTag(type_7,getTag(type_7));
                                                                setBG(type_7,7);
                                                                break;
                                                            case R.id.type_8:
                                                                setTag(type_8,getTag(type_8));
                                                                setBG(type_8,8);
                                                                break;
                                                        }
                                                    }
                                                }
                                            
                                            状态监听

                                            每一个标签被点击,其tag自增一次,若未被点击,初始值为1

                                            private void setTag(LinearLayout layout,int tag){
                                                    tag++;
                                                    layout.setTag(tag);
                                                }
                                            
                                             private int getTag(LinearLayout layout){
                                                    Object tag = layout.getTag();
                                                    if (tag == null)return 1;
                                                    return (int) tag;
                                                }
                                            

                                            然后通过tag值改变标签的样式,成偶数则高亮,奇数则灰色,并记录当前状态值,同时保存被选择的标签数量。

                                             private void setBG(LinearLayout layout,int index){
                                                    int tag = (int)layout.getTag();
                                                    if (tag % 2 == 0) {
                                                        layout.setBackground(getResources().getDrawable(R.drawable.blue_radius_bg));
                                                        TotalNum++;
                                                        b_select[index-1] = true;
                                                    }
                                                    else {
                                                        layout.setBackground(getResources().getDrawable(R.drawable.grey_radius_bg));
                                                        TotalNum--;
                                                        b_select[index-1] = false;
                                                    }
                                                }
                                            

                                            然后通过监听保存按钮点击事件,取出状态值为true的标签值进行返回

                                            private String selectTag(){
                                                    for (int i = 0; i < 8; i++) {
                                                        if ( b_select[i]){
                                                            return s_select[i];
                                                        }
                                                    }
                                                return null;
                                                }
                                            

                                            同时监听被选择的标签总数,若小于1,则未选择任何标签,给予提升;若大于1,则选择多个标签,同样给予提升。最后通过SharedPreferences进行数据传回;使用Intent传输应该会更安全,一开始设计使用EventBus,但最后不了了。

                                            public void SaveMessage(View view){
                                                    if (TotalNum > 1){
                                                        toastUtils.ShowFail("选择标签数量不能超过一");
                                                    }else if (TotalNum <= 0){
                                                        toastUtils.ShowFail("选择标签数量不能少于一");
                                                    }else {
                                                        toastUtils.ShowSuccess("success");
                                                        String tag = selectTag();
                                                        Log.d(TAG,"TAG="+tag);
                                                        SP sp = SP.getInstance();
                                                        sp.PutData(LabelActivity.this,"Label",tag);
                                                        //EventBus.getDefault().post(new TextClass(tag));
                                                        KillProcess.POP(LabelActivity.this);
                                                    }
                                                }
                                            

                                            导航界面

                                            采用底部导航控件BottomNavigationView切换账单记录界面和账单概览界面,并通过ViewPager进行页面滑动,两个子页面采用两个不同的Fragment。

                                            创建menu

                                            次menu即为底部导航的文字和图片效果,可以使用选择器,监听选择和不被选择两种状态,改变其效果。若不设置,系统模式使用样式颜色作为高亮显示。灰色呈不被选择状态。

                                              

                                            创建Fragment

                                            由于本APP只需要两个节目,故只需要创建两个fragment,然后在与nav进行绑定即可,此处仅作为标记,详细介绍如下文所示

                                            绑定Fragment

                                             /**
                                               * Set a listener that will be notified when a bottom navigation item is selected. This listener
                                               * will also be notified when the currently selected item is reselected, unless an {@link
                                               * OnNavigationItemReselectedListener} has also been set.
                                               *
                                               * @param listener The listener to notify
                                               * @see #setOnNavigationItemReselectedListener(OnNavigationItemReselectedListener)
                                               */
                                            

                                            设置底部导航栏当前页面显示

                                             navView.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
                                                        @Override
                                                        public boolean onNavigationItemSelected(@NonNull MenuItem item) {
                                                            switch (item.getItemId()) {
                                                                case R.id.menu_navigation_record:
                                                                    mViewPager.setCurrentItem(0);
                                                                    return true;
                                                                case R.id.menu_navigation_general:
                                                                    mViewPager.setCurrentItem(1);
                                                                    return true;
                                                            }
                                                            return false;
                                                        }
                                                    });
                                            

                                            将ViewPager和两个fragment进行绑定

                                            private void setupViewPager(ViewPager viewPager) {
                                                    BottomAdapter adapter = new BottomAdapter(getSupportFragmentManager());
                                                    adapter.addFragment(new RecordFragment());
                                                    adapter.addFragment(new GeneralFragment());
                                                    viewPager.setAdapter(adapter);
                                                }
                                            

                                            并通过监听ViewPager事件,进行页面切换

                                            mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
                                                        @Override
                                                        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
                                                        }
                                                        @Override
                                                        public void onPageSelected(int position) {
                                                            navView.getMenu().getItem(position).setChecked(true);
                                                        }
                                                        @Override
                                                        public void onPageScrollStateChanged(int state) {
                                                        }
                                                    });
                                                }
                                            

                                            账单记录显示

                                            效果预览

                                            简述

                                            此界面就比较简单,从数据库中拿出所有数据并构建一个集合类对象,然后放入RecyclerView中进行显示,最后根据类型计算总支出和总收入金额

                                            RecyclerView显示

                                            建立适配器

                                            public class OrderAdapter extends RecyclerView.Adapter {
                                                private String[] s_select = {"日用百货","文化休闲","交通出行","生活服务","服装装扮","餐饮美食","数码电器","其他标签"};
                                                private int[] img_select = {
                                                        R.drawable.icon_type_one,
                                                        R.drawable.icon_type_two,
                                                        R.drawable.icon_type_three,
                                                        R.drawable.icon_type_four,
                                                        R.drawable.icon_type_five,
                                                        R.drawable.icon_type_six,
                                                        R.drawable.icon_type_seven,
                                                        R.drawable.icon_type_eight};
                                                private List recordList;
                                                public OrderAdapter(List recordList){
                                                    this.recordList = recordList;
                                                }
                                                @NonNull
                                                @Override
                                                public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
                                                    View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.order_item,parent,false);
                                                    return new ViewHolder(view);
                                                }
                                                @Override
                                                public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
                                                    Record record = recordList.get(position);
                                                    holder.item_date.setText(record.getDate());
                                                    holder.item_time.setText("时间 "+record.getTime());
                                                    holder.item_label.setText("["+record.getLabel()+"]");
                                                    holder.item_name.setText(record.getGoodsName());
                                                    if (record.getType() == 1){
                                                        holder.item_price.setText("-"+record.getGoodsPrice());
                                                    }else {
                                                        holder.item_price.setText("+"+record.getGoodsPrice());
                                                    }
                                                    for (int i = 0; i < 8; i++) {
                                                        if (record.getLabel().equals(s_select[i])){
                                                            holder.item_img.setImageResource(img_select[i]);
                                                        }
                                                    }
                                                }
                                                @Override
                                                public int getItemCount() {
                                                    return recordList.size();
                                                }
                                                class ViewHolder extends RecyclerView.ViewHolder{
                                                    private TextView item_date,item_time,item_label,item_name,item_price;
                                                    private ImageView item_img;
                                                    public ViewHolder(@NonNull View itemView) {
                                                        super(itemView);
                                                        item_date = itemView.findViewById(R.id.item_date);
                                                        item_time = itemView.findViewById(R.id.item_time);
                                                        item_label = itemView.findViewById(R.id.item_label);
                                                        item_name = itemView.findViewById(R.id.item_name);
                                                        item_price = itemView.findViewById(R.id.item_price);
                                                        item_img = itemView.findViewById(R.id.item_img);
                                                    }
                                                }
                                            }
                                            

                                            获取数据源

                                            从数据库中获取实体类集合对象,然后根据其收入和支出两种状态计算相对应的总金额

                                            /**
                                                 * 获取RecyclerView数据源*/
                                                private void getData(){
                                                    recordList = dao.QueryAll();
                                                    if (recordList.size() == 0 || recordList == null){
                                                        IsEmpty(true);
                                                        return;
                                                    }
                                                    for (int i = 0; i < recordList.size(); i++) {
                                                        /**
                                                         * 1为支出
                                                         * 0为收入*/
                                                        if (recordList.get(i).getType() == 1){
                                                            totalPay += Double.parseDouble(recordList.get(i).getGoodsPrice());
                                                        }else {
                                                            totalIncome += Double.parseDouble(recordList.get(i).getGoodsPrice());
                                                        }
                                                    }
                                                    IsEmpty(TotalPay,totalPay,1);
                                                    IsEmpty(TotalIncome,totalIncome,0);
                                                }
                                            
                                            保留两位小数

                                            由于在转换格式的之后,进行加减运算精度会失衡,会产生很多位小数点,但由于美观以及界面设计,一般设计保留2位小数即可

                                            以12.345678为例:
                                            12.345678*100 = 1234.5678
                                            然后将其转为整数,则变为 1234
                                            最后除以100.0,此处标签,是100.0不是100,因为前面已经为整型数据,整型除整型依旧为整型,只有除100.0,int数据类型才会强制转换为float或者double类型
                                            
                                            private double SaveDecimal(double n){
                                                    return n = ((int)(n*100))/100.0;
                                                }
                                            

                                            概览

                                            效果预览

                                            简述

                                            此界面显示的内容包括共计收入、支出多少笔和合计收入、支出多少金额,以及通过标签分类显示支出、收入占比,以及全部收入、支出记录中前三甲。

                                            分类显示

                                            通过获取单个标签的所有金额除以全部标签的总金额,获取百分比占比,并通过view进行显示,条形bar通过获取屏幕宽度,例如:我的手机屏幕宽度为1080,就以数码电器为例:11998.99/总金额 * 1080 = 条形bar的长度

                                            百分比占比同样以数码电器为例:11998.99/总金额 * 100 = 数码电器百分比

                                            创建适配器

                                            public class BarAdapter extends RecyclerView.Adapter {
                                                private String[] s_select = {"日用百货", "文化休闲", "交通出行", "生活服务", "服装装扮", "餐饮美食", "数码电器", "其他标签"};
                                                private int[] img_select = {
                                                        R.drawable.icon_type_one,
                                                        R.drawable.icon_type_two,
                                                        R.drawable.icon_type_three,
                                                        R.drawable.icon_type_four,
                                                        R.drawable.icon_type_five,
                                                        R.drawable.icon_type_six,
                                                        R.drawable.icon_type_seven,
                                                        R.drawable.icon_type_eight};
                                                private List viewBarList;
                                                public BarAdapter(List viewBarList) {
                                                    this.viewBarList = viewBarList;
                                                }
                                                @NonNull
                                                @Override
                                                public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
                                                    View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.pay_type_item, parent, false);
                                                    return new ViewHolder(view);
                                                }
                                                @Override
                                                public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
                                                    int w = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
                                                    int h = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
                                                    holder.item_bar.measure(w, h);
                                                    ViewBar viewBar = viewBarList.get(position);
                                                    holder.item_bar.setLayoutParams(new LinearLayout.LayoutParams(viewBar.getWidth(), viewBar.getHeight()));
                                                    holder.item_label.setText(viewBar.getLabel());
                                                    holder.item_num.setText(viewBar.getNum());
                                                    holder.item_price.setText(viewBar.getPrice());
                                                    Log.d("testLabel",viewBar.getLabel());
                                                    for (int i = 0; i < 8; i++) {
                                                        if (viewBar.getLabel().trim().equals(s_select[i])){
                                                            Log.d("testLabel",viewBar.getLabel());
                                                            holder.item_img.setImageResource(img_select[i]);
                                                        }
                                                    }
                                                }
                                                @Override
                                                public int getItemCount() {
                                                    return viewBarList.size();
                                                }
                                                class ViewHolder extends RecyclerView.ViewHolder {
                                                    private TextView item_label, item_num, item_price;
                                                    private ImageView item_img;
                                                    private View item_bar;
                                                    public ViewHolder(@NonNull View itemView) {
                                                        super(itemView);
                                                        item_label = itemView.findViewById(R.id.pay_type_label);
                                                        item_num = itemView.findViewById(R.id.pay_type_num);
                                                        item_price = itemView.findViewById(R.id.pay_type_price);
                                                        item_img = itemView.findViewById(R.id.pay_type_img);
                                                        item_bar = itemView.findViewById(R.id.pay_type_bar);
                                                    }
                                                }
                                            }
                                            

                                            获取数据源

                                            获取屏幕宽度,以此作为基数

                                            manager = requireActivity().getWindowManager();
                                             width = manager.getDefaultDisplay().getWidth();
                                            
                                            private void getData(){
                                                    if (TotalPrice <= 0)return;
                                                    for (int i = 0; i < d_price.length; i++) {
                                                        if (d_price[i] == 0)continue;
                                                        int n = (int) (d_price[i] / TotalPrice * width);
                                                        double t = SaveDecimal(d_price[i] / TotalPrice * 100);
                                                        barList.add(new ViewBar(s_select[i]+"   ",t+"%","¥"+d_price[i],n,10));
                                                    }
                                                }
                                            

                                            前三甲

                                            通过比较所有账单记录,根据金额升序获取前三甲

                                            创建适配器

                                            public class RankAdapter extends RecyclerView.Adapter {
                                                private int[] img_select = {
                                                        R.drawable.gold,
                                                        R.drawable.silver,
                                                        R.drawable.tongpai,
                                                       };
                                                private List rankLists;
                                                public RankAdapter(List rankLists){
                                                    this.rankLists = rankLists;
                                                }
                                                @NonNull
                                                @Override
                                                public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
                                                    View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.ranking_list_item,parent,false);
                                                    return new ViewHolder(view);
                                                }
                                                @Override
                                                public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
                                                    RankList rank = rankLists.get(position);
                                                    holder.item_label.setText("["+rank.getLabel()+"]");
                                                    holder.item_content.setText(rank.getContent());
                                                    if (rank.getType() == 1){
                                                        holder.item_price.setText("-"+rank.getPrice());
                                                    }else {
                                                        holder.item_price.setText("+"+rank.getPrice());
                                                    }
                                                    switch (rank.getPosition()){
                                                        case 1:
                                                            holder.item_img.setImageResource(img_select[0]);
                                                            break;
                                                        case 2:
                                                            holder.item_img.setImageResource(img_select[1]);
                                                            break;
                                                        case 3:
                                                            holder.item_img.setImageResource(img_select[2]);
                                                            break;
                                                    }
                                                }
                                                @Override
                                                public int getItemCount() {
                                                    return rankLists.size();
                                                }
                                                class ViewHolder extends RecyclerView.ViewHolder{
                                                    private TextView item_label,item_content,item_price;
                                                    private ImageView item_img;
                                                    public ViewHolder(@NonNull View itemView) {
                                                        super(itemView);
                                                        item_label = itemView.findViewById(R.id.Rank_label);
                                                        item_content = itemView.findViewById(R.id.Rank_name);
                                                        item_price = itemView.findViewById(R.id.Rank_price);
                                                        item_img = itemView.findViewById(R.id.Rank_img);
                                                    }
                                                }
                                            }
                                            

                                            获取数据源

                                            代码虽不比递归以及排序整洁,但是时间复杂度控制在0(n),效率比冒泡排序、快速排序等要高一点

                                             /**
                                                 * 选出账单支出前三甲*/
                                                private void getRankings(){
                                                    if (recordList.size() == 0 || recordList == null)return;
                                                    double maxPrice = -32768,midPrice = -32768,lowPrice = -32768;
                                                    int maxIndex = -1,midIndex = -1,lowIndex = -1;
                                                    for (int i = 0; i < recordList.size(); i++) {
                                                        double price = Double.parseDouble(recordList.get(i).getGoodsPrice());
                                                        if ( price > maxPrice){
                                                            lowPrice = midPrice;
                                                            lowIndex = midIndex;
                                                            midPrice = maxPrice;
                                                            midIndex = maxIndex;
                                                            maxPrice = price;
                                                            maxIndex = i;
                                                        }
                                                        if (price < maxPrice && price > midPrice){
                                                            lowPrice = midPrice;
                                                            lowIndex = midIndex;
                                                            midPrice = price;
                                                            midIndex = i;
                                                        }
                                                        if (price < maxPrice && price < midPrice && price > lowPrice){
                                                            lowPrice = price;
                                                            lowIndex = i;
                                                        }
                                                    }
                                                    int[] poi = {maxIndex,midIndex,lowIndex};
                                                    for (int i = 0; i < 3; i++) {
                                                        if (poi[i] == -1)continue;
                                                        rankListList.add(new RankList(i+1,recordList.get(poi[i]).getLabel(),recordList.get(poi[i]).getGoodsName(),recordList.get(poi[i]).getGoodsPrice(),recordList.get(poi[i]).getType()));
                                                    }
                                                }
                                            

                                            单标签总价以及总金额

                                             /**
                                                 * 获取单个标签总价以及所有商品总价*/
                                                private void getPrice(){
                                                    if (recordList.size() == 0 || recordList == null)return;
                                                    d_price = new double[s_select.length];
                                                    for (int i = 0; i < recordList.size(); i++) {
                                                        for (int j = 0; j < s_select.length; j++) {
                                                            if (recordList.get(i).getLabel().equals(s_select[j])){
                                                                d_price[j] += Double.parseDouble(recordList.get(i).getGoodsPrice());
                                                                TotalPrice += Double.parseDouble(recordList.get(i).getGoodsPrice());
                                                                break;
                                                            }
                                                        }
                                                    }
                                                }
                                            

                                            可视化概览

                                            效果预览

                                            简述

                                            本可视化图表工具采用的是AAChartView,此工具相对于老牌MPChartView和HelloChartView而言,使用更加简单,种类更加齐全,重点是粉粉嫩嫩,但他的导入方式与其他不同,不是通过导入闭包进行使用;而且通过复制它到一些文件到自己工程项目中,其样式使用的js写的,所有需要导入一些js文件以及一些其他java文件。这一点不比导入闭包方便。根据需要进行选择使用。

                                            折线图

                                            通过aa_drawChartWithChartModel()方法获取AAChartModel对象即可,使用超级简单

                                            lineChartView.aa_drawChartWithChartModel(InitLineChart());
                                            

                                            然后可通过配置一些参数,更加形象化图表

                                            例如:categories 为 x轴数据源,类型为String[]
                                            yAxisMin 为 y轴数据源最小值
                                            yAxisMax 为 y轴数据源最大值
                                            series 为 每个数据点的提示内容,其中name为标题;data为数据,类型为Object[]
                                            
                                            private  AAChartModel InitLineChart() {
                                                    return new AAChartModel()
                                                            .chartType(AAChartType.Areaspline)
                                                            .legendEnabled(false)
                                                            .yAxisVisible(true)
                                                            .markerRadius(6f)
                                                            .markerSymbolStyle(AAChartSymbolStyleType.InnerBlank)
                                                            .zoomType(AAChartZoomType.XY)
                                                            .categories(s_select)
                                                            .yAxisMin(2.0f)//Y轴数据最大值和最小值范围
                                                            .yAxisMax(2000.0f)
                                                            .xAxisTickInterval(2)
                                                            .series(new AASeriesElement[]{
                                                                    new AASeriesElement()
                                                                            .name("合计")
                                                                            .color("#2494F3")
                                                                            .data( getPrice())
                                                            });
                                                }
                                            
                                            获取数据源

                                            由于需要的是Object[] 类型数据,所有需要将string类型数据转为double,然后将double转为Double类型,然后进行强制转换,最后变为Object类型

                                            private Object[] getPrice(){
                                                    if (recordList.size() == 0 || recordList == null)return null;
                                                    double[] d_price = new double[s_select.length];
                                                    Object[] o_price = new Object[s_select.length];
                                                    for (int i = 0; i < recordList.size(); i++) {
                                                        for (int j = 0; j < s_select.length; j++) {
                                                            if (recordList.get(i).getLabel().equals(s_select[j])){
                                                                Log.d("DetailedActivity",Double.parseDouble(recordList.get(i).getGoodsPrice())+"");
                                                                d_price[j] += Double.parseDouble(recordList.get(i).getGoodsPrice());
                                                                break;
                                                            }
                                                        }
                                                    }
                                                    for (int i = 0; i < s_select.length; i++) {
                                                        o_price[i] = new Double(d_price[i]);
                                                    }
                                                    return o_price;
                                                }
                                            

                                            南丁格尔玫瑰图

                                            同样适用aa_drawChartWithChartModel方法进行数据体现,同时无论什么类型的图表类型,都知使用AAChartView控件,并且只需要返回AAChartModel对象,这极大程度方便进行封装使用

                                            mapChartView.aa_drawChartWithChartModel(InitRoseChart());
                                            
                                             private AAChartModel InitRoseChart() {
                                                    return new AAChartModel()
                                                            .yAxisTitle("cm")
                                                            .chartType(AAChartType.Column)
                                                            .xAxisVisible(false)//是否显示最外一层圆环
                                                            .yAxisVisible(true)//是否显示中间的多个圆环
                                                            .yAxisAllowDecimals(true)
                                                            .legendEnabled(false)//隐藏图例(底部可点按的小圆点)
                                                            .categories(getTitles())
                                                            .dataLabelsEnabled(true)
                                                            .polar(true)//极地化图形
                                                            .series(new AASeriesElement[]{
                                                                            new AASeriesElement()
                                                                                    .name("价格")
                                                                                    .data(getRosePrice()),
                                                                    }
                                                            );
                                                }
                                            
                                            获取数据源
                                             /**
                                                 * 南丁格尔玫瑰图数据源x*/
                                                private Object[] getRosePrice(){
                                                    if (recordList.size() == 0 || recordList == null)return null;
                                                    double[] d_price = new double[recordList.size()];
                                                    Object[] o_price = new Object[recordList.size()];
                                                    for (int i = 0; i < recordList.size(); i++) {
                                                        d_price[i] = Double.parseDouble(recordList.get(i).getGoodsPrice());
                                                    }
                                                    for (int i = 0; i < recordList.size(); i++) {
                                                        o_price[i] = new Double(d_price[i]);
                                                    }
                                                    return o_price;
                                                }
                                            

                                            记录删除

                                            效果图

                                            首先删除数据库中的对象,然后删除当前列表数据

                                             adapter.setDeleteListener(new OrderAdapter.onDeleteListener() {
                                                        @Override
                                                        public void onClickListener(int pos, Record bean) {
                                                            dao.Delete(bean.getGoodsName());
                                                            recordList.remove(pos);
                                                            adapter.notifyDataSetChanged();
                                                            EventBus.getDefault().postSticky(new UpdateBean(false));
                                                        }
                                                    });
                                            

                                            尾言

                                            此代码为刚入门所敲,很多不足之处,最近有很多人找我要此项目代码,修复了一些Bug,增加删除功能,但由于之前技术不足,框架构建不是很好,无心去重构,再次感谢大家的厚爱