安卓练习之——记账软件

这是一个简单的账本,目前的功能可以实现记账,显示总的支出、收入、结余,查看账单以及删除不想要的账单。后续功能慢慢完善。那么就开始代码和图演示。
如果有不足的地方,希望看到的大神给予指点建议,不胜感激!

1.页面介绍:左侧侧滑菜单,实现功能还在施工,可以加一些设置之类。
首页使用ViewPager+Fragment分为两页,首页实现总账目,第二页实现记账和查看账单。
这里写图片描述

2.左侧滑菜单:通过HorizontalScrollView实现

package view;

import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.TypedValue;
import android.view.MotionEvent;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.HorizontalScrollView;
import android.widget.LinearLayout;

import com.chase.cn.demon.R;
import com.nineoldandroids.view.ViewHelper;

/**
 * Created by Chase on 2016/11/7.
 */

public class SlidingMenu extends HorizontalScrollView {
    private LinearLayout mWapper;
    private ViewGroup mMenu;
    private ViewGroup mContent;
    private int mScreenWidth;

    private int mMenuWidth;
    private int mMenuRightPadding = 50;
    private boolean once;

    private boolean isOpen;

    /**
     * 未使用自定义属性时,调用
     *
     * @param context
     * @param attrs
     */
    public SlidingMenu(Context context, AttributeSet attrs)
    {
        this(context, attrs, 0);
    }

    /**
     * 当使用了自定义属性时,会调用此构造方法
     *
     * @param context
     * @param attrs
     * @param defStyle
     */
    public SlidingMenu(Context context, AttributeSet attrs, int defStyle)
    {
        super(context, attrs, defStyle);

        // 获取我们定义的属性
        TypedArray a = context.getTheme().obtainStyledAttributes(attrs,
                R.styleable.SlidingMenu, defStyle, 0);

        int n = a.getIndexCount();
        for (int i = 0; i < n; i++)
        {
            int attr = a.getIndex(i);
            switch (attr)
            {
                case R.styleable.SlidingMenu_rightPadding:
                    mMenuRightPadding = a.getDimensionPixelSize(attr,
                            (int) TypedValue.applyDimension(
                                    TypedValue.COMPLEX_UNIT_DIP, 50, context
                                            .getResources().getDisplayMetrics()));
                    break;
            }
        }
        a.recycle();

        //获取屏幕宽高
        WindowManager wm = (WindowManager) context
                .getSystemService(Context.WINDOW_SERVICE);
        DisplayMetrics outMetrics = new DisplayMetrics();
        wm.getDefaultDisplay().getMetrics(outMetrics);
        mScreenWidth = outMetrics.widthPixels;

    }

    public SlidingMenu(Context context)
    {
        this(context, null);
    }

    /**
     * 设置子View的宽和高 设置自己的宽和高
     */
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
    {
        if (!once)
        {
            mWapper = (LinearLayout) getChildAt(0);
            mMenu = (ViewGroup) mWapper.getChildAt(0);
            mContent = (ViewGroup) mWapper.getChildAt(1);
            mMenuWidth = mMenu.getLayoutParams().width = mScreenWidth
                    - mMenuRightPadding;
            mContent.getLayoutParams().width = mScreenWidth;
            once = true;
        }
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

    /**
     * 通过设置偏移量,将menu隐藏
     */
    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b)
    {
        super.onLayout(changed, l, t, r, b);
        if (changed)
        {
            this.scrollTo(mMenuWidth, 0);
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev)
    {
        int action = ev.getAction();
        switch (action)
        {
            case MotionEvent.ACTION_UP:
                // 隐藏在左边的宽度
                int scrollX = getScrollX();
                if (scrollX >= mMenuWidth / 2)
                {
                    this.smoothScrollTo(mMenuWidth, 0);
                    isOpen = false;
                } else
                {
                    this.smoothScrollTo(0, 0);
                    isOpen = true;
                }
                return true;
        }
        return super.onTouchEvent(ev);
    }

    //切换菜单按钮的开关逻辑
    public void openMenu(){
        if (isOpen)return;
        this.smoothScrollTo(0,0);
        isOpen = true;
    }

    public void closeMenu(){
        if (!isOpen)return;
        this.smoothScrollTo(mMenuWidth,0);
        isOpen = false;
    }


    public void  toggle(){
        if (isOpen){
            closeMenu();
        }else
        {
            openMenu();
        }
    }

    //抽屉菜单
    @Override
    protected void onScrollChanged(int l, int t, int oldl, int oldt) {

        super.onScrollChanged(l, t, oldl, oldt);
        float scale = l * 1.0f / mMenuWidth; // 1 ~ 0
        float leftAlpha = 0.6f + 0.4f * (1 - scale);
        // 调用属性动画,设置TranslationX
        ViewHelper.setTranslationX(mMenu, l);
        ViewHelper.setAlpha(mMenu, leftAlpha);

    }
}

其中两个子View,Content和Menu:

下面是Content的xml文件,其中content部分包含了ViewPager。

<?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="#dbd0a7"
    android:orientation="vertical"
    android:weightSum="1">

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

