Android App----Pocketer (Mr Expense)

我来填坑了,因为最近软件测试作业和SOA作业太多,这个APP在5月4日上线后一直没有upgrade,其实有很多坑爹的地方,现在也是,昨天花了一天的时候,对V1.0进行了优化,真的还有很多的bug和一些强大的技术还没掌握,用不好,还是demo看的太少!

这个APP初步叫Mr Expense,后来改名了,具体原因我也忘了,现为Pocketer,至于为什么起这个名,我也忘了。。。现在可以在360平台找到吧。。。


因为现在是课程作业的迭代三阶段,其实这个时候要求只是上线和获取反馈,现在这个应用是不需要联网的,纯单机app,数据都存储在本地,卸载数据就清空了。最后迭代四再是对app的人机交互、服务器等进行优化的阶段,到时候应该会有更进一步的优化,可能会有云存储用户的数据,需要注册,用户名密码神马的,那么顺便得有应用数据清空的功能,也就是一键还原,可能还会再加个界面用户自定义的功能,和优化查看明细的功能。


对于现在这个版本的Pocketer,因为使用SQLite数据库,所以先写个数据库辅助类:

public class BillDbHelper {
	
	private static final String TAG="BillDbHelper";
	private static final String DATABASE_NAME="pocketer.db";
	
	SQLiteDatabase db;
	Context context;
	
	BillDbHelper(Context context){
		this.context=context;
		db=context.openOrCreateDatabase(DATABASE_NAME, 0, null);
		Log.v(TAG,"db path="+db.getPath());
	}
	
	public void createTable_bills(){
		try{
			db.execSQL("Create TABLE bills ("
		            +"_id INTEGER primary key autoincrement,"
					+"typeid integer,"
		            +"desc varchar(50),"
					+"money varchar(50),"
		            +"time varchar(50)"
					+");");
			Log.v(TAG, "create table_bills ok");
		}catch(Exception e){
			Log.v(TAG,"create table_bills error");
		}
	}
	
	public boolean saveBills(int typeid,String desc,String money,String time){
		String sql="";
		try{
			sql="insert into bills values(null,"+typeid+",'"+desc+"','"+money+"','"+time+"')";
			db.execSQL(sql);
			
			Log.v(TAG, "insert into table_bills ok");
			return true;
		}catch(Exception e){
			Log.v(TAG, "insert error");
			return false;
		}
	}
	
	public void deleteBills(int id){
		db.execSQL("delete from bills where _id="+id);
    	Log.v(TAG,"delete bill ok id="+id);
	}
	
	public void CreateTable_pocketerconfig() {
    	try{
	        db.execSQL("CREATE TABLE pocketerconfig ("
	                + "_ID INTEGER PRIMARY KEY,"
	                + "NAME varchar(50)"            
	                + ");");
	        Log.v(TAG,"Create Table config ok");
	    }catch(Exception e){
	    	Log.v(TAG,"Fail to create Table config ,table exists.");
	    }
    }

	public void firstStart(){
		try{
	    	String col[] = {"type", "name" };
	    	Cursor c =db.query("sqlite_master", col, "name='pocketerconfig'", null, null, null, null);
	    	int n=c.getCount();
	    	if (c.getCount()==0){
	    		CreateTable_pocketerconfig();
	    		createTable_bills();
	    	}	    		    	
	    	Log.v(TAG,"c.getCount="+n+"");
	    	    	
	    	
    	}catch(Exception e){
    		Log.v(TAG,"e="+e.getMessage());
    	}
    	
	}
	
	public void close(){
    	db.close();
    }
	
	public Cursor getAllBills(){
		Log.v(TAG, "run get all bill cursor");
		return db.query("bills", new String[]{"_id","desc","( case when typeid=1 then '' else '-' end)||money||'' money","time"} , null,null,null,null,null);
	}
	
	public Cursor getTypeBills(int typeid){
		Log.v(TAG, "run get some type bills cursor");
		return db.query("bills",new String[]{"_id","desc","( case when typeid=1 then '' else '-' end)||money||'' money","time"},"typeid="+typeid,null,null,null,null);
	}
	
	public Cursor getTimeBills(String date1,String date2){
		Log.v(TAG, "run get some time bills cursor");
		return db.query("bills",new String[]{"_id","typeid","( case when typeid=1 then '' else '-' end)||money||'' money"},"time between ? and ?",new String[]{date1,date2},null,null,null);
	}
}

欢迎界面:

public class Welcome extends Activity {
	private LinearLayout welcome; 	
	private BillDbHelper billDbHelper;	
	private Handler welcomeHand;		
	private Runnable welcomeShow;
	
