Android版DailyInsist(三)——业务逻辑和数据操作MainFragment

业务逻辑主要在主界面MainFragment进行,流程图(非完整)如下:


抽象出一个对象——任务Task,创建 TaskBean类:
/**
 * 
 * @ClassName TaskBean
 * @Description a bean store task information; every time only have one running
 *              task
 * @author kiyonlin@163.com
 * @date 2014-1-6 下午1:46:12
 */
public class TaskBean {

	/**
	 * task id in database for update or delete
	 */
	private int taskId;

	/**
	 * number of task during days
	 */
	private int during;

	/**
	 * number of completed days
	 */
	private int completed;

	/**
	 * task content
	 */
	private String content;

	/**
	 * the start date of task
	 */
	private String startTime;

	/**
	 * flag if today's task is done
	 */
	private boolean doneToday;

	/**
	 * flag if the task is running
	 */
	private boolean currentTask;

	/**
	 * 
	 * @Method: getStartDate
	 * @Description: get the start date of the task like "1月 03"
	 * @param @return
	 * @return String
	 * @throws
	 */
	@SuppressLint("SimpleDateFormat")
	public String getStartDate() {
		String startDate = "";
		try {
			SimpleDateFormat myFormatter = new SimpleDateFormat(
					"yyyy-MM-dd HH:mm:ss");
			Date date = myFormatter.parse(startTime);
			// long theDateMill = date.getTime() - (7 * (24 * 60 * 60 * 1000));
			// Date theDate = new Date(theDateMill);
			Calendar cal = Calendar.getInstance();
			cal.setTime(date);
			int day = cal.get(Calendar.DATE);
			int month = cal.get(Calendar.MONTH) + 1;
			startDate = month + "月 " + day + "日";
		} catch (Exception e) {
			return "";
		}
		return startDate;
	}

	/**
	 * 
	 * @Method: getEndDate
	 * @Description: get the end date of the task like "1月 16"
	 * @param @return
	 * @return String
	 * @throws
	 */
	@SuppressLint("SimpleDateFormat")
	public String getEndDate() {
		String endDate = "";
		try {
			SimpleDateFormat myFormatter = new SimpleDateFormat(
					"yyyy-MM-dd HH:mm:ss");
			Date date = myFormatter.parse(startTime);
			// start date adds during days
			long theDateMill = date.getTime()
					+ ((during - 1) * (24 * 60 * 60 * 1000));
			Date theDate = new Date(theDateMill);
			Calendar cal = Calendar.getInstance();
			cal.setTime(theDate);
			int day = cal.get(Calendar.DATE);
			int month = cal.get(Calendar.MONTH) + 1;
			endDate = month + "月 " + day + "日";
		} catch (Exception e) {
			return "";
		}
		return endDate;
	}

	{...set and get	}

}


相应数据存到本地数据库di.db3的tbl_task表(ID,持续天数,完成天数,任务内容,开始时间,今天是否签到,是否为当前任务)中,使用继承 SQLiteOpenHelper类的子类 MyDatabaseHelper来完成对数据库的操作:
public class MyDatabaseHelper extends SQLiteOpenHelper {
	final String TAG = "MyDatabaseHelper";
	final String CREATE_TABLE_SQL = "create table tbl_task(_id integer primary "
			+ "key , during , completed, content, startTime, doneToday, currentTask)";

	public MyDatabaseHelper(Context context, String name, int version) {
		super(context, name, null, version);
	}

	@Override
	public void onCreate(SQLiteDatabase db) {
		try {
			// 第一次使用数据库时自动建表
			db.execSQL(CREATE_TABLE_SQL);
		} catch (SQLException e) {
			Log.e(TAG, "SQLiteException, 创建表发生异常", e);
		}
	}

	@Override
	public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
		Log.w(TAG, "--------onUpdate database Called--------" + oldVersion
				+ "--->" + newVersion);
	}
}



对数据库的相关操作暂时有插入新任务、获取当前任务、获取任务列表、删除任务、更新签到状态。插入新任务时会将之前的任务(假如有的话)置为完成的状态,因为每次只允许有一个执行的任务。所有的方法都封装在 DailyInsistDao类中:
public class DailyInsistDao {
	final static String TAG = "DailyInsistDao";

