当头最近开始做一个Android app的开发,主要想法是设计一个基于现金结算旅游日记生成的AA结算神器。虽然网上有一些比较成熟的应用,但是当头还是想要做一个功能简单,便于使用的app,同时也是锻炼开发技能,所以在此记录下开发所经过的一步步流程,为以后的开发提供参考。
第一天:需求分析和功能设计,大致画出功能的一个草图和UI的设计。
第二天:UI设计由开始界面(两秒后跳入主菜单)——>主菜单(输入此次AA账本的名字)——>点击开始AA进入 tabhost实现的功能分页。
最主要的页面是tabhost界面布局,分成四个tab,名称暂定为添加人员,添加账单,AA结算,日志分享。四三个功能设计三个不同的activity和xml布局文件,内容简略先设为helloworld。创建一个main_activity统筹四个tab界面,添加一个spalsh_activity作为开始页面,设置两秒后转入begin——activity,在这个页面输入本次AA账本的名字,点击开始AA按钮,输入的内容会随着intent传到下一个Activity,第四个功能日志分享会用到这个数据,之后进入main_activity,默认的tab分页是添加人员。可在manifest.xml中设置最先进入的页面,我主要实现app最先进入spalsh_activity,在此贴上spalsh_activity的代码,spalsh_activity.xml设置背景图片,可用已经做好的图片作为开始界面。
第三天:实现基础的添加人员和添加账单功能。
总结的架构昨天基本上设计定型,今天主要完成的内容是添加人员和添加账单这一块,开发采用的数据存储方式是SQLite,数据库的程序主要是一个DbHelper.java。主要作用是建表,里面创建了两张表,一张是成员表,存储参与人员的姓名,旅游中支付的总金额和AA中应该支付的金额,类型是float,还有一张账单表,存储账单支付时间,支付金额,账单类型,支付人。两张表的主键id都是自动生成。
首先是添加成员,简单的界面设计,输入要添加的人员姓名,点击添加按钮,界面刷新显示成员表中的参与人员,即实时添加实时刷新,刷新设计了一个updatelist函数,用listview存储成员表中读出的数据,这里用一个成员实体封装数据库中的数据,这样读完数据就可以关掉cursor,避免报错和警告。此外稍微美化了一下,一直按着listview中的某个item即某个成员,大概2秒自动删除,然后刷新界面,贴上listview长按删除代码
listview.setOnItemLongClickListener(new OnItemLongClickListener() {
@Override
public boolean onItemLongClick(AdapterView<?> parent, View view,
int position, long id) {
String name="";
Cursor crr=sqldb.query("member", null, null, null, null,
null, null);
if(crr!=null&&crr.moveToFirst()){
for(crr.moveToFirst();!crr.isAfterLast();crr.moveToNext())
{
int _id=Integer.parseInt(crr.getString(0));
if(_id==id){
name = crr.getString(1);
break;
}
}}
crr.close();
sqldb.delete("member", "name=?",new String[]{name});
Toast.makeText(AddMemberActivity.this, "成功删除了成员" +name,
Toast.LENGTH_SHORT).show();
SimpleCursorAdapter adapter=(SimpleCursorAdapter)lv.getAdapter();
//adapter.notifyDataSetChanged();
adapter.notifyDataSetChanged();
updatelistview();
return true;
}
});
然后是添加账单,添加账单界面主要是按照提示输入一条账单的数据,存入到数据库内,如果要使程序看上去更好的话,可以多用dialog和toast之类的语句,很简单的。对于总的账单查询遍历我是放在了AA结算界面,切换到AA结算就可看到所有的账单信息,这里ui用了spinner组件。
第四天:完成核心内容AA计算模块。
这里也设置了一个分页,对应AAacountActivity,切换到这个分页,首先显示的是对账单表的一个遍历,用listview嵌套表格ui显示一条条的账单,下面显示统计的总的消费信息,和最核心的每个人需要支付的钱,贴上核心的AA结算代码,没有用到很复杂的数据结构。
t1=(TextView)findViewById(R.id.billsum);
t2=(TextView)findViewById(R.id.billmember);
t3=(TextView)findViewById(R.id.aatest);
float result=0;
String billme;
for(c.moveToFirst();!c.isAfterLast();c.moveToNext())
{
result +=Float.parseFloat(c.getString(1));
}
average=result/billmember.size();
t1.setText("总计消费: "+"¥"+String.valueOf(result));
for(MemberClass member:billmember){
System.out.println(member.getName());}
billme=billmember.get(0).getName();
t2.setText(billme+"等"+billmember.size()+"成员参加,每人平均需要支付¥"+average);
int geti=0,seti=0;
for(int i=0;i<billmember.size();i++){
billmember.get(i).setaamoney(billmember.get(i).getMoney()-average);
if(billmember.get(i).getaamoney()>0){
get.add(billmember.get(i));
}
else if(billmember.get(i).getaamoney()<0){
set.add(billmember.get(i));
}
}
while(get.size()!=0&&set.size()!=0){
if(get.get(geti).getaamoney()+set.get(seti).getaamoney()>0){
aabill.add(set.get(seti).getName()+" "+"应向"+" "+get.get(geti).getName()+" "+"支付"+" "+"¥"+Math.abs(set.get(seti).getaamoney()));
get.get(geti).setaamoney(get.get(geti).getaamoney()+set.get(seti).getaamoney());
set.remove(seti);
//t2.setText(get.get(geti).getName()+"应向"+set.get(seti).getName()+"支付"+set.get(seti).getaamoney());
}
else if(get.get(geti).getaamoney()+set.get(seti).getaamoney()==0){
aabill.add(set.get(seti).getName()+" "+"应向"+" "+get.get(geti).getName()+" "+"支付"+" "+"¥"+get.get(geti).getaamoney());
get.get(geti).setaamoney(get.get(geti).getaamoney()+set.get(seti).getaamoney());
set.remove(seti);
get.remove(geti);
//t2.setText(get.get(geti).getName()+"应向"+set.get(seti).getName()+"支付"+set.get(seti).getaamoney());
}
else if(get.get(geti).getaamoney()+set.get(seti).getaamoney()<0){
aabill.add(set.get(seti).getName()+" "+"应向"+" "+get.get(geti).getName()+" "+"支付"+" "+"¥"+get.get(geti).getaamoney());
set.get(seti).setaamoney(get.get(geti).getaamoney()+set.get(seti).getaamoney());
get.remove(geti);
//t2.setText(get.get(geti).getName()+"应向"+set.get(seti).getName()+"支付"+get.get(geti).getaamoney());
}
}
String stringtest="";
for(int i=0;i<aabill.size();i++){
stringtest =stringtest+aabill.get(i)+" ";
}
t3.setText(stringtest.toString());
下面贴上一些比较重要的架构
详细的一个文档介绍请点一下链接:http://download.csdn.net/detail/dtlscsl/7526099,下载需要2分。
1.Android开发中遇到的问题及解决方案
l 问题1:设计三个tabhost,对应不同的activity,希望一个activity数据改变,另一个activity可以看见新的数据,即切换可以重新创建activity。
l 解决方案:在MainActivity里定义tabhost在tabhost.add里面的new intent添加addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP))即可实现。
l 问题2:切换tab时activity的db和cursor没有关闭报错,虽然有时候界面没有出错,但是logcat出现这种error信息。
l 解决方案:用游标打开数据库进行查询时,将从数据信息存进ArrayLsit中,然后就及时关闭cursor。也可用startManagingCursor()方法自动管理cursor,但有时候关闭的时间选的不对,导致后面数据库操作报错。
l 问题3:view child 和parent的关系,同一个界面添加两个listview出错
l 解决方案:利用removeView()方法,解绑
l 问题4:listview跟表格结合,显示账单信息。
l 解决方案:设计了一个MySimpleAdapter类继承SimpleAdapter,实例化一个adapter,将多个xml关联起来。
l 问题5:更新数据库信息之后,后面进行表查询,返回数据库中没有此表的信息。
l 解决方案:因为当时向表中添加了一列新的属性,一般要将app卸载重新安装。
这是我学习android开发中的第一个亲手coding出来的app,可能有点小简陋,但对我来说意义挺重要的,也希望正在学习开发的菜鸟们都能成长为大神~