	public void onCreate(Bundle savedInstanceState){
		
		super.onCreate(savedInstanceState);
		setContentView(R.layout.welcome);
		//如果第一次使用,创建数据库
		billDbHelper=new BillDbHelper(this);
		billDbHelper.firstStart();
		billDbHelper.close();
		
		welcome=(LinearLayout)findViewById(R.id.welcome);
		welcome.setOnClickListener(new OnClickListener(){//点击就跳过等待

			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				welcome();
				welcomeHand.removeCallbacks(welcomeShow);
			}
			
		});
		
		welcomeHand=new Handler();
		welcomeShow=new Runnable() {
			
			@Override
			public void run() {
				// TODO Auto-generated method stub
				welcome();
			}
		};
		welcomeHand.postDelayed(welcomeShow, 3000);//等待3秒
	}
	
	private void welcome(){
		startActivity(new Intent(Welcome.this,MainList.class));
		finish();
	}
	
	
	
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		switch (keyCode) {
		case KeyEvent.KEYCODE_BACK:
			Log.v("Welcome.this", "App End...");
			finish();
			System.exit(0);
			return true;
		}
		return false;
	}
	
}

相关的xml文件:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/welcome"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:orientation="vertical"
    android:paddingTop="@dimen/wellayout_paddingtop" >
    
    <ImageView 
        android:id="@+id/wel_image1"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="4"
        android:layout_gravity="center"
        android:src="@drawable/mrexpen"
        android:paddingTop="@dimen/welimage1_paddingtop" />
     
    <TextView
        android:id="@+id/wel_txt1"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:gravity="center_horizontal"
        android:paddingTop="@dimen/weltxt1_paddingtop"
        android:text="@string/weltxt1"
        android:textColor="#cc6600"
        android:textSize="@dimen/weltxt1_textsize" />
    
    <TextView
        android:id="@+id/wel_txt2"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:gravity="center_horizontal"
        android:text="@string/weltxt2"
        android:textSize="@dimen/weltxt2_textsize"
        android:paddingTop="0dp"
        android:textColor="#808000"
        android:typeface="monospace"
        />
   
    

    <ImageView
        android:id="@+id/wel_image2"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="4"
        android:layout_gravity="center"
        android:src="@drawable/secai"
        android:padding="@dimen/welimage2_padding"  />
    
    
</LinearLayout>


效果:




而下个界面也就是MainList类:(下次用fragment写)

布局主要是listitem的布局:

<?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" >  
    <ImageView android:id="@+id/image"  
        android:layout_width="wrap_content" 
        android:layout_height="@dimen/mainlist_listitem_height" 
        android:layout_centerVertical="true" 
        android:layout_alignParentTop="true" 
        android:layout_alignParentBottom="true" 
        android:layout_alignParentLeft="true" 
        android:layout_margin="@dimen/mainlist_listitem_image_padding" />  
    <TextView android:id="@+id/title"  
        android:layout_width="match_parent" 
        android:layout_height="wrap_content"  
        android:layout_toRightOf="@id/image"  
        android:layout_alignParentTop="true"  
        android:layout_alignWithParentIfMissing="true"   
        android:textSize="@dimen/mainlist_listitem_tv1_textsize"
        android:paddingLeft="@dimen/mainlist_listiten_txt_paddingleft" />
    <TextView
        android:id="@+id/text"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/title"
        android:layout_toRightOf="@id/image"
        android:ellipsize="marquee"
        android:gravity="bottom"
        android:singleLine="true"
        android:layout_alignWithParentIfMissing="true"
        android:textSize="@dimen/mainlist_listitem_tv2_textsize"
        android:paddingLeft="@dimen/mainlist_listiten_txt_paddingleft"  />
  
</RelativeLayout>  


Mainlist类一部分:

public class MainList extends ListActivity{
	private String[] mListTitle = { "收入","食品消费","交通消费","医疗消费","穿着消费","娱乐消费","其他。。。"};  
    private String[] mListStr = { "工资/零花钱/奖金","午餐/下午茶/夜宵/...","地铁/公交/打的/...","疫苗/感冒药/点滴/...","化妆品/包包/衣裤/...",
    		"K歌/电动/看电影...","也许还有其他  -, =..." };  
    private int[] mListImage={R.drawable.income,R.drawable.shiwu,R.drawable.jiaotong,
    		R.drawable.yiliao,R.drawable.yifu,R.drawable.yule,R.drawable.zawu};
    private int[] mListColor=new int []{0xffff0033,0xff66cccc,0xff3333cc,0xff66cc33,0xffffcc33,
    		0xffff9900,0xffcc6600};
    