	/**
	 * 
	 * @Method: insertTask
	 * @Description: insert a new task
	 * @param @param dbHelper
	 * @param @param during the during days
	 * @param @param completed the completed days
	 * @param @param content task content
	 * @param @param startTime start time
	 * @return void
	 * @throws
	 */
	public static void insertTask(MyDatabaseHelper dbHelper, int during,
			int completed, String content, String startTime, boolean doneToday) {
		try {
			/*
			 * every time only have one running task
			 */
			setTaskFinished(dbHelper);
			
			boolean currentTask = true;
			// 执行插入语句
			dbHelper.getWritableDatabase().execSQL(
					"insert into tbl_task values(? , ? , ?, ? , ?, ?, ?)",
					new Object[] { null, during, completed, content, startTime,
							doneToday, currentTask });
		} catch (SQLException e) {
			Log.e(TAG, "SQLiteException, 调用本地数据库插入操作insertTask发生异常", e);
		}
	}

	/**
	 * 
	 * @Method: getTasks
	 * @Description: get all tasks
	 * @param @param dbHelper
	 * @param @param npos
	 * @param @param ncount
	 * @param @return
	 * @return List<TaskBean>
	 * @throws
	 */
	public static List<TaskBean> getTasks(MyDatabaseHelper dbHelper, int npos,
			int ncount) {
		ArrayList<TaskBean> result = null;
		Cursor cursor = null;
		try {

			// 执行查询
			cursor = dbHelper.getReadableDatabase().rawQuery(
					"select * from tbl_task order by _id DESC limit ?, ?",
					new String[] { npos + "", ncount + "" });

			result = new ArrayList<TaskBean>();

			// 遍历Cursor结果集
			while (cursor.moveToNext()) {
				int taskId = cursor.getInt(0);
				int during = cursor.getInt(1);
				int completed = cursor.getInt(2);
				String content = cursor.getString(3);
				String startTime = cursor.getString(4);
				boolean doneToday = cursor.getShort(5) == 0 ? false : true;
				boolean currentTask = cursor.getShort(6) == 0 ? false : true;

				// 将结果集中的数据存入ArrayList中
				TaskBean otask = new TaskBean();
				// 取出查询记录中的值
				otask.setTaskId(taskId);
				otask.setDuring(during);
				otask.setCompleted(completed);
				otask.setContent(content);
				otask.setStartTime(startTime);
				otask.setDoneToday(doneToday);
				otask.setCurrentTask(currentTask);

				result.add(otask);
			}
		} catch (SQLiteException e) {
			Log.e(TAG, "SQLiteException, 调用本地数据库查询操作getTasks发生异常", e);
		} finally {
			if (cursor != null) {
				cursor.close();
			}
		}
		return result;
	}

	/**
	 * 
	 * @Method: getcurrentTask
	 * @Description: get current task; return null if there is no running task
	 * @param @param dbHelper
	 * @param @return
	 * @return TaskBean
	 * @throws
	 */
	public static TaskBean getcurrentTask(MyDatabaseHelper dbHelper) {
		Cursor cursor = null;
		TaskBean otask = null;
		try {
			// 执行查询
			cursor = dbHelper.getReadableDatabase().rawQuery(
					"select * from tbl_task where currentTask = 1",
					new String[] {});
			// 遍历Cursor结果集
			while (cursor.moveToNext()) {
				// 取出查询记录中的值
				int taskId = cursor.getInt(0);
				int during = cursor.getInt(1);
				int completed = cursor.getInt(2);
				String content = cursor.getString(3);
				String startTime = cursor.getString(4);
				boolean doneToday = cursor.getShort(5) == 0 ? false : true;
				boolean currentTask = cursor.getShort(6) == 0 ? false : true;
				// 将结果集中的数据存入ArrayList中
				otask = new TaskBean();
				// 取出查询记录中的值
				otask.setTaskId(taskId);
				otask.setDuring(during);
				otask.setCompleted(completed);
				otask.setContent(content);
				otask.setStartTime(startTime);
				otask.setDoneToday(doneToday);
				otask.setCurrentTask(currentTask);

				return otask;
			}
		} catch (SQLException e) {
			Log.e(TAG, "SQLiteException, 调用本地数据库插入操作insertVisitRecord发生异常", e);
		} finally {
			if (cursor != null) {
				cursor.close();
			}
		}
		return otask;
	}