    <android.support.v4.view.ViewPager
        android:id="@+id/content_viewPager"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        >

        <!--Fragment的Tab-->
        <android.support.v4.view.PagerTabStrip  
            android:id="@+id/tab"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            >

        </android.support.v4.view.PagerTabStrip>

    </android.support.v4.view.ViewPager>

</LinearLayout>

其中上面的文件include的Title bar文件如下,其实就是一个Fragment

<?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:orientation="horizontal"
    android:background="#e69b03"
    >

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="toggleMenu"
        android:text="切换菜单"
        android:textColor="#ffffff"
        />

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="MyMoney"
        android:gravity="center_horizontal"
        android:textSize="20sp"
        />
</RelativeLayout>

下面是LeftMenu的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="match_parent"
    android:background="#d1494e"
    >

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:orientation="vertical">

        <RelativeLayout
            android:layout_width="fill_parent"
            android:layout_height="wrap_content">

            <ImageView
                android:id="@+id/image1"
                android:layout_width="50dp"
                android:layout_height="50dp"
                android:layout_centerVertical="true"
                android:layout_marginLeft="20dp"
                android:layout_marginTop="20dp"
                android:src="@mipmap/ic_launcher" />

            <TextView
                android:layout_centerVertical="true"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_toRightOf="@id/image1"
                android:text="施工中1"
                android:textColor="#ffffff"
                android:layout_marginLeft="20dp"
                android:textSize="20sp" />

        </RelativeLayout>

        <RelativeLayout
            android:layout_width="fill_parent"
            android:layout_height="wrap_content">

            <ImageView
                android:id="@+id/image2"
                android:layout_width="50dp"
                android:layout_height="50dp"
                android:layout_centerVertical="true"
                android:layout_marginLeft="20dp"
                android:layout_marginTop="20dp"
                android:src="@mipmap/ic_launcher" />

            <TextView
                android:layout_centerVertical="true"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_toRightOf="@id/image2"
                android:text="施工中2"
                android:textColor="#ffffff"
                android:layout_marginLeft="20dp"
                android:textSize="20sp" />

        </RelativeLayout>

        <RelativeLayout
            android:layout_width="fill_parent"
            android:layout_height="wrap_content">

            <ImageView
                android:id="@+id/image3"
                android:layout_width="50dp"
                android:layout_height="50dp"
                android:layout_centerVertical="true"
                android:layout_marginLeft="20dp"
                android:layout_marginTop="20dp"
                android:src="@mipmap/ic_launcher" />

            <TextView
                android:layout_centerVertical="true"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_toRightOf="@id/image3"
                android:text="施工中3"
                android:textColor="#ffffff"
                android:layout_marginLeft="20dp"
                android:textSize="20sp" />

        </RelativeLayout>

        <RelativeLayout
            android:layout_width="fill_parent"
            android:layout_height="wrap_content">