    private  ListView mListView ;
    private  MyListAdapter myAdapter;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {	
    	super.onCreate(savedInstanceState);
    	setContentView(R.layout.mainlist);
        
    	mListView = getListView(); 
	    myAdapter = new MyListAdapter(this);
	    setListAdapter(myAdapter);
	    mListView.setOnItemClickListener(new OnItemClickListener() {
	    	@Override
	    	public void onItemClick(AdapterView<?> adapterView, View view, int position,long id) {
	    		adapterView.getChildAt(position);
	    	//	Toast.makeText(MainUI.this,"您选择了" + mListTitle[position], Toast.LENGTH_LONG).show();
	            Intent intent=new Intent();
	            intent.setClass(MainList.this, BillInfo.class);
	            intent.putExtra("typeid",position+1+"");
	            Log.v("MainUI", "u choose the type: "+position+"+1");
	            startActivity(intent);
	            Log.v("MainUI", "to BillInfo");
	    	}
	    });
	    
	    ExitApplication.getInstance().addActivity(this);
	    }

    class MyListAdapter extends BaseAdapter {
    	private Context mContext;
    	public MyListAdapter(Context context) { 
    		mContext = context;
    		}

    	public int getCount() {   
    		return mListStr.length;
	    }

	    @Override
	    public boolean areAllItemsEnabled() {
	        return false;
	    }

	    public Object getItem(int position) {
	        return position;
	    }

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

	    public View getView(int position, View convertView, ViewGroup parent) {
	        ImageView image = null;
	        TextView title = null;
	        TextView text = null;
	        
	        if (convertView == null) {
	        	convertView = LayoutInflater.from(mContext).inflate(R.layout.mainlist_listitem, null);
		        image = (ImageView) convertView.findViewById(R.id.image);
		        title =(TextView) convertView.findViewById(R.id.title);
		        text= (TextView) convertView.findViewById(R.id.text);
	            }  

	        convertView.setBackgroundColor(mListColor[position]);
	        image.setImageResource(mListImage[position]);
	        title.setText(mListTitle[position]);
	        text.setText(mListStr[position]);
	           
	        return convertView;
	        }
	    }
……
}

效果图:




这里涉及到一个辅助类ExitApplication顾名思义,是用来退出应用的

public class ExitApplication extends Application {
	private List<Activity> activityList=new LinkedList<Activity>();
	private static ExitApplication instance;
	private ExitApplication(){}
	public static ExitApplication getInstance(){
		if(instance==null)
			instance=new ExitApplication();
		return instance;
	}
	
	public void addActivity(Activity activity){
		activityList.add(activity);
	}
	
	public void quitApp(){
		for(Activity activity:activityList){
			activity.finish();
		}
		System.exit(0);
	}
	
}



下面是点击item会跳转到BillInfo界面

部分代码:

public class BillInfo extends Activity {
	
	 private int[] mListImage={R.drawable.shebei,R.drawable.income,R.drawable.shiwu,R.drawable.jiaotong,
	    		R.drawable.yiliao,R.drawable.yifu,R.drawable.yule,R.drawable.zawu};
	 private int[] mListColor=new int []{0xffffffff,0xffff0033,0xff66cccc,0xff3333cc,0xff66cc33,0xffffcc33,
	    		0xffff9900,0xffcc6600};
	
	private EditText et_desc,et_money;
	private Button bt_cancel,bt_confirm,bt_sumup;
	private ListView type_lv,det_lv;
	private TextView view;
	
	private BillDbHelper billdb;
	
	private MyListAdapterTwo myListAdapterTwo;
	
	private String[] from;
	private int[] to;
	
	private SimpleCursorAdapter mAdapter;
	private Cursor cur;
	private int _id;
	private int billid;
	
