日程的增删改查
来源:互联网 发布:samba端口号作用 编辑:程序博客网 时间:2024/05/16 03:24
一些改动
首先,为了方便按条件查询时日期时间的比较,我们在Schedule类以及数据库表中加入了一个long类型的变量与字段,用于保存日期时间,同时也在本地数据库的工具类中做了相应的更改
由于用户的UID传递较麻烦,所以这里新建了一个类继承自Application,添加了一个名为user_id的成员变量,并添加了get set方法
添加日程功能
上次做好了本地数据库的工具类,所以添加功能是比较简单的,只需要
获取信息->判断信息合法性->封装至对象->保存至本地数据库->保存至firebase数据库
首先设计UI
这个UI也是比较简单,把所有需要的信息放上去就OK了,就只有日期时间特别点,需要用按钮来触发选择器,默认为当前时间,拖放控件,修改ID,在string.xml中加入资源文本,修改按钮的OnClick事件,做好后如图
初始化日期时间选择器部分
由于时间选择器和日期选择器差不多,所以这里只展示选择日期的部分
在窗口类中添加几个成员变量-日期选择器,侦听器,保存选择了的日期时间的int变量以及一个用于存储选择的日期时间的Calendar类对象
private DatePickerDialog dateDlg; private DatePickerDialog.OnDateSetListener dateLis; private int mYear,mMonth,mDay; private int mHour,mMin; private Calendar mCal=Calendar.getInstance();
再定义一个当日期选择了时触发的用于更新UI的函数()
private void OnDateChose(){ tv_date.setText(mYear+"-"+mMonth+"-"+mDay); }
然后在自己定义的init函数中初始化这些对象
dateLis=new DatePickerDialog.OnDateSetListener() { @Override public void onDateSet(DatePicker view, int year, int month, int dayOfMonth) { mYear=year; mMonth=month; mDay=dayOfMonth; mCal.set(Calendar.YEAR,mYear); mCal.set(Calendar.MONTH,mMonth); mCal.set(Calendar.DAY_OF_MONTH,mDay); mMonth++; OnDateChose(); } }; mYear = mCal.get(Calendar.YEAR); mMonth = mCal.get(Calendar.MONTH); mDay = mCal.get(Calendar.DAY_OF_MONTH); mHour= mCal.get(Calendar.HOUR_OF_DAY); mMin= mCal.get(Calendar.MINUTE); dateDlg=new DatePickerDialog(this,dateLis,mYear,mMonth,mDay); ... OnDateChose();
由于保存的日期月份与选择的月份相差1,且mCal变量中以及保存了选择好的日期,所以这里为了显示时正常将mMonth变量值加一
初始化完成后调用一次更新UI用的函数以显示初始值
然后编写选择日期按钮的OnClick函数
public void date(View v){ dateDlg.show(); }
接着编新建日程按钮的OnClick响应函数
public void insert(View v){ String id= RandomUtils.getRandomId(); String date=mYear+"-"+(mMonth+1)+"-"+mDay; String time=mHour+":"+mMin; String who=et_who.getText().toString(); String more=et_more.getText().toString(); int level=sp_level.getSelectedItemPosition(); if(who.equals("") || more.equals("")){ UIUtils.makeToast("不能留空",this); } Schedule schedule=new Schedule(id,date,time,who,more,null,level,mCal.getTimeInMillis()); ScheduleDbUtils db=new ScheduleDbUtils(this,null); db.insert(schedule); cloud(schedule); }
最后编写函数cloud用于将数据备份至firebase数据库
public void cloud(Schedule schedule){ final AlertDialog dlg=UIUtils.createDialog(getString(R.string.insert_cloud_handling),this); String uid=((GreenAppApplication)getApplication()).getUid(); FirebaseDatabase db=FirebaseDatabase.getInstance(); db.getReference().child("schedules").child(uid).child(schedule.getId()).setValue(schedule).addOnCompleteListener(new OnCompleteListener<Void>() { @Override public void onComplete(@NonNull Task<Void> task) { dlg.dismiss(); if(task.isSuccessful()){ UIUtils.makeToast(getString(R.string.insert_succeed),InsertScheduleActivity.this); }else{ UIUtils.makeToast(getString(R.string.insert_failed),InsertScheduleActivity.this); } InsertScheduleActivity.this.finish(); } }); }
编写查询功能
查询主要有两种方式,一种是查询全部,一种是按条件查询
改动工具类
原来的本地数据库工具类的查询功能以及不能满足需求了,需要再定义一个接受whereClause与whereArgs的查询函数并让接受id的查询函数调用那个函数
public List<Schedule> select(String id) { if(id==null){ return select(null,null); }else{ String whereClause = "s_id=?"; String[] whereArgs = {id}; return select(whereClause,whereArgs); } } public List<Schedule> select(String whereClause,String[] whereArgs) { SQLiteDatabase db = getReadableDatabase(); List<Schedule> result = new ArrayList<>(); Cursor cursor = db.query(TABLE_NAME, null, whereClause, whereArgs, null, null, null); if (cursor.moveToFirst()) { for (int i = 0; i < cursor.getCount(); i++) { cursor.move(i); String id=cursor.getString(0); String date=cursor.getString(1); String time=cursor.getString(2); String who=cursor.getString(3); int level=cursor.getInt(4); String more=cursor.getString(5); long t=cursor.getLong(6); Schedule schedule=new Schedule(id,date,time,who,more,null,level,t); result.add(schedule); } } return result; }
设计UI与实现功能
这里会出现四个Activity(今后可能会用对话框代替部分)
分别是充当菜单作用的SelectSchedulesActivity,
用户输入查询条件的SelectSchedulesConditionActivity,
显示查询结果的SelectSchedulesResultActivity,
用于显示日程详细信息并提供更改与删除操作的SelectSchedulesResultMoreActivity
SelectSchedulesActivity:
由于这只是充当菜单作用,所以UI相对简单
下面两个按钮只是用于跳转至其他Activity,重点是恢复与备份功能(以后可能会移到别处或自动处理)
这里把两个功能分开来做
备份将本地数据同步到云端,就需要获取本地的所有日程,然后挨个上传至服务器(以后可能会加入一个字段来保存日程内容的MD5,如果MD5且ID相同的日程就跳过以减少服务器与客户端的负担)
public void cloud(View v){ str_id=R.string.select_cloud_succeed; List<Schedule> schedules=db.select(null); if(schedules==null || schedules.size()==0){ UIUtils.makeToast(getString(str_id),SelectSchedulesActivity.this); return; } FirebaseDatabase fdb=FirebaseDatabase.getInstance(); final AlertDialog dlg=UIUtils.createDialog(getString(R.string.select_cloud_handling),this); for(final Schedule schedule:schedules){ DatabaseReference ref=fdb.getReference().child("schedules").child(uid).child(schedule.getId()); ref.setValue(schedule).addOnFailureListener(new OnFailureListener() { @Override public void onFailure(@NonNull Exception e) { str_id=R.string.select_cloud_failed; } }); } dlg.dismiss(); UIUtils.makeToast(getString(str_id),SelectSchedulesActivity.this); }
恢复功能就是将服务器上的弄到本地数据库里面去
但由于本地数据库并不能覆盖同ID的数据
所以先判断是否存在同ID的,不存在就添加,存在就修改
public void download(View v){ str_id=R.string.select_download_succeed; FirebaseDatabase fdb=FirebaseDatabase.getInstance(); final AlertDialog dlg=UIUtils.createDialog(getString(R.string.select_download_handling),this); final DatabaseReference ref=fdb.getReference().child("schedules").child(uid); ref.addListenerForSingleValueEvent(new ValueEventListener() { @Override public void onDataChange(DataSnapshot dataSnapshot) { if(dataSnapshot.getChildrenCount()==0){ str_id=R.string.select_download_succeed; } Iterable<DataSnapshot> children=dataSnapshot.getChildren(); for(DataSnapshot child:children){ String id=child.child("id").getValue(String.class); List<Schedule> result=db.select(id); if(result!=null && result.size()!=0){ db.update(child.getValue(Schedule.class),id); continue; } db.insert(child.getValue(Schedule.class)); } } @Override public void onCancelled(DatabaseError databaseError) { str_id=R.string.select_download_failed; return; } }); dlg.dismiss(); UIUtils.makeToast(getString(str_id),SelectSchedulesActivity.this); }
SelectSchedulesConditionActivity:
按条件查询就要考虑输入的空白数据,因为用户要使用这种查询是因为用户并不知晓所需日程的全部内容,所以这里有两种解决方案,一种是判断所输入的是否为空,如果为空那么就让该字段为任意值都可以查询到,即忽略该字段,还有一种是使用户并不用做出任何操作就可以查询到所有,这里显然是后者更方便,由于数据库中保存了日期时间化为long类型后的数据,所以用大于小于运算符就可以做出比较,文本类信息就用LIKE关键字,在所输入的数据的前后加入通配符’%’
这里的默认日期时间就是当时,默认查找当前时间之后的
等级默认是最低的那个,然后条件是大于等于,即任何日程都符合
其他的文本信息默认为空,即任何文本都可以匹配成功
UI也以选择性的控件为主,以引导用户查找
日期时间选择器前面以及介绍过了,重点在于查找部分
public void select(View v){ int time_con=sp_date_time_condition.getSelectedItemPosition(); int level_con=sp_level_condition.getSelectedItemPosition(); int level=sp_level.getSelectedItemPosition(); long time=mCal.getTimeInMillis(); String who=et_who.getText().toString(); String more=et_more.getText().toString(); String operatorTime[]={"<","=",">"}; String operatorLevel[]={">","=","<",">=","<="}; who="%"+who+"%"; more="%"+more+"%"; String whereClause="s_time_long "+operatorTime[time_con]+" ? and s_level"+operatorLevel[level_con]+" ? and s_who like ? and s_more like ?"; String whereArgs[]={String.valueOf(time),String.valueOf(level),who,more}; ScheduleDbUtils db=new ScheduleDbUtils(this,null); List<Schedule> schedules=db.select(whereClause,whereArgs); Intent intent=new Intent(this,SelectSchedulesResultActivity.class); intent.putExtra("schedules", (Serializable) schedules); startActivity(intent); }
这样就可以查找出符合条件的日程了
SelectSchedulesResultActivity:
这里的控件也就只有个ListView,用于展示查询结果
这里需要一个适配器
新建一个类MyAdapter继承自BaseAdapter,添加构造函数获取必须的数据
class MyAdapter extends BaseAdapter{ private List<Schedule> schedules; private boolean isListNull=false; private Context context; public MyAdapter(List<Schedule> schedules,boolean isListNull,Context context){ this.schedules=schedules; this.isListNull=isListNull; this.context=context; } ...
这里在res目录下新建一个view
这里只需改动一下getCount函数以及getView函数
@Override public int getCount() { if(isListNull){ return 1; } return schedules.size(); } ... @Override public View getView(int position, View convertView, ViewGroup parent) { if(isListNull){ LinearLayout layout=new LinearLayout(context); TextView tv=new TextView(context); tv.setText("没有数据"); layout.addView(tv); return layout; } View view=View.inflate(context,R.layout.view_select_result,null); TextView tv_date,tv_time,tv_who,tv_level,tv_more; tv_date= (TextView) view.findViewById(R.id.select_result_tv_date); tv_time= (TextView) view.findViewById(R.id.select_result_tv_time); tv_who= (TextView) view.findViewById(R.id.select_result_tv_who); tv_level= (TextView) view.findViewById(R.id.select_result_tv_level); tv_more= (TextView) view.findViewById(R.id.select_result_tv_more); Schedule schedule=schedules.get(position); String date=schedule.getDate(); String time=schedule.getTime(); String who=schedule.getWho(); String level= schedule.levelToString(context); String more=schedule.getMore(); tv_date.setText(context.getString(R.string.select_result_date)+date); tv_time.setText(context.getString(R.string.select_result_time)+time); tv_who.setText(context.getString(R.string.select_result_who)+who); tv_level.setText(context.getString(R.string.select_result_level)+level); tv_more.setText(context.getString(R.string.select_result_more)+more); return view; }
这里还需要为这个ListView做一个项目点击侦听器
class MyClickListener implements AdapterView.OnItemClickListener{ private Context context; private List<Schedule> schedules; public MyClickListener(Context context,List<Schedule> schedules){ this.context=context; this.schedules=schedules; } @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { if(schedules.size()==0) return; Schedule schedule=schedules.get(position); Intent intent=new Intent(context,SelectSchedulesResultMoreActivity.class); intent.putExtra("schedule",schedule); intent.putExtra("pos",position); context.startActivity(intent); }}
由于More窗口处理完成后需要告知Result窗口,所以这里再定义一个个广播接收者
private BroadcastReceiver receiver=new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { int what=intent.getIntExtra("what",0); int pos=intent.getIntExtra("pos",0); switch(what){ case 0://Delete schedules.remove(pos); break; case 1://Update Schedule schedule= (Schedule) intent.getSerializableExtra("schedule"); schedules.set(pos,schedule); break; } lv_result.setAdapter(new MyAdapter(schedules,(schedules.size()==0)?true:false,context)); } };
最后在init函数中设置它们
public void init(){ lv_result= (ListView) findViewById(R.id.select_result_lv_result); schedules= (List<Schedule>) getIntent().getSerializableExtra("schedules"); boolean isListNull=false; if(schedules==null || schedules.size()==0){ isListNull=true; }else{ lv_result.setOnItemClickListener(new MyClickListener(this,schedules)); } adapter=new MyAdapter(schedules,isListNull,this); }
在onCreate函数中注册广播接受者
IntentFilter filter = new IntentFilter(); filter.addAction("com.greenapp.note.SCHEDULE_CHANGE"); registerReceiver(receiver,filter);
SelectSchedulesResultMoreActivity:
这个UI和insert的差不多
功能的实现也和insert类似,获取信息,然后本地数据库的update,再设置firebase数据库中的值,就ok了,删除只需删除本地数据库里的值,然后将firebase数据库里的值设置为null就ok了
db.getReference().child("schedules").child(uid).child(schedule.getId()).setValue(null)//删除
- 日程的增删改查
- Android 日历管理 Calendars的(日程、提醒)增删改查
- datagridview的增删改查
- jdbc的增删改查
- GridView 的增删改查
- 联系人的增删查改
- 数据库的增删改查
- Linq的增删改查
- Hibernate的增删改查
- 网页的增删改查
- struts2的增删改查
- XML的增删改查
- Hibernate的增删改查
- json的增删改查
- thinkphp的增删改查
- SQLite的增删改查
- sql的增删改查
- Hibernate的增删查改
- 模拟实现ES5中原生的bind函数
- 1024 Calendar Game
- Android:判断手机运营商
- web.xml中的url-pattern标签/和/*有什么区别
- custom python matlabplot
- 日程的增删改查
- 建站也有认证了?你会去考吗
- HDU-2680 Choose the best route
- Spring 事件机制
- 8.10实战感悟
- VC DLL转换C++builder Lib
- 《大话数据结构》 第七章 图
- 红黑树笔记
- Java实现简单的网络爬虫(一)