专属空间二-记账本的实现

      今天是进行专属空间app开发的第二天。首先来说一下今天学到的东西吧。主要有以下几点:

  1、学到创建SQLite数据库的创建,并且在数据库中存取数据并且展示到Listview上;

  2、重新用到了Adapter,相当于是在再加工了一下,当然也学到了新的东西;

  3、学习了FloatingActionButton的用法。

        android:src:FAB中显示的图标.

        app:backgroundTint:正常的背景颜色 ,这里是ColorStateList类型

        app:rippleColor:按下时的背景颜色

        app:elevation:正常的阴影大小

        app:pressedTranslationZ:按下时的阴影大小

        app:layout_anchor:设置FAB的锚点,即以哪个控件为参照设置位置

        app:layout_anchorGravity:FAB相对于锚点的位置

        app:fabSize:FAB的大小,normal或mini(分别对应56dp和40dp)

        app:borderWidth:边框大小,最好设置成0dp否则会有边框

        android:clickable:一定要设置成true否则没有点击效果

    


  4、对第三方库有了点了解,具体是用到了加载图表库的依赖 链接:https://github.com/lecho/hellocharts-android
 
  下面就来说项目的进展吧。今天完成的是主界面的布局和跳转的实现,以及跳转以后的记账本的实现。
  
  第二张图就是跳转到记账本的主界面,主要用的是ListView和FloatingActionButton搭建的。
  点击右下角的那个FloatingActionButton组件跳转到的是第三张图,是来添加记账信息的,主要由标题、花销、日期构成。
  点击ok就会跳到记账本得主界面,也就是第二张图,同时数据会保存在数据库中,数据在主界面也会刷新显示。
  第四张图暂时就比较粗糙了,是点击图表跳到的由金额,及事件构成的折线图,由每天的消费总额(y)以及日期(x)所形成的点然后连成的折线,让你有一个大致的了解。
  下面是所编辑的代码:
  VoiceActivity.java
  
package com.example.personspace.ModelVoice;

import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;

import android.content.DialogInterface;
import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.DatePicker;
import android.widget.EditText;
import android.widget.ListView;

import com.example.personspace.MainActivity;
import com.example.personspace.R;
import com.google.android.material.floatingactionbutton.FloatingActionButton;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

public class VoiceActivity extends AppCompatActivity {
    private List<CostBean> mCostBeanList;
    private DatabaseHelper mDatabaseHelper;
    private CostListAdapter mAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_voice);
        mDatabaseHelper = new DatabaseHelper(this);
        mCostBeanList = new ArrayList<>();
        ListView costList = (ListView) findViewById(R.id.lv_main);

        // 初始化一些数据
        initCostData();
        mAdapter = new CostListAdapter(this, mCostBeanList);
        costList.setAdapter(mAdapter);


        FloatingActionButton fab = findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                AlertDialog.Builder builder = new AlertDialog.Builder(VoiceActivity.this);

                //需要修改上下
                LayoutInflater inflater = LayoutInflater.from(VoiceActivity.this);
                View viewDialog = inflater.inflate(R.layout.activity_nev_cost_data, null);
                final EditText title = viewDialog.findViewById(R.id.et_cost_title);
                final EditText money = viewDialog.findViewById(R.id.et_cost_money);
                final DatePicker date = viewDialog.findViewById(R.id.dp_cost_date);
                builder.setView(viewDialog);
                builder.setTitle("New Cost");
                builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        CostBean costBean = new CostBean();
                        costBean.costTitle = title.getText().toString();
                        costBean.costMoney = money.getText().toString();
                        costBean.costDate = date.getYear() + "-" + (date.getMonth() + 1) + "-" +
                                date.getDayOfMonth();
                        mDatabaseHelper.insertCost(costBean);
                        mCostBeanList.add(costBean);
                        //刷新数据并显示
                        mAdapter.notifyDataSetChanged();
                    }
                });
                builder.setNegativeButton("Cancel", null);
                builder.create().show();
            }
        });


    }


    private void initCostData() {
        //mDatabaseHelper.deleteAllData();
        /** for (int i = 0; i < 6; i++) {
         CostBean costBean = new CostBean();
         costBean.costTitle = "moke";
         costBean.costDate = "11-11";
         costBean.costMoney = "20";
         mDatabaseHelper.insertCost(costBean);
         }
         */
        Cursor cursor = mDatabaseHelper.getAllCostData();
        if (cursor != null) {
            while (cursor.moveToNext()) {
                CostBean costBean = new CostBean();
                costBean.costTitle = cursor.getString(cursor.getColumnIndex("cost_title"));
                costBean.costDate = cursor.getString(cursor.getColumnIndex("cost_date"));
                costBean.costMoney = cursor.getString(cursor.getColumnIndex("cost_money"));

                mCostBeanList.add(costBean);
            }
            cursor.close();


        }
    }

    public void Huan(View view) {

        Intent intent = new Intent(this, ChartsActivity.class);
        intent.putExtra("cost_list", (Serializable) mCostBeanList);
        startActivity(intent);


    }
    public void IncludeToMain(View view) {

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


    }
}