	protected void onCreate(Bundle savedInstance){
		super.onCreate(savedInstance);
		setContentView(R.layout.billinfo);
		
		et_desc=(EditText)findViewById(R.id.et01);
		et_money=(EditText)findViewById(R.id.et02);
		bt_cancel=(Button)findViewById(R.id.cancel_button);
    	bt_cancel.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				cancel();
			}
		});
		bt_confirm=(Button)findViewById(R.id.confirm_button);
		bt_confirm.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				save(_id);
			}
		});
		bt_sumup=(Button)findViewById(R.id.change_button);
     	bt_sumup.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
			   startActivity(new Intent().setClass(BillInfo.this, BillSumUp.class));
			}
		});
		det_lv=(ListView)findViewById(R.id.billinfo_det_list);
		type_lv=(ListView)findViewById(R.id.billinfo_total_list);
		view=(TextView)findViewById(R.id.free_view);
		
		
		Intent intent=getIntent();
		Bundle bundle=intent.getExtras();
		String type_idstr=bundle.getString("typeid");
		int type_id=Integer.parseInt(type_idstr);
		Log.v("BillInfo","typeid="+type_id);
		_id=type_id;
		updateActivity(_id);

		ExitApplication.getInstance().addActivity(this);
	}
	
	public class MyListAdapterTwo extends BaseAdapter{
		private Context mContext;
		private int id;
    	public MyListAdapterTwo(Context context,int id) { 
    		mContext = context;
    		this.id=id;
    		}

    	public int getCount() {   
    		return mListImage.length;
	    }

	    @Override
	    public boolean areAllItemsEnabled() {
	        return false;
	    }

	    public Object getItem(int position) {
	        return position;
	    }

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

	    public View getView(int position, View convertView, ViewGroup parent) {
	        ImageView image = null;
	        
	        if (convertView == null) {
	        	convertView = LayoutInflater.from(mContext).inflate(R.layout.billinfo_total_listitem, null);
		        image = (ImageView) convertView.findViewById(R.id.total_listitem_image);
	            }  
	    //    Log.v("position", "pos="+position);
	        int colorPos = position % mListColor.length;
	        convertView.setBackgroundColor(mListColor[colorPos]);
	   //     Log.v("setcolor", "success");
	        image.setImageResource(mListImage[colorPos]);
	   //     Log.v("setimage","success");
	        
	        if(!(position==id)){
	        	convertView.getBackground().setAlpha(120);
	    //    	Log.v("emphasize", position-id+"");
	        }
	           
	        return convertView;
	        }
	}
	
	
	
	private void updateActivity(int typeid){
		updateTypeListView(typeid);
	    updateViewColor(typeid);
		updateAllBillListView(typeid);
	}
	
	private void updateTypeListView(int typeid){
		myListAdapterTwo=new MyListAdapterTwo(this,typeid);
		type_lv.setAdapter(myListAdapterTwo);
		type_lv.setOnItemClickListener(new OnItemClickListener() {
			public void onItemClick(AdapterView<?> adapterView, View view, int position,long id){
				_id=position;
				updateActivity(_id);
			}
		});
	}
	
	private void updateViewColor(int typeid){
		view.setBackgroundColor(mListColor[typeid]);
		//Log.v("set view color", view.getBackground()+"");
		//Log.v("button color", bt_sumup.getBackground()+"");
		bt_sumup.setBackgroundColor(0xff333333);
	}
	
	private void updateAllBillListView(int typeid){
		billdb=new BillDbHelper(this);
		if(typeid==0){
		cur=billdb.getAllBills();
		Log.v("get all bill","success");
		}
		else {
			cur=billdb.getTypeBills(typeid);
			Log.v("get type bill","success");
		}
		//billdb.close();
		Log.v("cur.getCount", cur.getCount()+"");
		if(cur.getCount()>0){
		from=new String[]{"_id","desc","money","time"};
		to=new int[]{R.id._id,R.id.billinfo_det_listitem_title,R.id.billinfo_det_listitem_money,R.id.billinfo_det_listitem_time};
		mAdapter=new SimpleCursorAdapter(this, R.layout.billinfo_detail_listitem, cur,from, to);
		det_lv.setAdapter(mAdapter);
		det_lv.setOnItemLongClickListener(new OnItemLongClickListener() {

			@Override
			public boolean onItemLongClick(AdapterView<?> parent, View view,
					int position, long id) {
				// TODO Auto-generated method stub
				TextView tView=(TextView)view.findViewById(R.id._id);
				String idString=(String)tView.getText();
				Log.v("_id", idString);
				billid=Integer.parseInt(idString);
				Log.v("choose the id= ", billid+"");
				new AlertDialog.Builder(BillInfo.this).setTitle("提示").setMessage(
						"确定删除该明细?").setIcon(R.drawable.quit).setPositiveButton("确定",
						new DialogInterface.OnClickListener() {
							public void onClick(DialogInterface dialog, int whichButton) {
								 billdb=new BillDbHelper(BillInfo.this);
								 billdb.deleteBills(billid);
								 
								 Log.v("delete", "success");
								// mAdapter.changeCursor(cur);
								 //((SimpleCursorAdapter) mAdapter).notifyDataSetChanged();
								 updateAllBillListView(_id);
								 Log.v("update", "success");
								 billdb.close();
							}
						}).setNegativeButton("取消",
						new DialogInterface.OnClickListener() {
							public void onClick(DialogInterface dialog, int whichButton) {
							}
						}).show();

				return true;
		}
		});
		Log.v("output bills", "success");}
		else {
			det_lv.setAdapter(null);
		}
		billdb.close();
	}

			
	
	
	
	private void cancel(){
		Log.v("billinfo", "u cancel bt");
		et_desc.setText("");
		et_money.setText("");
		et_desc.setHint("ADD BILL(描述):");
		et_money.setHint("00.00");
	}
	
	private void save(int typeid){
		Log.v("billinfo", "u save bt");
		String descstr=et_desc.getText().toString();
		String fee=null;
		String s=et_money.getText().toString();
		if((descstr.length()!=0) &&( s.length()!=0)){
			Log.v("string", "not null");
		fee=moneyDeal(s);
		Log.v("fee", fee);
		if(fee.equals("0.00")){
			Toast.makeText(BillInfo.this, "输入正确money", Toast.LENGTH_SHORT).show();
		}else{
		Calendar c = Calendar. getInstance();
		Date d=c.getTime();
		SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
		String timestr=sdf.format(d);
		Log.v("time", timestr);
		billdb=new BillDbHelper(this);
		if(_id>0){
			Log.v("typeid", _id+"");
			if(billdb.saveBills(_id, descstr, fee, timestr)){
				Log.v("save", "success");
				cancel();
				updateAllBillListView(_id);
				//Cursor cursor =billdb.getTypeBills(_id);
				//mAdapter.changeCursor(cursor);
				//((SimpleCursorAdapter) mAdapter).notifyDataSetChanged();
				Log.v("update", "success");
			}}else {
				Toast.makeText(this, "请选个类别进行保存", Toast.LENGTH_SHORT).show();
			}
		billdb.close();
		}}
		else {
			Toast.makeText(BillInfo.this, "输入desc和money", Toast.LENGTH_SHORT).show();
		}
	}
			
	private String moneyDeal(String string){
		String result="0";
		String result2="0";

		int index=string.indexOf(".");
		if(index==0){
			if(string.length()==1||(string.length()==2 && string.substring(1).equals("0"))||
					(string.length()>2 && (string+"0").substring(1, 3).equals("00"))){
				result="0";
			}
			else {
			     result="0"+string;
			}
		}
		if(index==-1){
			if(Integer.parseInt(string)==0)
				result="0";
			else
				result=string;
		}
		if(index>0){
			if(index==string.length()-1){
				if(Integer.parseInt(string.substring(0,index))==0)
					result="0";
				else
					result=string.substring(0,index);
			}else {
				String string2=string+"00";
				if(Integer.parseInt(string.substring(0,index))==0){
					if(Integer.parseInt(string.substring(index+1,index+3))==0)
					     result="0";
					else
						result=string2.substring(0,index+3);}
				else{
					if(Integer.parseInt(string2.substring(index+1,index+3))==0)
						result=string2.substring(0,index);
					else
						result=string2.substring(0,index+3);}
				
				}
					
			}
		int index2=result.indexOf(".");
		if(index2==-1)
			result2=result+".00";
		else if(index2==result.length()-2)
			result2=result+"0";
		else result2=result;
		
		
		return result2;
		}

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" >
    <LinearLayout 
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="9"
        android:orientation="horizontal"
        android:baselineAligned="false"
         >
        <LinearLayout
            android:layout_width="70dp"
            android:layout_height="match_parent"
            android:orientation="vertical" >

        <ListView
            android:id="@+id/billinfo_total_list"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:cacheColorHint="@android:color/transparent"
            android:divider="@null"
            android:scrollbars="none|vertical" />
       
        </LinearLayout>
        <LinearLayout
            android:layout_width="8dp"
            android:layout_height="match_parent"
            android:orientation="vertical" >

        <TextView
            android:id="@+id/free_view"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="#000000" />

        </LinearLayout>
        <LinearLayout 
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical" >
        <LinearLayout 
            android:layout_width="match_parent"
            android:layout_height="60dp"
            
            android:orientation="horizontal" >

            <EditText
                android:id="@+id/et01"
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight="3"
                android:hint="@string/hint01"
                android:maxLength="10" />

            <EditText
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:id="@+id/et02"
                android:layout_weight="1"
                android:maxLength="7"
                android:hint="@string/hint02"
                android:singleLine="true"
                android:inputType="numberDecimal" />
            
        </LinearLayout>
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="60dp"
            
            android:orientation="horizontal" >

            <Button
                android:id="@+id/cancel_button"
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:background="#666666"
                android:gravity="center"
                android:text="@string/cancel"
                android:textColor="#ffffff"
                android:textStyle="bold" />

            <Button
                android:id="@+id/confirm_button"
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:background="#666666"
                android:gravity="center"
                android:text="@string/save"
                android:textColor="#ffffff"
                android:textStyle="bold" />
            
        </LinearLayout>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"
            android:orientation="vertical" >

            <ListView
                android:id="@+id/billinfo_det_list"
                android:layout_width="match_parent"
                android:layout_height="match_parent" >

            </ListView>

             </LinearLayout>   
        </LinearLayout>
    </LinearLayout>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:orientation="horizontal" >

    <Button
        android:id="@+id/change_button"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="#000000"
        android:gravity="center"
        android:text="@string/change"
        android:textColor="#ffffff"
        android:textStyle="bold" />

