Android App开发实战之实现微信记账本附源码 超详细必须看
发布时间:2023-03-23 13:29:30 所属栏目:教程 来源:
导读:好用的记账本必须具备两项基本功能。一项时记录新帐单,另一项时查看账单列表,其中账单的记录操作要求用户输入账单的明细要素,包括账单的发生时间,账单的收支类型,账单的交易金额,账单的事由描述等等,账单通常
好用的记账本必须具备两项基本功能。一项时记录新帐单,另一项时查看账单列表,其中账单的记录操作要求用户输入账单的明细要素,包括账单的发生时间,账单的收支类型,账单的交易金额,账单的事由描述等等,账单通常分月展示,每页显示单个月份的账单数据,还要支持在不同月份之间切换,每月的账单数据按照时间从上往下排列,然后列表末尾展示当月的账单合计情况。 package com.example.chapter08; import android.app.DatePickerDialog; import android.content.Intent; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.DatePicker; import android.widget.EditText; import android.widget.RadioButton; import android.widget.RadioGroup; import android.widget.TextView; import android.widget.Toast; import androidx.appcompat.app.AppCompatActivity; import com.example.chapter08.bean.BillInfo; import com.example.chapter08.database.BillDBHelper; import com.example.chapter08.util.DateUtil; import com.example.chapter08.util.ViewUtil; import java.util.Calendar; import java.util.Date; import java.util.List; public class BillAddActivity extends AppCompatActivity implements RadioGroup.OnCheckedchangelistener,View.OnClickListener,DatePickerDialog.OnDateSetListener { private final static String TAG = "BillAddActivity"; private TextView tv_date; private RadioButton rb_income; private RadioButton rb_expand; private EditText et_desc; private EditText et_amount; private int mBillType = 1; // 账单类型。0 收入;1 支出 private int xuhao; // 如果序号有值,说明已存在该账单 private Calendar calendar = Calendar.getInstance(); // 获取日历实例,里面包含了当前的年月日 private BillDBHelper mBillHelper; // 声明一个账单数据库的帮助器对象 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_bill_add); TextView tv_title = findViewById(R.id.tv_title); TextView tv_option = findViewById(R.id.tv_option); tv_date = findViewById(R.id.tv_date); RadioGroup rg_type = findViewById(R.id.rg_type); rb_income = findViewById(R.id.rb_income); rb_expand = findViewById(R.id.rb_expand); et_desc = findViewById(R.id.et_desc); et_amount = findViewById(R.id.et_amount); tv_title.setText("请填写账单"); tv_option.setText("账单列表"); findViewById(R.id.iv_back).setonClickListener(this); tv_option.setonClickListener(this); tv_date.setonClickListener(this); findViewById(R.id.btn_save).setonClickListener(this); rg_type.setonCheckedchangelistener(this); } @Override protected void onResume() { super.onResume(); xuhao = getIntent().getIntExtra("xuhao",-1); mBillHelper = BillDBHelper.getInstance(this); // 获取账单数据库的帮助器对象 if (xuhao != -1) { // 序号有值,就展示数据库里的账单详情 List<BillInfo> bill_list = (List<BillInfo>) mBillHelper.queryById(xuhao); if (bill_list.size() > 0) { // 已存在该账单 BillInfo bill = bill_list.get(0); // 获取账单信息 Date date = DateUtil.formatString(bill.date); Log.d(TAG,"bill.date="+bill.date); Log.d(TAG,"year="+date.getYear()+",month="+date.getMonth()+",day="+date.getDate()); calendar.set(Calendar.YEAR,date.getYear()+1900); calendar.set(Calendar.MONTH,date.getMonth()); calendar.set(Calendar.DAY_OF_MONTH,date.getDate()); if (bill.type == 0) { // 收入 rb_income.setChecked(true); } else { // 支出 rb_expand.setChecked(true); } et_desc.setText(bill.desc); // 设置账单的描述文本 et_amount.setText(""+bill.amount); // 设置账单的交易金额 } } tv_date.setText(DateUtil.getDate(calendar)); // 设置账单的发生时间 } @Override public void onClick(View v) { if (v.getId() == R.id.iv_back) { finish(); // 关闭当前页面 } else if (v.getId() == R.id.tv_option) { Intent intent = new Intent(this,BillPagerActivity.class); intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); // 设置启动标志 startActivity(intent); // 跳到账单列表页面 } else if (v.getId() == R.id.tv_date) { // 构建一个日期对话框,该对话框已经集成了日期选择器。 // DatePickerDialog的第二个构造参数指定了日期监听器 DatePickerDialog dialog = new DatePickerDialog(this,this,calendar.get(Calendar.YEAR),// 年份 calendar.get(Calendar.MONTH),// 月份 calendar.get(Calendar.DAY_OF_MONTH)); // 日子 dialog.show(); // 显示日期选择对话框 } else if (v.getId() == R.id.btn_save) { saveBill(); // 保存账单 } } @Override public void onCheckedChanged(RadioGroup group,int checkedId) { mBillType = (checkedId==R.id.rb_expand) ? 1 : 0; } @Override public void onDateSet(DatePicker view,int year,int month,int dayOfMonth) { calendar.set(Calendar.YEAR,year); calendar.set(Calendar.MONTH,month); calendar.set(Calendar.DAY_OF_MONTH,dayOfMonth); tv_date.setText(DateUtil.getDate(calendar)); } // 保存账单 private void saveBill() { //ViewUtil.hideAllInputMethod(this); // 隐藏输入法软键盘 ViewUtil.hideOneInputMethod(this,et_amount); // 隐藏输入法软键盘 BillInfo bill = new BillInfo(); bill.xuhao = xuhao; bill.date = tv_date.getText().toString(); bill.month = 100*calendar.get(Calendar.YEAR) + (calendar.get(Calendar.MONTH)+1); bill.type = mBillType; bill.desc = et_desc.getText().toString(); bill.amount = Double.parseDouble(et_amount.getText().toString()); mBillHelper.save(bill); // 把账单信息保存到数据库 Toast.makeText(this,"已添加账单",Toast.LENGTH_SHORT).show(); resetPage(); // 重置页面 } // 重置页面 private void resetPage() { calendar = Calendar.getInstance(); et_desc.setText(""); et_amount.setText(""); tv_date.setText(DateUtil.getDate(calendar)); } } 查看类代码 package com.example.chapter08; import android.app.DatePickerDialog; import android.content.Intent; import android.os.Bundle; import android.util.TypedValue; import android.view.View; import android.widget.DatePicker; import android.widget.TextView; import androidx.appcompat.app.AppCompatActivity; import androidx.viewpager.widget.PagerTabStrip; import androidx.viewpager.widget.ViewPager; import com.example.chapter08.adapter.BillPagerAdpater; import com.example.chapter08.util.DateUtil; import java.util.Calendar; public class BillPagerActivity extends AppCompatActivity implements View.OnClickListener,DatePickerDialog.OnDateSetListener,ViewPager.OnPagechangelistener { private TextView tv_month; private ViewPager vp_bill; // 声明一个翻页视图对象 private Calendar calendar = Calendar.getInstance(); // 获取日历实例,里面包含了当前的年月日 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_bill_pager); TextView tv_title = findViewById(R.id.tv_title); TextView tv_option = findViewById(R.id.tv_option); tv_month = findViewById(R.id.tv_month); tv_title.setText("账单列表"); tv_option.setText("添加账单"); findViewById(R.id.iv_back).setonClickListener(this); tv_option.setonClickListener(this); tv_month.setonClickListener(this); tv_month.setText(DateUtil.getMonth(calendar)); // 从布局视图中获取名叫vp_bill的翻页视图 vp_bill = findViewById(R.id.vp_bill); initViewPager(); // 初始化翻页视图 } @Override public void onClick(View v) { if (v.getId() == R.id.iv_back) { finish(); // 关闭当前页面 } else if (v.getId() == R.id.tv_option) { Intent intent = new Intent(this,BillAddActivity.class); intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); // 设置启动标志 startActivity(intent); // 跳到账单填写页面 } else if (v.getId() == R.id.tv_month) { // 构建一个日期对话框,该对话框已经集成了日期选择器。 // DatePickerDialog的第二个构造参数指定了日期监听器 DatePickerDialog dialog = new DatePickerDialog(this,// 月份 calendar.get(Calendar.DAY_OF_MONTH)); // 日子 dialog.show(); // 显示日期选择对话框 } } @Override public void onDateSet(DatePicker view,dayOfMonth); tv_month.setText(DateUtil.getMonth(calendar)); vp_bill.setCurrentItem(month); // 设置翻页视图显示第几页 } // 初始化翻页视图 private void initViewPager() { // 从布局视图中获取名叫pts_bill的翻页标签栏 PagerTabStrip pts_bill = findViewById(R.id.pts_bill); // 设置翻页标签栏的文本大小 pts_bill.setTextSize(TypedValue.COMPLEX_UNIT_SP,17); // 构建一个商品图片的翻页适配器 BillPagerAdpater adapter = new BillPagerAdpater(getSupportFragmentManager(),calendar.get(Calendar.YEAR)); vp_bill.setAdapter(adapter); // 设置翻页视图的适配器 vp_bill.setCurrentItem(calendar.get(Calendar.MONTH)); // 设置翻页视图显示第几页 vp_bill.addOnPagechangelistener(this); // 给翻页视图添加页面变更监听器 } // 翻页状态改变时触发 public void onPageScrollStateChanged(int state) {} // 在翻页过程中触发 public void onPageScrolled(int position,float ratio,int offset) {} // 在翻页结束后触发 public void onPageSelected(int position) { calendar.set(Calendar.MONTH,position); tv_month.setText(DateUtil.getMonth(calendar)); } } 适配器代码 package com.example.chapter08.adapter; import android.app.AlertDialog; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.BaseAdapter; import android.widget.TextView; import com.example.chapter08.BillAddActivity; import com.example.chapter08.R; import com.example.chapter08.bean.BillInfo; import com.example.chapter08.database.BillDBHelper; import java.util.ArrayList; import java.util.List; public class Billlistadapter extends BaseAdapter implements AdapterView.OnItemClickListener,AdapterView.OnItemLongClickListener{ private static final String TAG = "Billlistadapter"; private Context mContext; // 声明一个上下文对象 private List<BillInfo> mBillList = new ArrayList<BillInfo>(); // 账单信息列表 public Billlistadapter(Context context,List<BillInfo> billList) { mContext = context; mBillList = billList; } @Override public int getCount() { return mBillList.size(); } @Override public Object getItem(int position) { return mBillList.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(final int position,View convertView,ViewGroup parent) { ViewHolder holder; if (convertView == null) { holder = new ViewHolder(); // 根据布局文件item_bill.xml生成转换视图对象 convertView = LayoutInflater.from(mContext).inflate(R.layout.item_bill,null); holder.tv_date = convertView.findViewById(R.id.tv_date); holder.tv_desc = convertView.findViewById(R.id.tv_desc); holder.tv_amount = convertView.findViewById(R.id.tv_amount); convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } BillInfo bill = mBillList.get(position); holder.tv_date.setText(bill.date); holder.tv_desc.setText(bill.desc); if (bill.date.equals("合计")) { holder.tv_amount.setText(bill.remark); } else { holder.tv_amount.setText(String.format("%s%d元",bill.type==0?"收入":"支出",(int) bill.amount)); } return convertView; } @Override public void onItemClick(AdapterView<?> parent,View view,int position,long id) { if (position >= mBillList.size()-1) { // 合计行不响应点击事件 return; } Log.d(TAG,"onItemClick position=" + position); BillInfo bill = mBillList.get(position); // 以下跳转到账单填写页面 Intent intent = new Intent(mContext,BillAddActivity.class); intent.putExtra("xuhao",bill.xuhao); // 携带账单序号,表示已存在该账单 mContext.startActivity(intent); // 因为已存在该账单,所以跳过去实际会编辑账单 } @Override public boolean onItemLongClick(AdapterView<?> parent,final int position,long id) { if (position >= mBillList.size()-1) { // 合计行不响应长按事件 return true; } Log.d(TAG,"onItemLongClick position=" + position); BillInfo bill = mBillList.get(position); // 获得当前位置的账单信息 AlertDialog.Builder builder = new AlertDialog.Builder(mContext); String desc = String.format("是否删除以下账单?\n%s %s%d %s",bill.date,(int) bill.amount,bill.desc); builder.setMessage(desc); // 设置提醒对话框的消息文本 builder.setPositiveButton("是",new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog,int which) { deleteBill(position); // 删除该账单 } }); builder.setNegativeButton("否",null); builder.create().show(); // 显示提醒对话框 return true; } // 删除该账单 private void deleteBill(int position) { BillInfo bill = mBillList.get(position); mBillList.remove(position); notifyDataSetChanged(); // 通知适配器发生了数据变化 // 获得数据库帮助器的实例 BillDBHelper helper = BillDBHelper.getInstance(mContext); helper.delete(bill.xuhao); // 从数据库删除指定序号的账单 } public final class ViewHolder { public TextView tv_date; public TextView tv_desc; public TextView tv_amount; } } XML文件 <LinearLayout xmlns:android="" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <include layout="@layout/title_booking" /> <LinearLayout android:layout_width="match_parent" android:layout_height="40dp" android:layout_margin="5dp" android:orientation="horizontal"> <TextView android:layout_width="wrap_content" android:layout_height="match_parent" android:gravity="center|right" android:text="账单日期:" android:textColor="@color/black" android:textSize="17sp" /> <TextView android:id="@+id/tv_date" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="2" android:drawableRight="@drawable/arrow_down" android:gravity="center" android:textColor="@color/black" android:textSize="17sp" /> </LinearLayout> <RadioGroup android:id="@+id/rg_type" android:layout_width="match_parent" android:layout_height="30dp" android:layout_margin="5dp" android:orientation="horizontal" > <TextView android:layout_width="wrap_content" android:layout_height="match_parent" android:gravity="center|right" android:text="账单类型:" android:textColor="@color/black" android:textSize="17sp" /> <RadioButton android:id="@+id/rb_income" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:gravity="left|center" android:checked="false" android:text="收入" android:textColor="#000000" android:textSize="17sp" /> <RadioButton android:id="@+id/rb_expand" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:gravity="left|center" android:checked="true" android:text="支出" android:textColor="#000000" android:textSize="17sp" /> </RadioGroup> <LinearLayout android:layout_width="match_parent" android:layout_height="100dp" android:layout_margin="5dp" android:orientation="horizontal"> <TextView android:layout_width="wrap_content" android:layout_height="match_parent" android:gravity="center|right" android:text="事项说明:" android:textColor="@color/black" android:textSize="17sp" /> <EditText android:id="@+id/et_desc" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="2" android:gravity="left|top" android:background="@drawable/editext_selector" android:textColor="@color/black" android:textSize="17sp" android:hint="请填写说明内容" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="40dp" android:layout_margin="5dp" android:orientation="horizontal"> <TextView android:layout_width="wrap_content" android:layout_height="match_parent" android:gravity="center|right" android:text=" 金额:" android:textColor="@color/black" android:textSize="17sp" /> <EditText android:id="@+id/et_amount" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="2" android:background="@drawable/editext_selector" android:inputType="number" android:textColor="@color/black" android:textSize="17sp" android:hint="单位(元)" /> </LinearLayout> <Button android:id="@+id/btn_save" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center" android:text="保 存" android:textColor="@color/black" android:textSize="20sp" /> </LinearLayout> <LinearLayout xmlns:android="" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <include layout="@layout/title_booking" /> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:paddingLeft="5dp" android:paddingRight="5dp" android:gravity="center|top" android:orientation="vertical"> <LinearLayout android:layout_width="match_parent" android:layout_height="40dp" android:orientation="horizontal"> <TextView android:layout_width="wrap_content" android:layout_height="match_parent" android:gravity="center|right" android:text="请选择月份:" android:textColor="@color/black" android:textSize="17sp" /> <TextView android:id="@+id/tv_month" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="2" android:drawableRight="@drawable/arrow_down" android:gravity="center" android:textColor="@color/black" android:textSize="17sp" /> </LinearLayout> <androidx.viewpager.widget.ViewPager android:id="@+id/vp_bill" android:layout_width="match_parent" android:layout_height="match_parent"> <androidx.viewpager.widget.PagerTabStrip android:id="@+id/pts_bill" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </androidx.viewpager.widget.ViewPager> </LinearLayout> (编辑:汽车网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
推荐文章
站长推荐