            <ImageView
                android:id="@+id/image4"
                android:layout_width="50dp"
                android:layout_height="50dp"
                android:layout_centerVertical="true"
                android:layout_marginLeft="20dp"
                android:layout_marginTop="20dp"
                android:src="@mipmap/ic_launcher" />

            <TextView
                android:layout_centerVertical="true"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_toRightOf="@id/image4"
                android:text="施工中4"
                android:textColor="#ffffff"
                android:layout_marginLeft="20dp"
                android:textSize="20sp" />

        </RelativeLayout>


    </LinearLayout>


</RelativeLayout>

现在来看MainActivity:

package com.chase.cn.demon;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.view.PagerTabStrip;
import android.support.v4.view.ViewPager;
import android.view.View;
import android.view.Window;

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

import view.SlidingMenu;


public class MainActivity extends FragmentActivity {

    private SlidingMenu mLeftMennu;
    private ViewPager mContentPager;
    private List<Fragment> fragList;
    private List<String> tabList;
    private PagerTabStrip myTab;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.activity_main);
        mLeftMennu = (SlidingMenu) findViewById(R.id.leftMenu);

        //fragment的数据源
        fragList = new ArrayList<Fragment>();
        fragList.add(new Content_Fragment1());
        fragList.add(new Content_Fragment2());
        //tab的数据源
        tabList = new ArrayList<String>();
        tabList.add("首页");
        tabList.add("我的账本");

        MyFragmentPagerAdapter pagerAdapter = new MyFragmentPagerAdapter(getSupportFragmentManager(), fragList, tabList);

        mContentPager = (ViewPager) findViewById(R.id.content_viewPager);
        mContentPager.setAdapter(pagerAdapter);

        myTab = (PagerTabStrip) findViewById(R.id.tab);
        myTab.setDrawFullUnderline(false);
        myTab.setTextSpacing(5);

    }



    public void toggleMenu(View v) {
        mLeftMennu.toggle();
    } //切换菜单按键

}

MainActivity的xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:chase="http://schemas.android.com/apk/res-auto"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <view.SlidingMenu
        android:id="@+id/leftMenu"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        chase:rightPadding="150dp">

        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:orientation="horizontal">
            <!--引入左菜单-->
            <include layout="@layout/leftmenu" />

            <!--内容区域-->
            <include layout="@layout/content" />

        </LinearLayout>

    </view.SlidingMenu>


</RelativeLayout>

MainActivity用到的FragmentAdapter如下:

package com.chase.cn.demon;

import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;

import java.util.List;

/**
 * Created by Chase on 2016/11/8.
 */

public class MyFragmentPagerAdapter extends FragmentPagerAdapter{
    private List<Fragment> fragList;
    private List<String> tabList;

    public MyFragmentPagerAdapter(FragmentManager fm, List<Fragment> fragList, List<String> tabList) {
        super(fm);
        this.fragList = fragList;
        this.tabList = tabList;
    }

    @Override
    public CharSequence getPageTitle(int position) {
        return tabList.get(position);
    }

    @Override
    public Fragment getItem(int position) {
        return fragList.get(position);
    }

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

因为主要功能是在Fragment里实现的,所以两个页面的Fragment中来写代码,首先先建立数据库,使用SQLiteOpenHelper:

package com.chase.cn.demon;

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

/**
 * Created by Chase on 2016/11/8.
 */

public class MySQLiteOpenHelper extends SQLiteOpenHelper {


    public MySQLiteOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
        super(context, name, null, 1);
    }


    //首次创建时调用 一般用于建库 建表
    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL("create table if not exists finance" +
                "(_id integer primary key autoincrement," +
                "Type varchar(10)," +
                "Time varchar(20)," +
                "Fee double," +
                "Budget varchar(10))");
    }

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

    }
}

Fragment1的代码:

package com.chase.cn.demon;

import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.os.Handler;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

/**
 * Created by Chase on 2016/11/8.
 */

public class Content_Fragment1 extends android.support.v4.app.Fragment {
    private MySQLiteOpenHelper mSqlHelper;
    private SQLiteDatabase mDataBase;
    private TextView textRemaind,textPay,textIncome;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View pager1 = inflater.inflate(R.layout.fragment_page1, container, false);