</LinearLayout>
</LinearLayout>

outline是:



效果:



图标除了第一个是汇总以外,其余的都与在前面一页对应。

收入是正的,消费是负的

每一项输出备注、日期、money

长按可以删除明细

按钮主要是跳转到饼图消费分析(自然不包括收入)

图标都有setAlpha,所以会有一些视觉上的别样感受吧


按钮式跳转到BillSumUp界面,饼图消费分析,比较直观:这里用了fragment

public class BillSumUp extends FragmentActivity implements OnClickListener {
	private View tab_view_1, tab_view_2;
	private TextView tab_text_1, tab_text_2;
	private int tab_status = -1;

	private BillDbHelper billdb;
	private Cursor cursor,cursor2;
	private float[] bill;
	private float[] bill2;
	private String today,today2;
	private String weekAgo,thisMonthFirstDay;

	/**
	 * 用于对Fragment进行管理
	 */
	private FragmentManager fragmentManager;

	private WeekSumUp tabFragment_1;
	private MonthSumUp tabFragment_2;

	

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.billsumup);
		

		tab_view_1 = findViewById(R.id.linearLayout_tab_1);
		tab_view_2 = findViewById(R.id.linearLayout_tab_2);

		tab_view_1.setBackgroundColor(0xff000033);
		tab_view_2.setBackgroundColor(0xff000033);
		
		tab_text_1 = (TextView) findViewById(R.id.tab_text_1);
		tab_text_2 = (TextView) findViewById(R.id.tab_text_2);

		tab_text_1.setTextColor(0xff999999);
		tab_text_2.setTextColor(0xff999999);


		tab_view_1.setOnClickListener(this);
		tab_view_2.setOnClickListener(this);
		

		billdb=new BillDbHelper(this);
		Date date=new Date();
		long time=date.getTime()/1000-7*24*3600;
		Date date2=new Date();
		date2.setTime(time*1000);
		SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
		 today=sdf.format(date);
		 weekAgo=sdf.format(date2);
		Log.v("today", today);
		Log.v("weekago", weekAgo);
		cursor=billdb.getTimeBills(weekAgo, today);
		bill=new float[8];
		for(int i=0;i<bill.length;i++)
			bill[i]=0;
		while(cursor.moveToNext()){
			String money=cursor.getString(cursor.getColumnIndex("money"));
			String typeid=cursor.getString(cursor.getColumnIndex("typeid"));
			float moneyDouble=Float.parseFloat(money);
			int typeInt=Integer.parseInt(typeid);
			bill[typeInt]=bill[typeInt]-moneyDouble;
			bill[0]+=moneyDouble;
		}
		Log.v("bill[]", bill[0]+" "+bill[1]+" "+bill[2]+" "+bill[3]+" "+bill[4]+" "
				+bill[5]+" "+bill[6]+" "+bill[7]);
		
		Calendar cal = Calendar.getInstance();  
        int minDate=cal.getActualMinimum(5);  
        cal.set(Calendar.DATE, minDate);  
        Date date4=cal.getTime();
		 today2=sdf.format(date);
		 thisMonthFirstDay=sdf.format(date4);
		 Log.v("today2", today2);
			Log.v("firstday", thisMonthFirstDay);
		cursor2=billdb.getTimeBills(thisMonthFirstDay, today2);
		bill2=new float[8];
		for(int i=0;i<bill2.length;i++)
			bill2[i]=0;
		while(cursor2.moveToNext()){
			String money=cursor2.getString(cursor2.getColumnIndex("money"));
			String typeid=cursor2.getString(cursor2.getColumnIndex("typeid"));
			float moneyDouble=Float.parseFloat(money);
			int typeInt=Integer.parseInt(typeid);
			bill2[typeInt]=bill2[typeInt]-moneyDouble;
			bill2[0]+=moneyDouble;
		}
		Log.v("bill2[]", bill2[0]+" "+bill2[1]+" "+bill2[2]+bill2[3]+bill2[4]
				+bill2[5]+bill2[6]+bill2[7]);
		
		fragmentManager = getSupportFragmentManager();
		// 第一次启动时选中第0个tab
		setTabSelection(0);
		Log.v("settab", "success");
		ExitApplication.getInstance().addActivity(this);
		billdb.close();
	}

	private void setTabSelection(int index) {
		// TODO Auto-generated method stub
		// 开启一个Fragment事务
		FragmentTransaction transaction = fragmentManager.beginTransaction();
		// 切换设置动画
		setAnimations(transaction, index);
		// 先隐藏掉所有的Fragment,以防止有多个Fragment显示在界面上的情况
		hideFragments(transaction);
		// 清除
		clearBackground();
		switch (index) {
		case 0:
			tab_view_1.setBackgroundColor(0xff333333);
			tab_text_1.setTextColor(Color.WHITE);
			if (tabFragment_1 == null) {
				// 如果Fragment为空,则创建一个并添加到界面上
				tabFragment_1 = new WeekSumUp();
				Bundle bundle=new Bundle();
				bundle.putFloatArray("bill[week]", bill);
				bundle.putString("weekago",weekAgo );
				bundle.putString("today", today);
				tabFragment_1.setArguments(bundle);
				transaction.add(R.id.content, tabFragment_1);
			} else {
				// 如果Fragment不为空,则直接将它显示出来
				transaction.show(tabFragment_1);
			}
			break;
		case 1:
			tab_view_2.setBackgroundColor(0xff333333);
			tab_text_2.setTextColor(Color.WHITE);
			if (tabFragment_2 == null) {
				// 如果Fragment为空,则创建一个并添加到界面上
				tabFragment_2 = new MonthSumUp();
				Bundle bundle=new Bundle();
				bundle.putFloatArray("bill[month]", bill2);
				bundle.putString("firstday",thisMonthFirstDay );
				bundle.putString("today2", today2);
				tabFragment_2.setArguments(bundle);
				transaction.add(R.id.content, tabFragment_2);
			} else {
				// 如果Fragment不为空,则直接将它显示出来
				transaction.show(tabFragment_2);
			}
			break;
		default:
			break;
		}
		transaction.commit();
	}

	/**
	 * 设置Fragment切换动画
	 * 
	 * @param transaction
	 */
	private void setAnimations(FragmentTransaction transaction, int index) {
		// TODO Auto-generated method stub
		if (tab_status < index || tab_status == -1) {
			transaction.setCustomAnimations(R.anim.push_left_in,
					R.anim.push_left_out);
		} else if (tab_status > index) {
			transaction.setCustomAnimations(R.anim.back_left_in,
					R.anim.back_right_out);
		}
		tab_status = index;
	}

	/**
	 * 隐藏Fragment
	 * 
	 * @param transaction
	 */
	private void hideFragments(FragmentTransaction transaction) {
		// TODO Auto-generated method stub
		if (tabFragment_1 != null) {
			transaction.hide(tabFragment_1);
		}
		if (tabFragment_2 != null) {
			transaction.hide(tabFragment_2);
		}
		}


	@Override
	public void onClick(View v) {
		// TODO Auto-generated method stub
		switch (v.getId()) {
		case R.id.linearLayout_tab_1:
			setTabSelection(0);
			break;
		case R.id.linearLayout_tab_2:
			setTabSelection(1);
			break;
		default:
			break;
		}
	}

	
	/**
	 * 清除点击效果
	 */
	private void clearBackground() {
		tab_view_1.setBackgroundColor(0xff000033);
		tab_view_2.setBackgroundColor(0xff000033);

		tab_text_1.setTextColor(0xff999999);
		tab_text_2.setTextColor(0xff999999);


	}