	/**
	 * 
	 * @Method: updateDoneState
	 * @Description: set everyday's done state; if done today, the completed day
	 *               should increase
	 * @param @param dbHelper
	 * @param @param doneToday
	 * @return void
	 * @throws
	 */
	public static void updateDoneState(MyDatabaseHelper dbHelper, int taskId,
			boolean doneToday) {
		try {
			String sql;

			if (doneToday) {
				sql = "update tbl_task set doneToday = ? "
						+ ", completed = (completed + 1) " + "where _id = ?";
			} else {
				sql = "update tbl_task set doneToday = ? where _id = ?";
			}
			// 执行更新语句
			dbHelper.getWritableDatabase().execSQL(sql,
					new Object[] { doneToday, taskId });
			Log.i(TAG, "updateDoneState success");
		} catch (SQLException e) {
			Log.e(TAG, "SQLiteException, 调用本地数据库插入操作updateDoneState发生异常", e);
		}
	}

	/**
	 * 
	 * @Method: setTaskFinished
	 * @Description: set the task to the passed one which had finished
	 * @param @param dbHelper
	 * @param @param currentTask
	 * @return void
	 * @throws
	 */
	private static void setTaskFinished(MyDatabaseHelper dbHelper) {
		try {
			// 执行更新语句
			dbHelper.getWritableDatabase()
					.execSQL(
							"update tbl_task set currentTask = 0 where currentTask = 1");
		} catch (SQLException e) {
			Log.e(TAG, "SQLiteException, 调用本地数据库插入操作setTaskFinished发生异常", e);
		}
	}

	/**
	 * 
	 * @Method: deleteTask
	 * @Description: delete a task
	 * @param @param dbHelper
	 * @param @param taskId
	 * @return void
	 * @throws
	 */
	public static void deleteTask(MyDatabaseHelper dbHelper, int taskId) {
		try {
			// 执行更新语句
			dbHelper.getWritableDatabase().execSQL(
					"delete from tbl_task where _id = ?",
					new Object[] { taskId });
		} catch (SQLException e) {
			Log.e(TAG, "SQLiteException, 调用本地数据库插入操作deleteTask发生异常", e);
		}
	}
}


程序开启后就会进入主界面,然后根据上述的业务逻辑进行判断如何显示界面。IOS版本中,点击“DoneToday”按钮后,会有动画效果,按钮先旋转再垂直下落至消失,然后显示剩余天数。这个效果后期再考虑。更新后的 MainFragment如下:
@EFragment(R.layout.frag_main)
public class MainFragment extends BaseFragment {

	private MyDatabaseHelper dbHelper;

	@ViewById
	LinearLayout ll_new_round, ll_running_round, ll_frag_main_root;

	@ViewById
	TextView tv_done, tv_title, tv_remain;

	@ViewById
	Button btn_done_today, btn_new_round;

	@StringRes
	String str_remain_format, str_last_day, str_failed, str_finished;

	@ColorRes
	int main_bg, record_title_bg;

	private TaskBean task;

	@AfterViews
	void initView() {
		dbHelper = new MyDatabaseHelper(this.getActivity(), "di.db3", 1);
		task = DailyInsistDao.getcurrentTask(dbHelper);
		if (task == null) {
			/*
			 * if there is no task, show New Round button
			 */
			ll_new_round.setVisibility(View.VISIBLE);
			btn_new_round.setTextColor(main_bg);
			ll_running_round.setVisibility(View.GONE);
		} else {

			ll_running_round.setVisibility(View.VISIBLE);
			ll_new_round.setVisibility(View.GONE);
			if (isTaskFailed(task.getCompleted(), task.getStartTime())) {
				/*
				 * show failed title and new round button
				 */
				tv_remain.setText(str_failed);

				ll_new_round.setVisibility(View.VISIBLE);
				btn_new_round.setTextColor(main_bg);
			} else {
				/*
				 * show completed days, title
				 */
				tv_done.setText(task.getCompleted() + "");
				tv_title.setText(task.getContent());

				if (task.isDoneToday()) {
					/*
					 * show remain days; hide done today button
					 */
					btn_done_today.setVisibility(View.GONE);
					tv_remain.setVisibility(View.VISIBLE);
					int remainDays = task.getDuring() - task.getCompleted();

					showRemainDays(remainDays);

				} else {
					/*
					 * show done today button; hide remain days
					 */
					tv_remain.setVisibility(View.GONE);
					btn_done_today.setVisibility(View.VISIBLE);
				}
			}
		}
	}