        //初始统计值
        double resultPay = 0, resultIncome = 0, resultRemain = 0;
        textRemaind = (TextView) pager1.findViewById(R.id.resultRemain);
        textPay = (TextView) pager1.findViewById(R.id.resultPay);
        textIncome = (TextView) pager1.findViewById(R.id.resultIncome);

        //sqliteOpenHelper创建数据库

        mTimeHandler.sendEmptyMessageDelayed(0, 1000);

        return pager1;
    }

    @Override
    public void onDestroy() {
        mTimeHandler.removeCallbacksAndMessages(null);

        mSqlHelper.close();
        mDataBase.close();
        super.onDestroy();
    }

    //跑一个线程handle 动态更新textView
    public Handler mTimeHandler = new Handler() {
        public void handleMessage(android.os.Message msg) {

            if (msg.what == 0) {
                double resultPay = 0, resultIncome = 0, resultRemain = 0;
                mSqlHelper = new MySQLiteOpenHelper(getActivity(), "finance.db", null, 1);
                mDataBase = mSqlHelper.getReadableDatabase();

                Cursor cursor = mDataBase.rawQuery("select Fee,Budget from finance",null);

                if (cursor.getCount()>0) {
                    while (cursor.moveToNext()) {
//                          cursor.move(i);
                        //移动到指定记录
                        double Fee = cursor.getDouble(cursor.getColumnIndex("Fee"));
                        String budget = cursor.getString(cursor.getColumnIndex("Budget"));
                        if (budget.equals("支出")) {
                            resultPay += Fee;
                        } else if (budget.equals("收入")) {
                            resultIncome += Fee;
                        }
                    }
                }

                //保留小数点后两位
                java.text.DecimalFormat df = new java.text.DecimalFormat(".##");

                textPay.setText(String.valueOf(df.format(resultPay)));
                textIncome.setText(String.valueOf(df.format(resultIncome)));
                textRemaind.setText(String.valueOf(df.format(resultIncome - resultPay)));
                sendEmptyMessageDelayed(0, 1000);
                cursor.close();

            }
        }
    };



}

Fragment2的代码:

package com.chase.cn.demon;

import android.content.Intent;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;

/**
 * Created by Chase on 2016/11/8.
 */

public class Content_Fragment2 extends android.support.v4.app.Fragment implements View.OnClickListener{
    private LinearLayout recordLinearlayout;
    private LinearLayout billLinearlayout;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View pager2 = inflater.inflate(R.layout.fragment_page2, container, false);
        recordLinearlayout = (LinearLayout) pager2.findViewById(R.id.record_layout);
        billLinearlayout = (LinearLayout) pager2.findViewById(R.id.bill_layout);
        recordLinearlayout.setOnClickListener(this);
        billLinearlayout.setOnClickListener(this);

        return pager2;
    }

    //点击条目的监听 并进行跳转
    @Override
    public void onClick(View v){
        switch (v.getId()){
            case R.id.record_layout:
            {
                Intent intentRecorder = new Intent(getActivity(),RecorderActiviity.class);
                startActivity(intentRecorder);
                int version = Integer.valueOf(android.os.Build.VERSION.SDK);
                if(version  >= 5) {
                    this.getActivity().overridePendingTransition(R.anim.push_up_in,R.anim.push_up_out);
                }
                break;
            }
            case R.id.bill_layout:
            {
                Intent intentBill = new Intent(getActivity(),BillActivity.class);
                startActivity(intentBill);
                this.getActivity().overridePendingTransition(R.anim.push_up_in,R.anim.push_up_out);
                break;
            }
        }
    }


}

在Fragment2中,点击“记一笔”和“查看账单”,进入不同的Activity中:
下面是“记一笔”代码:

package com.chase.cn.demon;

import android.app.Activity;
import android.app.DatePickerDialog;
import android.content.ContentValues;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.text.InputType;
import android.util.Log;
import android.view.View;
import android.view.Window;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.DatePicker;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.Spinner;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.Calendar;