对应的xml文件:Activity_voice.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout  xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.personspace.ModelVoice.VoiceActivity"
    android:background="@mipmap/back"
    >

    <com.google.android.material.appbar.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        >



    </com.google.android.material.appbar.AppBarLayout>

    <include layout="@layout/content_main" />

    <com.google.android.material.floatingactionbutton.FloatingActionButton
        android:id="@+id/fab"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom|end"
        android:layout_margin="16sp"
        app:srcCompat="@android:drawable/ic_dialog_email" />

</androidx.coordinatorlayout.widget.CoordinatorLayout>

以及content_main.xml这个是用来嵌入到voice.xml中的

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    tools:context="com.example.personspace.ModelVoice.VoiceActivity"
    tools:showIn="@layout/activity_main">
    <RadioGroup
        android:layout_width="match_parent"
        android:layout_height="80dp"
        android:orientation="horizontal">
        <RadioButton
            android:layout_width="0dp"
            android:layout_weight="1"
            android:layout_height="80dp"
            android:text="返回"
            android:textSize="25sp"
            android:button="@null"
            android:gravity="center"
            android:onClick="IncludeToMain"
            />
        <RadioButton
            android:layout_width="0dp"
            android:layout_weight="1"
            android:layout_height="80dp"
            android:text="图表"
            android:textSize="25sp"
            android:button="@null"
            android:gravity="center"
            android:onClick="Huan"
            />

    </RadioGroup>


    <ListView
        android:layout_marginTop="80dp"
        android:id="@+id/lv_main"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</RelativeLayout>

接下来是数据库的帮助类:DataBaseHelper.java

package com.example.personspace.ModelVoice;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

import androidx.annotation.Nullable;

public class DatabaseHelper extends SQLiteOpenHelper {

    public static final String COST_MONEY = "cost_money";
    public static final String COST_DATE = "cost_date";
    public static final String COST_TITLE = "cost_title";


    public DatabaseHelper(@Nullable Context context) {
        super(context,"daily",null,1);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL("create table if not exists include_cost("+

                "id integer primary key, "+
                "cost_title varchar, "+
                "cost_date varchar, "+
                "cost_money varchar)"
        );

    }
    public void insertCost(CostBean costBean){
        SQLiteDatabase database = getWritableDatabase();
        ContentValues cv = new ContentValues();
        cv.put(COST_TITLE,costBean.costTitle);
        cv.put(COST_DATE,costBean.costDate);
        cv.put(COST_MONEY,costBean.costMoney);
        database.insert("include_cost",null,cv);

    }

    public Cursor getAllCostData(){
        SQLiteDatabase database = getWritableDatabase();
        return database.query("include_cost",null,null,null,null,null,COST_DATE+" ASC");
    }


    public void deleteAllData(){
        SQLiteDatabase database = getWritableDatabase();
        database.delete("include_cost",null,null);


    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

    }
}

接下来是实体类以及保存数据和显示数据到listView的代码:CostBean.java和CostListAdapter.java

package com.example.personspace.ModelVoice;

import java.io.Serializable;

public class CostBean implements Serializable {
    public String costTitle;
    public String costDate;
    public String costMoney;
}
package com.example.personspace.ModelVoice;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;

import com.example.personspace.R;

import java.util.List;

public class CostListAdapter extends BaseAdapter {
    private List<CostBean> mList;
    private Context mContext;
    private LayoutInflater mLayoutInflater;




    public CostListAdapter(Context context, List<CostBean> list) {
        mContext= context;
        mList=list;
        mLayoutInflater=LayoutInflater.from(context);
    }


    @Override
    public int getCount() {
        return mList.size();
    }

