Android版DailyInsist(四)——业务逻辑和数据操作RecordFragment

本文介绍了在Android应用DailyInsist的RecordFragment中,如何处理新建任务、每日签到和删除任务的业务逻辑。通过实现ITaskFinder接口,使用SQLite数据库存储和获取任务数据,并创建TaskItemAdapter来展示任务列表。在TaskItemView中,实现了任务详情的显示和删除操作的对话框。当任务被删除时,会发送广播更新RecordFragment的数据和界面。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

统计界面RecordFragment中的业务逻辑涉及到三个方面:新建任务,每日签到和删除任务。有上面三个中的任何一个操作时,统计界面都要做出相应的更新。其中删除操作在统计界面中进行。
这里参考了文章中实现自定义ListView的形式。

TaskBean类在上一篇文章中已经介绍过了,下面定义一个接口 ITaskFinder
public interface ITaskFinder {
     List<TaskBean> findAllTask();
}

接口中只有一个方法 findAllTask,获取所有任务的列表。
接口实现类 ITaskFinderImpl如下:
@EBean
public 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接口的实现类获取任务列表,然后绑定数据,创建相应视图:
@EBean
public 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了,实现了具体的功能:
@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天,运行效果图:
 
目前为止源码:
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值