AndroidStdio 关于课程表的小项目

来源:互联网 发布:ezdsdpro软件下载 编辑:程序博客网 时间:2024/06/06 09:57

花了半个月写的一个关于课程表的小项目,而且比较牛逼的地方还没写出来QAQ
巩固了很多基础知识,并且学习了那么一丢丢的实战技巧
我将整个学习并操作的过程总结成下面的步骤:

  1. 课表的数据库结构是什么样的?数据库的范式和内容都要非常详细的罗列出来。
  2. 课程表的每个页面是什么样,每个按钮点击后有什么样的结果。
  3. 开始写代码,最先做的就是构建一个课表数据库,在从数据库的基础上,逐渐完成其他代码。

首先是数据库结构:
|Class | Mon | Tue | Wed | Thu | Fri | Sar | Time | Data
| 1-2 |—————–message—————- |8:00|2017-12-16|
.
.
.
第一行的横坐标为课表的9个属性,第二行一下为每个属性的信息
Class :每天的第几堂课程 1-2 代表1-2 节课,假设每天都有12节课,就是6堂课
Mon–Sar:表示星期几,内容message为 课名&&上课地点&&这周课是单周还是双周还是xx-xx周
Time:表示上课的时间,比如1-2节课上课的时间是 8:00
Data:纵坐标的第一行表示开学日期,第二行表示主题,第三行表示提醒时间

接下来就是每个页面:
开始——->SetTime——>SetDay——–>SetClass
SetTime:开始的界面,可以看到一天每节课的上课时间,开学日期,提醒时间和主题,点击Button可以达到SetDay页面。
SetDay:第n个星期的某一天的上课信息, 每节课要上的课程,包含课程名和上课地点,当点击某节课的时候,表示要设置这节课的信息,跳转到SetClass页面
SetClass:可以设置课名,上课地点和上课的周次,当设置完以后点击Button可以回到SetDay中。
除此之外,还设计一个桌面小插件用来提醒是否上课(因为这是最难的,现在还没完全搞懂,代码和内容等下就不讲了)

先写数据库的代码,编写一个ScheduleDAO 的数据库类继承SQLiteOpenHelper,创建Table Schedule
然后使用execSQL的方法SQL,具有建表、查询、获取上课信息方法、更新,并且插入最原始的数据
关键代码如下:

//建表 public void onCreate(SQLiteDatabase db) {        String sql;        sql="CREATE TABLE IF NOT EXISTS Schedule(Class text," +                "Mon text,Tue text,Wed text,Thu text,Fri text," +                "Sar text,Sun text,Time text,Data text)";        db.execSQL(sql);        insertValue(db);    }//查询 public Cursor getValue(String key,String value){        Cursor c;        db = this.getReadableDatabase();        c=db.query("Schedule",new String[]{"Class","Mon","Tue","Wed","Thu","Fri","Sar","Sun","Time","Data"},                key+"=?",new String[]{value},null,null,null);        return c;    }//更新数据库  public String updateValue(String week,String theclass,String value){        String aaa="";        try{            String sql="UPDATE Schedule set "+week+"='"+value+"'where Class='"+theclass+"'";            db.execSQL(sql);        }catch (Exception e){            aaa=e.getMessage();        }        return aaa;    }

接下来开始写SetTime页面,页面布局如图:
这里写图片描述
当点击每一栏的时候都可以设置该栏,比如时间,开学日期都可以设置
从每节课到主题风格都存放在一个listview中,所以要配置适配器,设置一个Simpleadapter。SetTime类首先要完成数据初始化,即刚进入这个页面的时候上面就已经显示了如图的默认信息,这类代码就是使用数据库将数据库实例化然后取出默认数据。
listview配置balablabla…
接下来就是设置时间,开学日期和提醒时间主题什么的了,这部分没什么难点
先给ListView设置点击事件,再从点击事件获取点击的位置,然后开始写功能
代码如下:

//设置时间 public void setTime(final int position) {             new TimePickerDialog(SetTime.this, new TimePickerDialog.OnTimeSetListener() {                 @Override                 public void onTimeSet(TimePicker view, int hourOfDay, int minute) {                     String tip=TipUtil.getTipWithFormate(position);                     String thetime=STime.getTimeBack(new STime(hourOfDay,minute));  //更改后的上课时间                     //更新显示的信息                     updateListView(new String[]{"tip","time"},new String[]{tip,thetime},position);                     //更新数据库信息                     String theclass=TipUtil.getTheclass(position);                     sd.updateValue("Time",theclass,thetime);                     //更新timelist                     timelist.set(position,thetime);                 }             },STime.getTime(timelist.get(position)).getHour(),STime.getTime(timelist.get(position)).getMinutes(),true).show();        }//设置开学日期 public void setData(final int position) {            new DatePickerDialog(SetTime.this, new DatePickerDialog.OnDateSetListener() {                @Override                public void onDateSet(DatePicker view, int year, int month, int dayOfMonth) {                    String tip = "开学日期";                    //月份要+1                    String thedata = SData.getDataBack(new SData(year, month + 1, dayOfMonth));                    updateListView(new String[]{"tip", "time"}, new String[]{tip, thedata}, position);                    sd.updateValue("Data", "1-2", thedata);                    Data = thedata;                }            },SData.getData(Data).getYear(),SData.getData(Data).getMonth(),SData.getData(Data).getDayOfMonth()).show();        }//设置提醒时间  public void setTiptime(final int position) {            new AlertDialog.Builder(SetTime.this)                    .setTitle("请设置提醒时间")                    .setSingleChoiceItems(new String[]{"5分钟","10分钟","15分钟","20分钟","不提醒"},0,                            new DialogInterface.OnClickListener() {                        @Override                        public void onClick(DialogInterface dialog, int which) {                            String a="";                            switch (which){                                case 0:                                case 1:                                case 2:                                case 3:                                    a=(which+1)*5+"";                                    break;                                case 4:                                    a="不提醒";                                    break;                            }                            updateListView(new String[]{"tip","time"},new String[]{"提醒时间",a},position);                            sd.updateValue("Data","5-6",a);                            dialog.dismiss();                        }                    }).show();        }//设置主题 public void settheme(final int position) {            new AlertDialog.Builder(SetTime.this)                    .setTitle("请设置主题风格")                    .setSingleChoiceItems(new String[]{"阿狸","DOTA"},0,                            new DialogInterface.OnClickListener() {                                @Override                                public void onClick(DialogInterface dialog, int which) {                                    String a="";                                    switch (which){                                        case 0:                                            a="阿狸";                                            break;                                        case 1:                                            a="Dota";                                            break;                                    }                                    updateListView(new String[]{"tip","time"},new String[]{"主题风格",a},position);                                    sd.updateValue("Data","3-4",which+"");                                    dialog.dismiss();                                }                            }).show();        }//更新界面  private void updateListView(String[] strings, String[] strings1, int position) {            //往listview上更新信息使用map对list更新数据            Map<String,Object> map =new HashMap<String,Object>();            for(int i=0;i<strings.length;i++){                map.put(strings[i],strings1[i]);            }            list.set(position,map);            adapter.notifyDataSetChanged(); //list更新后的绑定操作,是对item的强制刷新        }

在SetTime页面中点击“下一步”,来到SetDay界面,注意要在MainFest文件中添加新的有布局文件的类,SetDay页面布局如下:
这里写图片描述
SetDay页面有个功能,就是可以通过左滑和右滑来转到下一天或前一天
主要是实现了接口 OnTouchListener和OnGestureListener
重写onFling和onTouch方法实现左滑右滑实现页面变化如下:

//其中e1.getX()为滑动的前一个点,e2.getX()为后一个点//velocityX()为滑动的速度,单位大概是像素每单位时间,可能为负数所以用的时候要加一个abspublic boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {        //左滑动        if(e1.getX()-e2.getX()>100&&Math.abs(velocityX)>200){            setWeek(week+1);            tiptext.setText(weektip);        }        //右滑动        if(e2.getX()-e1.getX()>100&&Math.abs(velocityX)>200){            setWeek(week-1);            tiptext.setText(weektip);        }        return false;    } public boolean onTouch(View v, MotionEvent event) {        return mGestureDetector.onTouchEvent(event);    }