	/**
	 * 
	 * @Method: isTaskFailed
	 * @Description: check if the task is failed
	 * @param @param completed the completed days
	 * @param @param startTime time when the task started
	 * @param @return
	 * @return boolean
	 * @throws
	 */
	private boolean isTaskFailed(int completed, String startTime) {
		/*
		 * get the days between now and the start time. if the value larger than
		 * completed days, then task failed
		 */
		int interval = Util.daysBetweenTwoDate(startTime.substring(0, 10), Util
				.currentTime().substring(0, 10));
		return interval > completed;
	}

	@AfterInject
	void run() {

	}

	private static final int RC_NEW_ROUND = 0;

	@Click
	void btn_new_round() {
		/*
		 * receive result in DailyInsistActivity
		 */
		Intent intent = new Intent(this.getActivity(), NewTaskActivity_.class);
		
		this.getActivity().startActivityForResult(intent, RC_NEW_ROUND);
	}

	@Click
	void btn_done_today() {
		/*
		 * increase completed days by 1; show remain days
		 */
		// dismiss done today button by animate in the future
		btn_done_today.setVisibility(View.GONE);

		tv_done.setText("" + (task.getCompleted() + 1));

		tv_remain.setVisibility(View.VISIBLE);

		int remainDays = task.getDuring() - task.getCompleted() - 1;
		showRemainDays(remainDays);

		DailyInsistDao.updateDoneState(dbHelper, task.getTaskId(), true);
	}

	private void showRemainDays(int remainDays) {
		switch (remainDays) {
		case 0:
			/*
			 * show finished layout
			 */
			tv_remain.setText(str_finished);

			ll_frag_main_root.setBackgroundColor(record_title_bg);

			ll_new_round.setVisibility(View.VISIBLE);
			
			btn_new_round.setTextColor(record_title_bg);
			break;
		case 1:
			tv_remain.setText(str_last_day);
			int line = tv_remain.getLineCount();
			while (line > 1) {
				float textSize = tv_remain.getTextSize() - 1;
				tv_remain.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize);
				line = tv_remain.getLineCount();
			}
			break;
		default:
			tv_remain.setText(String.format(str_remain_format, remainDays));
			break;
		}
	}

	@Override
	public void show() {
	}

	@UiThread
	void showShortToastMsg(String msg) {
		Toast.makeText(getActivity(), msg, Toast.LENGTH_SHORT).show();
	}

	@UiThread
	void showLongToastMsg(String msg) {
		Toast.makeText(getActivity(), msg, Toast.LENGTH_LONG).show();
	}
}


新建任务是在另一个activity中( NewTaskActivity)进行,这个activity也比较简单,获取到新任务的持续时间和内容后,插入到数据库中即可。有一点需要注意的是,选择任务周期需要对字体大小进行设置,只有一个参数的setTextSize (float size)方法,默认使用的单位是SP,而从资源文件获得的字体大小单位已经从SP转化为PX,所以使用该方法会使得字体比预计的要大。正确的方法是指定字体大小单位,使用setTextSize (int unit, float size)方法。另外,切换任务周期的时候可以加上动画,使得字体渐影放大(缩小)。具体代码如下:
@SuppressWarnings("deprecation")
@NoTitle
@EActivity(R.layout.new_task)
public class NewTaskActivity extends Activity {
	/*
	 * default is 14 days
	 */
	private int during = 14;

	@ViewById
	TextView tv_7, tv_14, tv_21;

	@ViewById
	EditText et_todo;

	@Click
	void btn_ok() {
		String whatToDo = et_todo.getText().toString();
		if (TextUtils.isEmpty(whatToDo)) {
			showAlertDialog();
		} else {
			MyDatabaseHelper dbHelper = new MyDatabaseHelper(this, "di.db3", 1);
			DailyInsistDao.insertTask(dbHelper, during, 0, whatToDo,
					Util.currentTime(), false);
			setResult(RESULT_OK);
			finish();
		}
	}