/**
 * Created by Chase on 2016/11/8.
 */

public class RecorderActiviity extends Activity {

    private RadioGroup mRadioGroup;
    private TextView  TextTime;
    private EditText TextMoney;
    private Spinner spinner;
    private Button Confirm, Cancel;

    private MySQLiteOpenHelper sqLiteOpenHelper;
    private SQLiteDatabase mDataBase;

    private ImageButton timer_chooser;


    //保存类型数据
    private String add_type, radioButton_selected;

    //将这些数据保存一组data 用Data存入sqlite
    private ArrayList<String> Data = new ArrayList<String>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.recorder);

        mRadioGroup = (RadioGroup) findViewById(R.id.recorder_radioGroup);
        spinner = (Spinner) findViewById(R.id.record_spinner);
        Confirm = (Button) findViewById(R.id.recorder_confirm);
        Cancel = (Button) findViewById(R.id.recorder_cancel);
        TextTime = (TextView) findViewById(R.id.record_textView_time);
        TextMoney = (EditText) findViewById(R.id.record_textView_money);
        timer_chooser = (ImageButton) findViewById(R.id.timer_chooser);

        TextMoney.setInputType(InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_DECIMAL);//设置输入的钱为数字和小数
        //spinner设置属性 设置收入 和 支出的 spinner 利用arrays中的数据
        final ArrayAdapter<CharSequence> spinnerAdapterPay = ArrayAdapter.createFromResource(this,
                R.array.type1, android.R.layout.simple_spinner_item);
        spinnerAdapterPay.setDropDownViewResource(android.R.layout.simple_dropdown_item_1line);
        final ArrayAdapter<CharSequence> spinnerAdapterIncome = ArrayAdapter.createFromResource(this,
                R.array.type2, android.R.layout.simple_spinner_item);

        spinner.setAdapter(spinnerAdapterPay);//匹配不选情况下默认的pay
        //在radioButton中加入选 支出 还是 收入 的不同情况spinner
        radioButton_selected = "支出";
        mRadioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(RadioGroup group, int checkedId) {
                int radioButtonId = group.getCheckedRadioButtonId();

                if (radioButtonId == R.id.radio_pay) {
                    spinner.setAdapter(spinnerAdapterPay);
                    spinnerAdapterPay.setDropDownViewResource(android.R.layout.simple_dropdown_item_1line);
                } else {
                    spinner.setAdapter(spinnerAdapterIncome);
                    spinnerAdapterIncome.setDropDownViewResource(android.R.layout.simple_dropdown_item_1line);
                }

                //根据ID获取RadioButton的选的是 收入 还是 支出
//                radioButton_selected = (((RadioButton) findViewById(radioButtonId)).getText()).toString();
                RadioButton radioButton = (RadioButton) findViewById(mRadioGroup.getCheckedRadioButtonId());
                radioButton_selected = radioButton.getText().toString();
            }
        });

        //Spinner获取选中的内容 赋值给add_type
        spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                add_type = (String) spinner.getSelectedItem();
            }

            @Override
            public void onNothingSelected(AdapterView<?> parent) {

            }
        });

        Calendar cnow = Calendar.getInstance();
        final int year = cnow.get(Calendar.YEAR);
        final int month = cnow.get(Calendar.MONTH)+1;
        final int day = cnow.get(Calendar.DAY_OF_MONTH);
        Log.i("time", "time" + year + month + day);
        TextTime.setHint(year + "-" + month + "-" + day);
        //时间选择的dialog
        timer_chooser.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Calendar c = Calendar.getInstance();
                new DatePickerDialog(RecorderActiviity.this, new DatePickerDialog.OnDateSetListener() {
                    @Override
                    public void onDateSet(DatePicker view, int year, int month, int dayOfMonth) {
                        TextTime.setHint(year + "-" + (month+1) + "-" + dayOfMonth);
                    }
                },c.get(Calendar.YEAR),c.get(Calendar.MONTH),c.get(Calendar.DAY_OF_MONTH)).show();



            }
        });

        //确定按钮
        Confirm.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Data.clear();
                Data.add(add_type);
                Data.add(TextTime.getHint().toString());
                Data.add(TextMoney.getText().toString());
                Data.add(radioButton_selected);
                WriteData(Data);
                finish();
                overridePendingTransition(R.anim.push_up_in,R.anim.push_up_out);
                Log.i("info", "add_type" + add_type);
                Log.i("info", "radioButton_selected" + radioButton_selected);
            }
        });

        //取消按钮
        Cancel.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                finish();
                overridePendingTransition(R.anim.push_up_in,R.anim.push_up_out);
            }
        });
    }


    public void WriteData(ArrayList<String> Data) {
        sqLiteOpenHelper = new MySQLiteOpenHelper(this, "finance.db", null, 1);
        mDataBase = sqLiteOpenHelper.getWritableDatabase();
        ContentValues values = new ContentValues();
        values.clear();
        values.put("Type", Data.get(0));
        values.put("Time", Data.get(1));
        values.put("Fee", Data.get(2));
        values.put("Budget", Data.get(3));

        mDataBase.insert("finance", "Type", values);
        mDataBase.close();
        sqLiteOpenHelper.close();

    }

    @Override
    protected void onDestroy() {

        super.onDestroy();
    }
}