别的代码就是实现给ListView配置适配器,然后页面本来是什么都没有的,我们要通过点击某节课来设置上课信息,跳转到SetClass页面,从SetClass页面设置完以后回到SetDay页面,这里用到了数据的传送,是android特别常见并且实用的一个方法,下面是一些代码:

 //初始化listview数据    private void getDate(String day) {           list.clear();           ArrayList<String> classlist=new ArrayList<String>();        Cursor c=sd.getWeekValue(day);        while (c.moveToNext()){            classlist.add(c.getString(0));        }        Map<String,Object> map;        SClass classinfo;        for(int i=0;i<6;i++){            map=new HashMap<String,Object>();            classinfo=SClass.getInformation(classlist.get(i));            map.put("tip",TipUtil.getTipWithFormate(i));            map.put("classname",classinfo.getTheclass());            map.put("classplace",classinfo.getTheplace());            list.add(map);        }        classlist.clear();    }    //设置星期public void setWeek(int week) {        this.week = week;        String day="";  //用于使用getdate方法        switch (week){            case 0:                this.week=6;                weektip="星期六";                day="Sar";                break;            case 1:                weektip="星期一";                day="Mon";                break;            case 2:                weektip="星期二";                day="Tue";                break;            case 3:                weektip="星期三";                day="Wed";                break;            case 4:                weektip="星期四";                day="Thu";                break;            case 5:                weektip="星期五";                day="Fri";                break;            case 6:                weektip="星期六";                day="Sar";                break;            case 7:                this.week=1;                weektip="星期一";                day="Mon";                break;        }        getDate(day);        list.clear();        adapter.notifyDataSetChanged();    }    //比较重要的输送数据     class MyListener implements AdapterView.OnItemClickListener{       //点击后进入setclass页面,然后等待回传数据,返回此页面        //因为涉及到回传数据,所以使用bundle函数        @Override        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {            Bundle bundle=new Bundle();            //用户的点击设置,对应着一天中的某节课            bundle.putInt("theclass",position);            theclass=position;            //星期几            bundle.putInt("theweek",week);            Intent intent=new Intent();            intent.setClass(SetDay.this,SetClass.class);            intent.putExtras(bundle);            //等待数据回传            startActivityForResult(intent,0);        }    }/*因为使用数据输送,所以页面切换的时候不使用StartActivity而是使用      startActivityForResult(intent,0); *因为在SetClass使用完后数据回到SetDay的时候会通过startActivityForResult而调用onActivityResult方法,因为回来的时候要把新的数据给显示在页面上,所以要重写onActivityResult方法更新几面*/ protected void  onActivityResult(int requestCode,int resultCode,Intent data){        switch (resultCode){            case 1:                //更新ListView的信息                Bundle bundle=data.getExtras();                String information=bundle.getString("information");                Map<String,Object> map=new HashMap<String,Object>();                String tip=TipUtil.getTipWithFormate(theclass);                map.put("tip",tip);                SClass classInfo=SClass.getInformation(information);                map.put("classname",classInfo.getTheclass());                map.put("classplace",classInfo.getTheplace());                list.set(theclass,map);                adapter.notifyDataSetChanged();        }    }

SetClass布局文件如图所示:
这里写图片描述
点击课名、地点会出现一个dialog写信息到Textview中去,周次可以选择单周,双周,每周和自定义xx-xx周
在配置完listview后,点击事件如下:

//编辑课名  private void showClassNameDialog(final int position) {        final EditText esitText=new EditText(SetClass.this);        new AlertDialog.Builder(SetClass.this).setTitle("设置课程名字")                .setIcon(R.drawable.ic_launcher_background)                .setView(esitText)                .setPositiveButton("确定", new DialogInterface.OnClickListener() {                    @Override                    public void onClick(DialogInterface dialog, int which) {                        className=" "+esitText.getText().toString();                        updateListView(new String[]{"tip1","editcontent"},new String[]{"课名",className},position);                    }                }).setNegativeButton("取消",null)                .show();    }//编辑地名private void showClassPlaceDialog(final int position) {        final EditText esitText=new EditText(SetClass.this);        new AlertDialog.Builder(SetClass.this).setTitle("设置上课地点")                .setIcon(R.drawable.ic_launcher_background)                .setView(esitText)                .setPositiveButton("确定", new DialogInterface.OnClickListener() {                    @Override                    public void onClick(DialogInterface dialog, int which) {                     classPlace=" "+esitText.getText().toString();                        updateListView(new String[]{"tip1","editcontent"},new String[]{"地点",classPlace},position);                    }                }).setNegativeButton("取消",null)                .show();    }//编辑周次,略长,= =主要是自定义要写很多  private void showWeekPickerDialog(final int position) {        new AlertDialog.Builder(SetClass.this)                .setTitle("请选择周次")                .setSingleChoiceItems(new String[]{"单周","双周","全部","自定义"}, 0,                        new DialogInterface.OnClickListener() {                            @Override                            public void onClick(DialogInterface dialogInterface, int i) {                                String value="";                                switch (i){                                    case 0:                                        value =" 单周";                                        weekTime=1;                                        break;                                    case 1:                                        value =" 双周";                                        weekTime=2;                                        break;                                    case 2:                                        value =" 全部";                                        weekTime=0;                                        break;                                    case 3:                                        //选择开始周次和结束周次                                        showWeekDetailPickerDialog(i);                                        break;                                }                                updateListView(new String[]{"tip1","editcontent"},new String[]{"周次",value},position);                                dialogInterface.dismiss();                            }                            //使用hashset来存放已经选择的周次                            private void showWeekDetailPickerDialog(int i) {                                final HashSet<Integer> choice=new HashSet<Integer>();                                final String[] values={"1","2","3","4","5","6","7","8","9","10","11","12","13","14","15"                                        ,"16","17","18","19","20","21","22","23","24","25"};                                new AlertDialog.Builder(SetClass.this)                                        .setTitle("请选择开始周次和结束周次")                                        .setMultiChoiceItems(values, null, new DialogInterface.OnMultiChoiceClickListener() {                                            @Override                                            public void onClick(DialogInterface dialogInterface, int i, boolean b) {                                                if(b){                                                    choice.add(i+1);                                                }                                                else choice.remove(i+1);                                            }                                        })                                        .setPositiveButton("确定", new DialogInterface.OnClickListener() {                                            @Override                                            public void onClick(DialogInterface dialogInterface, int i) {                                                if(choice.size()==2){                                                    //选中两个                                                    Object object[]=choice.toArray();                                                    String value=Math.min((Integer)object[0],(Integer)object[1])                                                            +"-"+Math.max((Integer)object[0],(Integer)object[1]);                                                    updateListView(new String[]{"tip1","editcontent"},new String[]{"周次",value},position);                                                    weekTime=Math.min((Integer)object[0],(Integer)object[1])*1000                                                            +Math.max((Integer)object[0],(Integer)object[1]);                                                    dialogInterface.dismiss();                                                }                                                else {                                                    new AlertDialog.Builder(SetClass.this)                                                            .setTitle("注意")                                                            .setMessage("请选择两个选项")                                                            .setPositiveButton("确定",null)                                                            .show();                                                }                                                choice.clear();                                            }                                        })                                        .setNegativeButton("取消",null).show();                            }                        })                .setPositiveButton("确定",null)                .setNegativeButton("取消",null)                .show();    }//更新列表视图    private void updateListView(String[] strings, String[] strings1, int position) {        Map<String,Object>map=new HashMap<String,Object>();        for(int i=0;i<strings.length;i++){            map.put(strings[i],strings1[i]);        }        list.set(position,map);        adapter.notifyDataSetChanged();    }//点击事件回传数据class MyButtonListener implements Button.OnClickListener {        @Override        public void onClick(View v) {            int i=v.getId();            switch (i){                //回传数据                case R.id.donebutton:                    String message=SClass.getInformationBack(new SClass(className,classPlace,weekTime));                   sd.updateValue(theweek,theclass,message);                    Toast.makeText(SetClass.this,message,Toast.LENGTH_SHORT).show();                    Intent intent=SetClass.this.getIntent();                    intent.putExtra("information",message);                    SetClass.this.setResult(1,intent);                    intent.setClass(SetClass.this,SetDay.class);                    SetClass.this.finish();                    break;                case R.id.cancelbutton:                    SetClass.this.finish();                    break;            }        }    }

至此,基本功能已经实现,代码只放了部分比较关键的代码,其他很多代码都是比较基本的或者工具类(快捷的提取信息),后面的桌面小插件,关于Broadcast、Service那些写的我想死QAQ,所以过个月再去研究。
这几个页面比较难的地方我认为:
一个是要写很多转化,类型的转化,内容的转化,所以要多写几个工具类出来,我就写SClass,TipUtil,STime等工具类来帮助代码更加便捷;
二是代码特别冗长,建议边写边调试,我一开始试水的时候无脑写代码,然后程序怎么都是Stopped,所以就又写了一次;
三是关于SetDay和SetClass的数据传输,我在总结一下
关于Received方和End方的
End(SetDay):

            Bundle bundle=new Bundle();            bundle.putInt("theweek",week);            Intent intent=new Intent();            intent.setClass(SetDay.this,SetClass.class);            intent.putExtras(bundle);            //等待数据回传            startActivityForResult(intent,0);

使用bundle插入关键数据,intent的putExtras(Bundle)方法实现将数据送过去
startActivityForResult()方法用来代替startActivity
Received(SetClass):

//接收数据 Intent intent = this.getIntent(); Bundle bundle = intent.getExtras();//送回新数据String message=SClass.getInformationBack(new         SClass(className,classPlace,weekTime));                   sd.updateValue(theweek,theclass,message);                    Intent intent=SetClass.this.getIntent();                    intent.putExtra("information",message);                    SetClass.this.setResult(1,intent);                    intent.setClass(SetClass.this,SetDay.class);                    SetClass.this.finish();

接收数据后SetClass就能使用从SetDay中得到的Bundle的关键数据了
然后返回数据使用intent的putExtra和setResult方法,回去的时候可以重写onActivityResult方法来更新下界面。

最后一个是每一个步骤都有一个更新页面的方法,不要嫌烦的每次都要写一下!


emmm课程表学到了一下小东西,但其实能拿到实战去的东西微乎其微,只能自娱自乐一下,而且最NB的地方我也没研究头侧,所以就下次加油争取早日研究完关于Servier的东西。

写到最后只想说一句:我透!算法的东西根本就拿不出来呀!