	@Click
	void btn_cancel() {
		finish();
	}

	@DimensionRes
	/*
	 * the obtained text size's unit is px
	 */
	float text_title, selected_days;

	@ColorRes
	int setting_text_light, main_text;

	@Click
	void tv_7() {
		/*
		 * setTextSize(float size) use the default unit of sp
		 */
		tv_7.setTextColor(main_text);
		tv_7.setTextSize(TypedValue.COMPLEX_UNIT_PX, selected_days);

		tv_14.setTextColor(setting_text_light);
		tv_14.setTextSize(TypedValue.COMPLEX_UNIT_PX, text_title);

		tv_21.setTextColor(setting_text_light);
		tv_21.setTextSize(TypedValue.COMPLEX_UNIT_PX, text_title);

		during = 7;
	}

	@Click
	void tv_14() {
		tv_7.setTextColor(setting_text_light);
		tv_7.setTextSize(TypedValue.COMPLEX_UNIT_PX, text_title);

		tv_14.setTextColor(main_text);
		tv_14.setTextSize(TypedValue.COMPLEX_UNIT_PX, selected_days);

		tv_21.setTextColor(setting_text_light);
		tv_21.setTextSize(TypedValue.COMPLEX_UNIT_PX, text_title);

		during = 14;
	}

	@Click
	void tv_21() {
		tv_7.setTextColor(setting_text_light);
		tv_7.setTextSize(TypedValue.COMPLEX_UNIT_PX, text_title);

		tv_14.setTextColor(setting_text_light);
		tv_14.setTextSize(TypedValue.COMPLEX_UNIT_PX, text_title);

		tv_21.setTextColor(main_text);
		tv_21.setTextSize(TypedValue.COMPLEX_UNIT_PX, selected_days);

		during = 21;
	}

	private void showAlertDialog() {
		new AlertDialog.Builder(this)
				.setMessage("You should tell us what to do")
				.setPositiveButton("OK", null).create().show();
	}
}


相应的布局文件 new_task.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="@color/main_bg"
    android:orientation="vertical"
    android:paddingLeft="10dp"
    android:paddingRight="10dp"
    android:paddingTop="30dp" >

    <TextView
        style="@style/title_text_style"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:text="@string/str_do" />

    <EditText
        android:id="@+id/et_todo"
        android:layout_width="match_parent"
        android:layout_height="36dp"
        android:layout_margin="10dp"
        android:background="@color/main_text"
        android:ellipsize="end"
        android:hint="@string/str_something"
        android:singleLine="true"
        android:textSize="@dimen/text_title" />

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="10dp" >

        <TextView
            style="@style/title_text_style"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_centerVertical="true"
            android:text="@string/str_for" />

        <TextView
            android:id="@+id/tv_14"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:clickable="true"
            android:text="@string/str_14"
            android:textColor="@color/main_text"
            android:textSize="@dimen/selected_days" />

        <TextView
            android:id="@+id/tv_7"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignRight="@+id/tv_14"
            android:layout_centerVertical="true"
            android:layout_marginRight="70dp"
            android:clickable="true"
            android:text="@string/str_7"
            android:textColor="@color/setting_text_light"
            android:textSize="@dimen/text_title" />

        <TextView
            android:id="@+id/tv_21"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignLeft="@+id/tv_14"
            android:layout_centerVertical="true"
            android:layout_marginLeft="55dp"
            android:clickable="true"
            android:text="@string/str_21"
            android:textColor="@color/setting_text_light"
            android:textSize="@dimen/text_title" />

        <TextView
            style="@style/title_text_style"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:layout_centerVertical="true"
            android:text="@string/str_days" />
    </RelativeLayout>

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="10dp" >

        <Button
            android:id="@+id/btn_cancel"
            style="@style/btn_small_style"
            android:layout_width="128dp"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:background="@drawable/white_button"
            android:text="@string/str_cancel" />

        <Button
            android:id="@+id/btn_ok"
            style="@style/btn_small_style"
            android:layout_width="128dp"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:background="@drawable/white_button"
            android:text="@string/str_ok" />
    </RelativeLayout>

</LinearLayout>


部分运行效果图:
     

目前为止源码:
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值