下面是“记一笔”的界面
Recorder界面

xml如下:

<?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:background="#547387">

    <LinearLayout
        android:layout_marginTop="15dp"
        android:background="@drawable/recorder_radio_bg"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:layout_marginLeft="5dp"
        android:layout_marginRight="5dp">

        <RadioGroup
            android:gravity="center"
            android:id="@+id/recorder_radioGroup"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal">

            <RadioButton
                android:layout_marginRight="95dp"
                android:id="@+id/radio_pay"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:checked="true"
                android:textSize="25sp"
                android:text="支出" />

            <RadioButton
                android:id="@+id/radio_income"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textSize="25sp"
                android:text="收入" />
        </RadioGroup>

    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:layout_marginLeft="5dp"
        android:layout_marginRight="5dp"
        android:background="@drawable/recorder_type_bg">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="种类:"
            android:textSize="25sp"
            android:id="@+id/textView" />

        <Spinner
            android:scrollbarSize="20dp"
            android:id="@+id/record_spinner"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

        </Spinner>
    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:layout_marginLeft="5dp"
        android:layout_marginRight="5dp"
        android:background="@drawable/recorder_time_bg">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="时间:"
            android:textSize="25sp"
            android:id="@+id/textView2" />

        <TextView
                android:id="@+id/record_textView_time"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textSize="25sp"
                android:hint="null" />

            <ImageButton
                android:layout_marginRight="15dp"
                android:layout_marginTop="4dp"
                android:id="@+id/timer_chooser"
                android:layout_width="40dp"
                android:layout_height="40dp"
                android:background="@mipmap/recorder_calendar"
                />



    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:layout_marginTop="10dp"
        android:layout_marginLeft="5dp"
        android:layout_marginRight="5dp"
        android:background="@drawable/recorder_money_bg">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="金额:"
            android:textSize="25sp"
            android:textColor="#fff"
            android:id="@+id/textView3" />

        <EditText
            android:id="@+id/record_textView_money"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:textSize="25sp"
            android:textColorHint="#afe1e2"
            android:hint="请输入消费/收入的金额"
            />

    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"

        >

        <Button
            android:id="@+id/recorder_confirm"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="确定"
            android:textAllCaps="false"
            android:layout_weight="1"/>

        <Button
            android:id="@+id/recorder_cancel"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="取消"
            android:textAllCaps="false"
            android:layout_weight="1"/>
    </LinearLayout>

</LinearLayout>