    @Override
    public Object getItem(int position) {
        return mList.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder viewHolder;
        if (convertView==null){
            viewHolder=new ViewHolder();
            convertView=mLayoutInflater.inflate(R.layout.list_item,null);
            viewHolder.mTvCostTitle=convertView.findViewById(R.id.include_title);
            viewHolder.mTvCostDate=convertView.findViewById(R.id.include_date);
            viewHolder.mTvCostMoney=convertView.findViewById(R.id.include_cost);
            convertView.setTag(viewHolder);
        }else{
            viewHolder=(ViewHolder) convertView.getTag();

        }
        CostBean costBean=mList.get(position);
        viewHolder.mTvCostTitle.setText(costBean.costTitle);
        viewHolder.mTvCostDate.setText(costBean.costDate);
        viewHolder.mTvCostMoney.setText(costBean.costMoney);



        return convertView;
    }



    private static class ViewHolder{
        public TextView mTvCostTitle;
        public TextView mTvCostDate;
        public TextView mTvCostMoney;

    }


}

接下来是用在Listview的xml文件:list_item.xml

<?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="80dp"
    android:orientation="vertical"
    >
    <TextView
        android:id="@+id/include_title"
        android:layout_width="100dp"
        android:layout_height="80dp"
        android:layout_marginLeft="10dp"
        android:layout_alignParentLeft="true"
        android:gravity="center"
        android:singleLine="true"
        android:ellipsize="marquee"
        android:textSize="35sp"
        android:text="costtitle"/>
    <TextView
        android:id="@+id/include_date"
        android:layout_width="wrap_content"
        android:layout_height="80dp"
        android:layout_toRightOf="@id/include_title"
        android:gravity="center"
        android:textSize="20sp"
        android:layout_marginLeft="15dp"
        android:text="CostDate"/>
    <TextView
        android:id="@+id/include_cost"
        android:layout_width="wrap_content"
        android:layout_height="80dp"
        android:gravity="center"
        android:text="30"
        android:textSize="30sp"
        android:layout_marginRight="20dp"
        android:layout_alignParentRight="true"
        />

</RelativeLayout>

接下来是点击FloatingActionButton的组件所跳转的页面:activity_nev_cost_data.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:gravity="center"
    >
    <EditText
        android:id="@+id/et_cost_title"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="4dp"
        android:hint="Cost Title"
        />
    <EditText
        android:id="@+id/et_cost_money"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="4dp"
        android:hint="Cost Money"
        />
    <DatePicker
        android:id="@+id/dp_cost_date"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="4dp"
        android:datePickerMode="spinner"
        android:calendarViewShown="false"/>




</LinearLayout>

然后是ChartsActivity.java和对应的xml文件Activity_charts.xml

package com.example.personspace.ModelVoice;

import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;

import com.example.personspace.R;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import lecho.lib.hellocharts.model.Line;
import lecho.lib.hellocharts.model.LineChartData;
import lecho.lib.hellocharts.model.PointValue;
import lecho.lib.hellocharts.model.ValueShape;
import lecho.lib.hellocharts.util.ChartUtils;
import lecho.lib.hellocharts.view.LineChartView;

public class ChartsActivity extends AppCompatActivity {
    private LineChartView mChart;
    private Map<String,Integer> table = new TreeMap<>();
    private LineChartData mData;


    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_charts);
        mChart = findViewById(R.id.chart);
        mData = new LineChartData();
        List<CostBean> allDate = (List<CostBean>) getIntent().getSerializableExtra("cost_list");
        generateValues(allDate);
        generateData();
    }

    private void generateData() {
        List<Line> lines = new ArrayList<>();
        List<PointValue> values = new ArrayList<>();
        int indexX = 0;
        for(Integer value : table.values()){
            values.add(new PointValue(indexX, value));
            indexX++;
        }
        Line line = new Line(values);
        line.setColor(ChartUtils.COLORS[0]);
        line.setShape(ValueShape.CIRCLE);
        line.setPointColor(ChartUtils.COLORS[1]);
        lines.add(line);
        mData.setLines(lines);
        mChart.setLineChartData(mData);
    }

    private void generateValues(List<CostBean> allDate) {
        if(allDate != null){
            for (int i = 0; i < allDate.size(); i++) {
                CostBean costBean = allDate.get(i);
                String costDate = costBean.costDate;
                int costMoney = Integer.parseInt(costBean.costMoney);
                if(!table.containsKey(costDate)){
                    table.put(costDate,costMoney);
                }else {
                    int originMoney = table.get(costDate);
                    table.put(costDate,originMoney+costMoney);
                }
            }
        }
    }
}
<?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:orientation="vertical"
    android:padding="10dp"
    >
    <lecho.lib.hellocharts.view.LineChartView
        android:id="@+id/chart"
        android:padding="20dp"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</LinearLayout>

今天的任务到此结束,好累啊!!!

 
 
    
原文地址:https://www.cnblogs.com/moxihuishou/p/13334379.html