AndroidStdio 关于课程表的小项目

花了半个月写的一个关于课程表的小项目,而且比较牛逼的地方还没写出来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页面,页面布局如图:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FdNXJjom-1587976582893)(https://img-blog.csdn.net/20171216201119672?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcmlra2F0aGV3b3JsZA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)]
当点击每一栏的时候都可以设置该栏,比如时间,开学日期都可以设置
从每节课到主题风格都存放在一个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页面布局如下:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uqpozQZ6-1587976582895)(https://img-blog.csdn.net/20171216204159286?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcmlra2F0aGV3b3JsZA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)]
SetDay页面有个功能,就是可以通过左滑和右滑来转到下一天或前一天
主要是实现了接口 OnTouchListener和OnGestureListener
重写onFling和onTouch方法实现左滑右滑实现页面变化如下:

//其中e1.getX()为滑动的前一个点,e2.getX()为后一个点
//velocityX()为滑动的速度,单位大概是像素每单位时间,可能为负数所以用的时候要加一个abs
public 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布局文件如图所示:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CVWRLUSo-1587976582898)(https://img-blog.csdn.net/20171216205713378?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcmlra2F0aGV3b3JsZA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)]
点击课名、地点会出现一个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的东西。

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

  • 2
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值