“记一笔中”的种类选择spinner用到在values文件夹下添加的array.xml文件:
这个文件中分别定义了两个type来对应“收入”和“支出”。

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string-array name="type1">
        <item>一般</item>
        <item>用餐</item>
        <item>交通</item>
        <item>服饰</item>
        <item>丽人</item>
        <item>旅行</item>
        <item>果蔬</item>
        <item>日用品</item>
        <item>网购</item>
        <item>购物</item>
    </string-array>

    <string-array name="type2">
        <item>一般</item>
        <item>报销</item>
        <item>工资</item>
        <item>零花钱</item>
        <item>兼职</item>
        <item>红包</item>
        <item>生活费</item>
        <item>奖金</item>
        <item>投资</item>
        <item>其他</item>

    </string-array>

</resources>

“查看账单”的代码如下,查看账单,从数据库中取得信息,我用的是CursorAdapter,所以在长按动态删除时,我用adapter change cursor实现。

package com.chase.cn.demon;

import android.app.Activity;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.View;
import android.view.Window;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;
import android.widget.Toast;

/**
 * Created by Chase on 2016/11/10.
 */
public class BillActivity extends Activity {
    private ListView billListView;
    private MySQLiteOpenHelper sqLiteOpenHelper;
    private SQLiteDatabase mDataBase;
    private SimpleCursorAdapter billAdapter;
    private boolean flag = true;


    // 存储数据的数组列表
  //  ArrayList<HashMap<String, Object>> listData;
    // 适配器

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.bill);

        sqLiteOpenHelper = new MySQLiteOpenHelper(BillActivity.this, "finance.db", null, 1);
        mDataBase = sqLiteOpenHelper.getReadableDatabase();
        final Cursor c = mDataBase.rawQuery("select * from finance", null);
        Log.i("database", "data" + mDataBase.isOpen());

//        int columnsSize = c.getColumnCount();
//        listData = new ArrayList<HashMap<String, Object>>();
        // 获取表的内容

//        while (c.moveToNext()) {
//            HashMap<String, Object> map = new HashMap<String, Object>();
//            for (int i = 0; i < columnsSize; i++) {
//                map.put("Type", c.getString(c.getColumnIndex("Type")));  //Type time fee budget
//                map.put("Time", c.getString(c.getColumnIndex("Time")));
//                String budget = c.getString(c.getColumnIndex("Budget"));
//                if (budget.equals("收入")) {
//                    map.put("Fee", "+" + c.getString(c.getColumnIndex("Fee")));
//                } else {
//                    map.put("Fee", "-" + c.getString(c.getColumnIndex("Fee")));
//                }
//                map.put("Budget", c.getString(c.getColumnIndex("Budget")));
//
//
//                Log.i("data", "data= " + map.get("Time"));
//                Log.i("data", "data= " + map.get("Type"));
//                Log.i("data", "data= " + map.get("Budget"));
//                Log.i("data", "data= " + map.get("Fee"));
//            }
//            listData.add(map);
//
//
//        }
        mDataBase.close();  先不关 等activity不在了再关
        sqLiteOpenHelper.close();
        c.close();


        billListView = (ListView) findViewById(R.id.bill_listView);
        //优化使用cursorAdapter减少代码
        billAdapter = new SimpleCursorAdapter(BillActivity.this,
                R.layout.bill_item,
                c,
                // ListItem的XML实现
                // 动态数组与Item对应的子项
                new String[]{"Time", "Fee", "Budget", "Type"},
                // ImageItem的XML文件里面的一个ImageView,两个TextView ID
                new int[]{R.id.billItem_time, R.id.billItem_money, R.id.billItem_budget, R.id.billItem_type});

        billListView.setAdapter(billAdapter);





        //item监听
        billListView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
            @Override
            public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {

                    String cc = c.getString(c.getColumnIndex("_id")); //用cursor得到对应表中的id
                    Log.i("info", "cc=  " + cc);
                    Toast.makeText(BillActivity.this, "删除了", Toast.LENGTH_SHORT).show();
                    //删除表中的对应id的行
                    mDataBase.execSQL("delete from finance where _id="
                            + cc);


                /**
                 * 也就是说,在数据库中删除一条记录之后,紧跟着直接用ListView的remove() 方法删掉对应的View,但是这样报错:
                 Java.lang.UnsupportedOperationException: removeView(View) is not supported in AdapterView

                 说明不能直接用ListView的remove()方法。于是网上查了查,找到了新的方法,而且也更合理:
                 [java] view plain copy 在CODE上查看代码片派生到我的代码片
                 for(Sample sample : selectedSamples){
                 SampleManager.get(getActivity()).deleteSample(Long.parseLong(sample.getId()));
                 }

                 ((SampleCursor)adapter.getCursor()).requery();
                 adapter.notifyDataSetChanged();
                 lv.setAdapter(adapter);

                 也就是说:
                 1. 对应的cursor要重新查询一边,
                 2. 然后适配器adapter调用notifiyDataSetChanged()方法,
                 3. 最后重新设置一下ListView的adapter
                 */

                (billAdapter.getCursor()).requery();
                billAdapter.notifyDataSetChanged();

                    Log.i("info","c  "+c.isClosed());
//

//                mDataBase.close();
//                sqLiteOpenHelper.close();
                return false;
            }
        });