……
}

weeksumup类部分:

public class WeekSumUp extends Fragment {
	
	View view;
	TextView timeText;
	TextView moneyText,foodText;
	Button btn;
	PieChartView barChart;
	float[] bill;
	Activity mActivity;
	String today,weekAgo;
	
	

	
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		view = inflater.inflate(R.layout.weeksumup, container, false);
		btn=(Button)view.findViewById(R.id.btn01);
        btn.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				 Intent intent=new Intent();
		         intent.setClass(mActivity,BillInfo.class);
		         intent.putExtra("typeid","0");
		         startActivity(intent);
			}
		});
        timeText=(TextView)view.findViewById(R.id.timetv01);
		moneyText=(TextView)view.findViewById(R.id.totaltv01);
		
		foodText=(TextView)view.findViewById(R.id.foodtv01);
		SpannableString ss=new SpannableString("FoodTransportHealthcareClothesEntertainmentOthers");
		ss.setSpan(new ForegroundColorSpan(Color.YELLOW), 0,4,Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
		ss.setSpan(new ForegroundColorSpan(Color.BLUE), 4,13,Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
		ss.setSpan(new ForegroundColorSpan(Color.GRAY), 13,23,Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
		ss.setSpan(new ForegroundColorSpan(Color.MAGENTA),23,30,Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
		ss.setSpan(new ForegroundColorSpan(Color.RED), 30,43,Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
		ss.setSpan(new ForegroundColorSpan(Color.GREEN), 43,49,Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
		foodText.setText(ss);
		
		bill=getArguments().getFloatArray("bill[week]");
		today=getArguments().getString("today");
		weekAgo=getArguments().getString("weekago");
		
		
		PieChartView pcv = (PieChartView)view.findViewById(R.id.pie01);
        pcv.setDataCount(6);
        pcv.setColor(new int[]{Color.YELLOW,Color.BLUE,Color.GRAY,Color.MAGENTA,Color.RED,Color.GREEN});
        pcv.setData(new float[]{bill[2],bill[3],bill[4],bill[5],bill[6],bill[7]});
        pcv.setDataTitle(new String[]{"food","transport","healthcare","clothes","entertainment","others"});
        //pcv.setSpecial(5);
		
        SpannableString s=new SpannableString(weekAgo+" to "+today);
        s.setSpan(new ForegroundColorSpan(0xffff0099), 0,10,Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        s.setSpan(new ForegroundColorSpan(0xffcccccc), 11,13,Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        s.setSpan(new ForegroundColorSpan(0xffff0099), 14,24,Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        s.setSpan(new StyleSpan(Typeface.BOLD), 11,13,Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        
        
        timeText.setText(s);
        float income=0;
        if(bill[1]==0)
        	income=0;
        else income=-bill[1];
        double temp=(double)Math.abs((bill[1]+bill[0]));
        BigDecimal bd=new BigDecimal(temp);
        moneyText.setText("TOTAL IN: "+"\n"+"                    "+income+"\n"+"TOTAL OUT: "+"\n"+"                    "+ bd.setScale(2, BigDecimal.ROUND_HALF_UP));
        
 
        
		return view;
	}
	
	
	public void onActivityCreated(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onActivityCreated(savedInstanceState);
		mActivity=getActivity();
	}
	
	
	

    
   
}

因为用了fragment,对fragment间以及与Activity间的通信有了一定了解

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" >
    
     <LinearLayout
        android:id="@+id/tab_menu"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:baselineAligned="false"
        android:orientation="horizontal" >

        <LinearLayout
            android:id="@+id/linearLayout_tab_1"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:orientation="vertical" >

           

            <TextView
                android:id="@+id/tab_text_1"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_gravity="center_horizontal"
                android:layout_marginTop="@dimen/billsumuo_margintop"
                android:gravity="center_horizontal"
                android:text="@string/week"
                android:textSize="@dimen/ts03" />
        </LinearLayout>
        <LinearLayout
            android:id="@+id/linearLayout_tab_2"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:orientation="vertical" >

          

            <TextView
                android:id="@+id/tab_text_2"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_gravity="center_horizontal"
                android:layout_marginTop="@dimen/billsumuo_margintop"
                android:gravity="center_horizontal"
                android:text="@string/month"
                android:textSize="@dimen/ts03" />
        </LinearLayout>
    </LinearLayout>

    <FrameLayout
        android:id="@+id/content"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_below="@id/tab_menu" >

    </FrameLayout>



</RelativeLayout>

weeksumup的布局

<?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" >
                
    <TextView 
                    android:id="@+id/foodtv01"
                    android:layout_width="match_parent"
                    android:layout_height="0dp"
                    android:layout_weight="4"
                    android:textStyle="bold"
                    android:textSize="@dimen/ts04"
                    android:gravity="center"
                    android:background="#FFFFFF" />
    
                <com.pocketer.PieChartView 
                    android:layout_width="match_parent"
                    android:layout_height="0dp"
                    android:layout_weight="29"
                    android:id="@+id/pie01" />
                <TextView
                    android:id="@+id/timetv01"
                    android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="7"
        android:background="#333333"
        android:gravity="center"
        android:textSize="@dimen/ts05"
        android:textStyle="italic" />
                <TextView
                    android:id="@+id/totaltv01"
                    android:layout_width="match_parent"
                    android:layout_height="0dp"
                    android:layout_weight="13"
                    android:paddingTop="@dimen/paddingtop02"
                    android:paddingBottom="@dimen/paddingtop02"
                    android:paddingLeft="@dimen/paddingleft03"
                    android:textColor="#660033"
                    android:background="#ffffff"
                    android:textSize="@dimen/ts06" />
                <Button
                    android:id="@+id/btn01"
                    android:layout_width="match_parent"
                    android:layout_height="0dp"
                    android:layout_weight="6"
                    android:gravity="center"
                    android:background="#333333"
                    android:text="@string/change"
                    android:textColor="#ffffff"
                    android:textStyle="bold" />
    
    

</LinearLayout>

很多变量名也可以优化,后期会改。

效果:




至此,迭代三做完了,这个项目上线大概花了5天,昨天又更新了应用,准备在2周后实现我想到的新功能吧。迭代四是和小伙伴们组队一起,但是不是使用我的项目,但是这个应用今后还会维护下去吧,有新点子,或者优化就去upgrade一下。比如这个饼图,必须优化,最近在学数字图像处理,但是遇到一些问题,还是很蛋疼的,所以还是要努力啊。。。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值