Android版DailyInsist(四)——业务逻辑和数据操作RecordFragment
来源:互联网 发布:java管理系统实战 编辑:程序博客网 时间:2024/09/21 08:16
统计界面RecordFragment中的业务逻辑涉及到三个方面:新建任务,每日签到和删除任务。有上面三个中的任何一个操作时,统计界面都要做出相应的更新。其中删除操作在统计界面中进行。
这里参考了文章中实现自定义ListView的形式。
TaskBean类在上一篇文章中已经介绍过了,下面定义一个接口ITaskFinder:
public interface ITaskFinder { List<TaskBean> findAllTask();}
接口中只有一个方法findAllTask,获取所有任务的列表。
接口实现类ITaskFinderImpl如下:
@EBeanpublic class ITaskFinderImpl implements ITaskFinder { @RootContext Context context; private MyDatabaseHelper dbHelper = null; @Override public List<TaskBean> findAllTask() { if ( dbHelper == null) { dbHelper = new MyDatabaseHelper( context, "di.db3", 1); } return DailyInsistDao. getTasks(dbHelper, 0, -1); }}
因为RecordFragment要列出所有的任务并统计它们的信息,所以我们需要一个TaskItemAdapter来绑定数据到视图上,TaskItemView是列表项的视图,如下:
@EViewGroup(R.layout.task_item )public class TaskItemView extends LinearLayout { @ViewById TextView tv_rate, tv_item_title, tv_start_to_end; @ViewById LinearLayout ll_rec_rate, ll_main; @StringRes String rate; @DrawableRes Drawable orange_rec, blue_rec, gray_rec, btn_up, btn_down; @ViewById Button btn_toggle; /* * set toggle button to control show or hide delete part */ @ViewById RelativeLayout rl_del; /* * for delete */ private int taskId; public TaskItemView(Context context) { super(context); } public void bind(TaskBean task) { taskId = task.getTaskId(); /* * show rate view */ tv_rate.setText(String. format(rate, task.getCompleted(), task.getDuring())); /* * show title view */ tv_item_title.setText(task.getContent()); /* * show rectangle rate */ ll_rec_rate.removeAllViews(); /* * the task is finished */ if (task.getCompleted() == task.getDuring()) { for ( int i = 0, count = task.getDuring(); i < count; i++) { ll_rec_rate.addView(getRegBackgroundByDrawable( ll_rec_rate, orange_rec)); } } else { /* * if the task is not finished, completed parts use blue rectangle * and rest use gray one */ for ( int i = 0, count = task.getCompleted(); i < count; i++) { ll_rec_rate.addView(getRegBackgroundByDrawable( ll_rec_rate, blue_rec)); } for ( int i = 0, count = task.getDuring() - task.getCompleted(); i < count; i++) { ll_rec_rate.addView(getRegBackgroundByDrawable( ll_rec_rate, gray_rec)); } } /* * set start to end date view */ tv_start_to_end .setText(task.getStartDate() + " - " + task.getEndDate()); } @SuppressWarnings("deprecation") private TextView getRegBackgroundByDrawable(LinearLayout ll_rec_rate, Drawable rec) { /* * set width, height, background and layout */ TextView tv_rec = new TextView(getContext()); tv_rec.setWidth(Util. dip2px(getContext(), 7)); tv_rec.setHeight(Util. dip2px(getContext(), 7)); tv_rec. setBackgroundDrawable(rec); LayoutParams lp = new LayoutParams(LayoutParams.WRAP_CONTENT , LayoutParams. WRAP_CONTENT); lp.setMargins(0, 0, Util. dip2px(getContext(), 5), 0); tv_rec.setLayoutParams(lp); return tv_rec; } @Click protected void btn_del() { new AlertDialog.Builder(getContext()) .setMessage( "Sure to DELETE?") .setNegativeButton( "Cancel", null) .setPositiveButton( "DELETE", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { deleteTask(); } }).create().show(); } @SuppressWarnings("deprecation") @Click void ll_main() { if ( rl_del.getVisibility() == View. GONE) { rl_del.setVisibility(View. VISIBLE); btn_toggle. setBackgroundDrawable(btn_up); } else { rl_del.setVisibility(View. GONE); btn_toggle. setBackgroundDrawable(btn_down); } } protected void deleteTask() { DailyInsistDao. deleteTask(new MyDatabaseHelper(getContext(), "di.db3" , 1), taskId); getContext().sendBroadcast( new Intent(Actions.ACTION_UPDATE_INFO )); }}
删除任务后将发广播通知RecordFragment界面更新数据和界面。
列表项的布局task_item.xml如下:
<?xml version="1.0" encoding= "utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/ll_main" android:layout_width= "match_parent" android:layout_height= "wrap_content" android:background="@android:color/white" android:clickable="true" android:orientation="vertical" > <RelativeLayout android:layout_width= "match_parent" android:layout_height= "wrap_content" android:layout_marginBottom="10dp" > <TextView android:id= "@+id/tv_rate" android:layout_width= "wrap_content" android:layout_height= "wrap_content" android:layout_marginLeft= "30dp" android:layout_marginTop= "10dp" android:text= "@string/rate" android:textColor= "@color/record_title_text_dark" android:textSize= "@dimen/text_title" /> <TextView android:id= "@+id/tv_item_title" android:layout_width= "wrap_content" android:layout_height= "wrap_content" android:layout_alignBaseline="@+id/tv_rate" android:layout_alignBottom= "@+id/tv_rate" android:layout_marginLeft= "16dp" android:layout_toRightOf= "@+id/tv_rate" android:text= "@string/str_title" android:textColor= "@color/record_title_text_dark" android:textSize= "@dimen/text_subtitle" /> <Button android:id= "@+id/btn_toggle" android:layout_width= "25dp" android:layout_height= "25dp" android:layout_alignParentRight="true" android:layout_centerVertical="true" android:layout_marginRight= "25dp" android:background= "@drawable/btn_down" /> <LinearLayout android:id= "@+id/ll_rec_rate" android:layout_width= "wrap_content" android:layout_height= "wrap_content" android:layout_below= "@+id/tv_rate" android:layout_marginLeft= "30dp" android:layout_marginTop= "7dp" > <!-- <TextView --> <!-- android:layout_width="7dp" --> <!-- android:layout_height="7dp" --> <!-- android:layout_marginRight="5dp" --> <!-- android:background="@drawable/gray_rec" /> --> </LinearLayout > </RelativeLayout > <RelativeLayout android:id= "@+id/rl_del" android:layout_width= "match_parent" android:layout_height= "wrap_content" android:layout_marginBottom="10dp" android:visibility= "gone" > <TextView android:id= "@+id/tv_start_to_end" android:layout_width= "wrap_content" android:layout_height= "wrap_content" android:layout_alignParentLeft="true" android:layout_centerVertical="true" android:layout_marginLeft= "30dp" android:text= "@string/str_something" android:textColor= "@color/record_title_text_dark" android:textSize= "@dimen/text_subtitle" /> <Button android:id= "@+id/btn_del" style= "@style/btn_del_style" android:layout_width= "81dp" android:layout_height= "37dp" android:layout_alignParentRight="true" android:layout_centerVertical="true" android:layout_marginRight= "30dp" android:background= "@drawable/orange_del_button" android:text= "@string/str_delete" /> </RelativeLayout ></LinearLayout>
TaskItemAdapter适配器直接操作ITaskFinder接口的实现类获取任务列表,然后绑定数据,创建相应视图:
@EBeanpublic class TaskItemAdapter extends BaseAdapter { @RootContext Context context; @Bean(ITaskFinderImpl. class) ITaskFinder iTaskFinder; private List<TaskBean> taskList; @AfterInject void initAdapter() { taskList = iTaskFinder.findAllTask(); } /** * * @Method: getView * @Description: The adapter directly manipulates task list to bind its data * and create the corresponding views * @param pos * @param convertView * @param parent * @return * @see android.widget.Adapter#getView(int, android.view.View, * android.view.ViewGroup) */ @Override public View getView( int pos, View convertView, ViewGroup parent) { TaskItemView taskItemView; if (convertView == null) { taskItemView = TaskItemView_. build(context); } else { taskItemView = (TaskItemView) convertView; } taskItemView.bind(getItem(pos)); return taskItemView; } @Override public int getCount() { return taskList.size(); } @Override public TaskBean getItem( int pos) { return taskList.get(pos); } @Override public long getItemId( int pos) { return pos; } /** * * @Method: resetTaskList * @Description: reset the task list to update the listview * @param @param taskList * @return void * @throws */ public void resetTaskList(List<TaskBean> taskList) { this. taskList.clear(); this. taskList.addAll(taskList); this.notifyDataSetChanged(); }}使用这种方法的话就不需要View Holder 模式了
resetTaskList方法用来重置数据后刷新界面。
最后就是RecordFragment了,实现了具体的功能:
使用了一个全局的SharePreference,由changed变量保存数据改变状态(使用AndroidAnnotation):
@EFragment(R.layout.frag_record )public class RecordFragment extends BaseFragment { private MyDatabaseHelper dbHelper = null; @ViewById TextView tv_rounds, tv_completed_tasks, tv_days; @ViewById ListView lv_task_list; @Bean TaskItemAdapter adapter; @AfterViews void initAdapter() { if ( dbHelper == null) { dbHelper = new MyDatabaseHelper(this.getActivity(), "di.db3" , 1); } lv_task_list.setAdapter( adapter); updateInfo(); registerUpdateInfoReceiver(); } @Override public void show() { initView(); } @Pref GlobalPrefBean_ globalPrefBean; void initView () { boolean changed = globalPrefBean.changed().get(); if (changed) { /* * update Fragment */ updateInfo(); } } private void updateInfo() { /* * get data from local database */ List<TaskBean> taskList = DailyInsistDao.getTasks(dbHelper, 0, -1); /* * update UI */ tv_rounds.setText(taskList.size() + ""); int completedTasks = 0, completedDays = 0; for (TaskBean task : taskList) { if (task.getCompleted() == task.getDuring()) { completedTasks++; } completedDays += task.getCompleted(); } tv_completed_tasks.setText(completedTasks + ""); tv_days.setText(completedDays + ""); /* * reset adapter */ adapter.resetTaskList(taskList); } /** * * @ClassName UpdateInfoReceiver * @Description when delete a task, this broadcast receiver will receive it * @author kiyonlin@163. com * @date 2014- 1- 17 下午2:31:02 */ public class UpdateInfoReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { if (intent == null) { return; } if (com.kiyonlin.utils.Actions.ACTION_UPDATE_INFO .equals(intent .getAction())) { updateInfo(); } } } protected UpdateInfoReceiver updateInfoReceiver; protected void registerUpdateInfoReceiver() { if ( updateInfoReceiver == null) { updateInfoReceiver = new UpdateInfoReceiver(); } IntentFilter filter = new IntentFilter(Actions.ACTION_UPDATE_INFO ); getActivity().registerReceiver( updateInfoReceiver, filter); } @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(); }}
使用了一个全局的SharePreference,由changed变量保存数据改变状态(使用AndroidAnnotation):
@SharedPref(value = SharedPref .Scope.UNIQUE)public interface GlobalPrefBean { boolean changed();}
MainFragment和NewTaskActivity中也作了相应的改变,有兴趣请查看源码。
为了方便起见,测试任务持续日期都是1天,运行效果图:
目前为止源码:
百度云
0 0
- Android版DailyInsist(四)——业务逻辑和数据操作RecordFragment
- Android版DailyInsist(三)——业务逻辑和数据操作MainFragment
- Android版DailyInsist(五)——业务逻辑和数据操作SettingFragment & 小结
- Android版DailyInsist(一)——简介
- Android版DailyInsist(二)——滑动界面
- 业务逻辑层的设计(四)——表模块模式简介
- 购物车项目(四)——编写业务逻辑类
- EF5 操作数据库,分离数据操作与业务逻辑
- 【SSH进阶之路】一步步重构MVC实现Struts框架——封装业务逻辑和跳转路径(四)
- ] 【SSH进阶之路】一步步重构MVC实现Struts框架——封装业务逻辑和跳转路径(四)
- 【SSH进阶之路】一步步重构MVC实现Struts框架——封装业务逻辑和跳转路径(四)
- 【SSH进阶之路】一步步重构MVC实现Struts框架——封装业务逻辑和跳转路径(四)
- 【SSH进阶之路】一步步重构MVC实现Struts框架——封装业务逻辑和跳转路径(四)
- ASP.NET2.0数据操作之创建业务逻辑层
- Android---程序锁(2)业务逻辑
- 业务逻辑和算法
- 数据操作——逻辑判断
- Python基础(四)—逻辑行和物理行
- 不锈钢通风柜
- s:if的用法
- git 用法一
- VC多线程篇
- java执行bat命令碰到的阻塞问题
- Android版DailyInsist(四)——业务逻辑和数据操作RecordFragment
- 三层架构入门
- pdo mysql ----centos
- Ubuntu server下“初始化月份字符串出错”的解决
- 网络验证相关资料
- 替换SQL字段中的换行符,回车符
- VC操作文件、注册表
- js prototype 详解
- 图解如何实现SSH无密码远程登陆