在上一篇博客中我们将记录页面初步搭建,但是如果运行的话,依然看不到界面。
首先我们需要创建一个ViewPager的适配器,命名为RecordPagerAdapter.java
public class RecordPagerAdapter extends FragmentPagerAdapter { List<Fragment> fragmentList; String[] titles = {"支出", "收入"}; public RecordPagerAdapter(@NonNull FragmentManager fm, List<Fragment> fragmentList) { super(fm); this.fragmentList = fragmentList; } @NonNull @Override public Fragment getItem(int position) { return fragmentList.get(position); } @Override public int getCount() { return fragmentList.size(); } @Nullable @Override public CharSequence getPageTitle(int position) { return titles[position]; } }
写一个初始化ViewPager的方法
private void initPager() { /*初始化ViewPager页面的集合*/ List<Fragment> fragmentList = new ArrayList<>(); /*创建收入和支出页面放置在Fragment当中*/ OutcomeFragment outcomeFragment = new OutcomeFragment(); IncomeFragment incomeFragment = new IncomeFragment(); fragmentList.add(outcomeFragment); fragmentList.add(incomeFragment); /*创建适配器*/ RecordPagerAdapter recordPagerAdapter = new RecordPagerAdapter(getSupportFragmentManager(), fragmentList); /*设置适配器*/ viewPager.setAdapter(recordPagerAdapter); /*将TabLayout和ViewPager进行关联*/ tabLayout.setupWithViewPager(viewPager); }
在创建RecorfActivity时所需要的步骤:
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_record); /*查找控件*/ tabLayout = findViewById(R.id.record_tabs); viewPager = findViewById(R.id.record_vp); /*设置viewPager*/ initPager(); }
此外,在记录页面中左上角存在一个叉号图片。我们所想要实现的功能是点击此叉号可以返回至主界面,所以在这个地方添加一个点击事件,实现可以返回主界面。
/*点击事件*/ public void onClick(View view) { switch (view.getId()) { case R.id.record_iv_back: finish(); break; } }
现在,我们将目光放在需要实现支出与收入的两个fragment上,考虑到两个fragment有很多相同的地方,所以为了避免代码冗余,我们抽象出一个BaseRecordFragment类,编写两个fragment中一样的地方。
将fragment填充至view中。
@Nullable @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_outcome, container, false); initView(view); /*给GridView填充数据的方法*/ loadDataToGV(); /*设置GridView的每一项的点击事件*/ setGridViewListener(); /*初始化当前时间*/ initTime(); return view; }
这时,我们现将GridView中需要显示的数据加载出来。便于以后的更改,我们将这里的数据添加至数据库中。
我们新建一个DBOpenHelper类,继承SQLiteOpenHelper
public class DBOpenHelper extends SQLiteOpenHelper { public DBOpenHelper(@Nullable Context context) { super(context, "tally.db", null, 1); } /*创建数据库的方法 * 只有项目第一次运行时会被调用*/ @Override public void onCreate(SQLiteDatabase db) { String sql = "create table tb_type(id integer primary key autoincrement, " + "typename varchar(10)," + "imageId integer," + "sImageId integer," + "kind integer)"; db.execSQL(sql); insertType(db); /*创建记账表*/ String sql2 = "create table tb_account(id integer primary key autoincrement, " + "typename varchar(10), " + "sImageId integer, " + "mark varchar(80), " + "money float, " + "time varchar(60), " + "year integer, " + "month integer, " + "day integer, " + "kind integer) "; db.execSQL(sql2); } /** * 数据库版本在更新时发生改变,会调用此方法*/ @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { } public void insertType(SQLiteDatabase db) { //向tb_type表中插入元素 String sql = "insert into tb_type(typename, imageId, sImageId, kind) values(?,?,?,?)"; db.execSQL(sql, new Object[]{"其它", R.mipmap.ic_other, R.mipmap.ic_other, 0}); db.execSQL(sql, new Object[]{"餐饮", R.mipmap.ic_catering, R.mipmap.ic_catering_selected, 0}); db.execSQL(sql, new Object[]{"日用", R.mipmap.ic_daily, R.mipmap.ic_daily_selected, 0}); db.execSQL(sql, new Object[]{"水果", R.mipmap.ic_fruit, R.mipmap.ic_fruit_selected, 0}); db.execSQL(sql, new Object[]{"娱乐", R.mipmap.ic_recreation, R.mipmap.ic_recreation_selected, 0}); db.execSQL(sql, new Object[]{"宠物", R.mipmap.ic_pet, R.mipmap.ic_pet_selected, 0}); db.execSQL(sql, new Object[]{"学习", R.mipmap.ic_study, R.mipmap.ic_study_selected, 0}); db.execSQL(sql, new Object[]{"交通", R.mipmap.ic_traffic, R.mipmap.ic_traffic_selected, 0}); db.execSQL(sql, new Object[]{"医疗", R.mipmap.ic_medical, R.mipmap.ic_medical_selected, 0}); db.execSQL(sql, new Object[]{"其它", R.mipmap.ic_other, R.mipmap.ic_other, 1}); db.execSQL(sql, new Object[]{"工资", R.mipmap.ic_salary, R.mipmap.ic_salary_selected, 1}); db.execSQL(sql, new Object[]{"兼职", R.mipmap.ic_part_time, R.mipmap.ic_part_time_selected, 1}); db.execSQL(sql, new Object[]{"理财", R.mipmap.ic_transaction, R.mipmap.ic_transaction_selected, 1}); db.execSQL(sql, new Object[]{"礼金", R.mipmap.ic_gift, R.mipmap.ic_gift_selected, 1}); } }
通过insertType方法将我们所需要的类型说明以及图片全部添加至数据库,用kind区分支出与收入, 0表示支出 1表示收入
新建一个DBManager类用于操作数据库中的表。
/** * 读取数据库当中的数据,写入内存集合里 * kind: * 0 支出 * 1 收入 */ public static List<TypeBean> getTypeList(int kind) { ArrayList<TypeBean> list = new ArrayList<>(); String sql = "select * from tb_type where kind="+kind; Cursor cursor = db.rawQuery(sql, null); while(cursor.moveToNext()) { String typename = cursor.getString(cursor.getColumnIndex("typename")); int imageId = cursor.getInt(cursor.getColumnIndex("imageId")); int sImageId = cursor.getInt(cursor.getColumnIndex("sImageId")); int id = cursor.getInt(cursor.getColumnIndex("id")); TypeBean typeBean = new TypeBean(id, typename, imageId, sImageId, kind); list.add(typeBean); } return list; }
将需要的类别数据全部添加至数据库后,我们继续编写实现GridView
我们需要一个适配器
public class TypeBaseAdapter extends BaseAdapter { Context context; List<TypeBean> mDatas; int selectPos = 0;//选中的位置 public TypeBaseAdapter(Context context, List<TypeBean> mDatas) { this.context = context; this.mDatas = mDatas; } @Override public int getCount() { return mDatas.size(); } @Override public Object getItem(int position) { return mDatas.get(position); } @Override public long getItemId(int position) { return position; } public void setSelectPos(int selectPos) { this.selectPos = selectPos; } @Override public View getView(int position, View convertView, ViewGroup parent) { convertView = LayoutInflater.from(context).inflate(R.layout.item_recordfragment_gv, parent, false); /*查找布局当中的控件*/ ImageView iv = convertView.findViewById(R.id.item_recordfrag_iv); TextView tv = convertView.findViewById(R.id.item_recordfrag_tv); /*获取指定位置的数据源*/ TypeBean typeBean = mDatas.get(position); tv.setText(typeBean.getTypename()); if (selectPos == position) { iv.setImageResource(typeBean.getsImageId()); } else { iv.setImageResource(typeBean.getImageId()); } return convertView; } }
给GridView加载数据
/*给GridView填充数据的方法*/ public void loadDataToGV() { typeBeanList = new ArrayList<>(); adapter = new TypeBaseAdapter(getContext(), typeBeanList); gv_type.setAdapter(adapter); }
这里所需要的数据,支出与收入并不相同,所以需要在两个fragment中重写这个方法。下面给出OutcomeFragment中重写的实现。
@Override public void loadDataToGV() { super.loadDataToGV(); /* TODO:获取数据库当中的数据源 */ List<TypeBean> inList = DBManager.getTypeList(1); typeBeanList.addAll(inList); adapter.notifyDataSetChanged(); }
在GridView中设置点击事件,保证我们点击不同的type可以更改type的类型
/*设置GridView的点击事件*/ private void setGridViewListener() { gv_type.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { adapter.setSelectPos(position); adapter.notifyDataSetInvalidated(); imageView.setImageResource(typeBean.getImageId()); tv_type.setText(typeBean.getTypename()); } }); }
初始化界面
public void initView(View view) { keyboardView = view.findViewById(R.id.frag_record_keyboard); et_money = view.findViewById(R.id.frag_record_et_money); imageView = view.findViewById(R.id.frag_record_iv); gv_type = view.findViewById(R.id.frag_record_gv); tv_mark = view.findViewById(R.id.frag_record_tv_mark); tv_time = view.findViewById(R.id.frag_record_tv_time); tv_type = view.findViewById(R.id.frag_record_tv_type); tv_time.setOnClickListener(this); tv_mark.setOnClickListener(this); //让自定义软键盘显示出来 KeyboardUtils keyboard = new KeyboardUtils(keyboardView, et_money); keyboard.showKeyboard(); /*设置接口,监听确定按钮被点击了*/ keyboard.setOnEnsureListener(new KeyboardUtils.OnEnsureListener() { @Override public void onEnsure() { /*点击了确定按钮 * 获取记录的信息保存在数据库当中 * 返回上一级页面 * */ } }); }
初始化时间
/*初始化时间*/ public void initTime() { Date date = new Date(); SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm"); String time = simpleDateFormat.format(date); tv_time.setText(time); }
现在,记录界面已经可以显示了。下一步,我们将对记录界面进一步完善。