//        mTimeHandler2.sendEmptyMessageDelayed(0, 500);
    }



    @Override
    public void onDestroy() {
        mTimeHandler2.removeCallbacksAndMessages(null);

//        sqLiteOpenHelper.close();
//        mDataBase.close();
        super.onDestroy();
    }

    public Handler mTimeHandler2 = new Handler() {
        public void handleMessage(android.os.Message msg) {

            if (msg.what == 0) {


//                billAdapter.changeCursor(c);

            }
        }
    };

}

对应的xml:

<?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:background="#b3d66e">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="长按删除每条账目"
        android:textSize="20sp"
        android:gravity="center"/>


    <ListView
        android:id="@+id/bill_listView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginLeft="5dp"
        android:layout_marginRight="5dp"
        android:layout_marginTop="5dp">

    </ListView>

</LinearLayout>

上面的listview的适配器为simpleCursorAdapter,所以每条对应的item的xml如下:

<?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="wrap_content"
    android:background="@drawable/bill_bottom_bg"
    android:orientation="vertical"
    android:layout_marginRight="5dp"
    android:layout_marginLeft="5dp"
    android:layout_marginBottom="5dp"
    android:layout_marginTop="5dp">

    <RelativeLayout
        android:layout_marginRight="4dp"
        android:layout_marginLeft="4dp"
        android:layout_marginBottom="2dp"
        android:layout_marginTop="4dp"
        android:background="@drawable/bill_bottom_up_bg"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <TextView
            android:id="@+id/billItem_time"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Time"
            android:textColor="#fff"
            android:textSize="30sp" />
        <TextView
            android:id="@+id/billItem_budget"
            android:layout_alignParentRight="true"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Pay?Income"
            android:textColor="#fff"
            android:textSize="30sp"/>

    </RelativeLayout>

    <RelativeLayout
        android:layout_marginRight="4dp"
        android:layout_marginLeft="4dp"
        android:layout_marginBottom="4dp"
        android:layout_marginTop="2dp"
        android:background="@drawable/bill_bottom_down_bg"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <TextView
            android:id="@+id/billItem_type"

            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Type"
            android:textColor="#fff"
            android:textSize="30sp"/>
        <TextView
            android:id="@+id/billItem_money"
            android:layout_alignParentRight="true"
            android:layout_marginLeft="100dp"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Money"
            android:textColor="#fff"
            android:textSize="30sp" />



    </RelativeLayout>

</LinearLayout>

这张图为“查看账单”的界面:
这里写图片描述

然后跳转Activity的动画可以自己定义,这里我使用了:

<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate
        android:duration="500"
        android:fromYDelta="100%p"
        android:toYDelta="0"
    />
    <alpha
        android:duration="500"
        android:fromAlpha="0.0"
        android:toAlpha="1.0"
    />
</set>

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" >
    <translate
        android:duration="500"
        android:fromYDelta="0"
        android:toYDelta="-100%p" />
    <alpha
        android:duration="500"
        android:fromAlpha="1.0"
        android:toAlpha="0.0" />
</set>

基本功能就实现了,后续会完善更多功能。

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值