Android+leancloud实现火车实时管理系统模型(课设题目,写出来当笔记)

火车实时管理系统模型


 我先把代码和AKP文件链接贴出来

apk文件

代码,解压后用Android studio打开

设计一套火车管理系统,并能合理的调度火车的运行系统,并能提供购票系统,用户邮箱能获得购票信息

 

 

详细功能描述:

 

该火车管理系统包括以下模块:1)火车站信息 2)轨道信息,轨道由各种站点组成,两站点之间只有一条轨道,3)火车信息,或者调度信息如出站信息和进站信息等 4)客户预定火车票,包括火车,时间,出发站点,到达站点,车厢,座位和乘客信息

关键词

火车购票

 



目录

第一部分 设计任务 3

(一) 任务一 3

(二) 任务二 3

(三) 任务三 3

第二部分 功能模块 5

(一) 功能1——登录注册页面 5

(二) 功能2——侧滑菜单栏 10

(三) 功能3——显示列车信息 13

(四) 功能4——在线购票之路线、日期选择 15

(五) 功能5——在线购票之车次选择 19

(六) 功能6——在线购票之座位选择,购票确认 22

(七) 功能7——本地客户端查看购票记录 30

(八) 功能8——个人信息修改 33

(九) 功能9——小组成员及分工查看 36

第三部分 数据库 38

(一) leancloud数据库介绍: 38

(二) 构建用户信息表: 42

(三) 构建购票信息表: 42

第四部分 总结 43

课程设计总结 43


第一部分 设计任务

(一)任务一

用户能注册,登录进行购票操作

 

(二)任务

设计3条火车路线,并提供购票流程

 

(三)任务三

用户购票,并能在客户端查询到购票记录,邮箱能收到通知邮件

 

第二部分 功能模块

(一)功能1——登录注册页面

 

用户首先点击注册,可以注册新用户,如图。用户名和密码均不能为空,邮箱需正确填写格式才能注册成功,注册成功后,用户表会生成一条用户数据:

本部分注册界面代码如下:

package mountain_hua.train;

import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import com.avos.avoscloud.AVException;
import com.avos.avoscloud.AVObject;
import com.avos.avoscloud.AVQuery;
import com.avos.avoscloud.CountCallback;
import com.avos.avoscloud.SaveCallback;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
 * Created by dhs on 2018/5/15.
 */

public class zhuce extends AppCompatActivity {
    private String name,pwd,email;
    private static final String EP="^[a-z0-9]+([._\\\\-]*[a-z0-9])*@([a-z0-9]+[-a-z0-9]*[a-z0-9]+.){1,63}[a-z0-9]+$";//邮箱格式
    private static final String EPP="^[a-zA-Z0-9#_~!$&'()*+,;=:.\"(),:;<>@\\[\\]\\\\]+@[a-zA-Z0-9-]+(\\.[a-zA-Z0-9-]+)*$";
    private Pattern pa=Pattern.compile(EPP);
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.zhuce);
        //注册按钮
        Button b2=(Button)findViewById(R.id.button5);
        b2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                EditText ed4=(EditText)findViewById(R.id.editText4);
                name=ed4.getText().toString();
                pwd=((EditText)findViewById(R.id.editText5)).getText().toString();
                email=((EditText)findViewById(R.id.editText)).getText().toString();
                zhuce();

            }
        });
    }
    //保存信息
    void baocun(){
        if(youxiang(email)) {
            AVObject inf = new AVObject("user_info");
            inf.put("name", name);
            inf.put("pwd", pwd);
            inf.put("email", email);
            inf.saveInBackground(new SaveCallback() {
                @Override
                public void done(AVException e) {
                    if (e == null) {
                        Toast.makeText(zhuce.this, "注册成功,即将返回登录页面", Toast.LENGTH_SHORT).show();
                        finish();
                    } else {
                        Toast.makeText(zhuce.this, "注册失败,请检查网络", Toast.LENGTH_SHORT).show();
                    }
                }
            });
        }
        else {
            Toast.makeText(zhuce.this, "邮箱格式不正确", Toast.LENGTH_SHORT).show();
        }
    }

    void zhuce() {
        if(name.length()==0||pwd.length()==0) {
            Toast.makeText(zhuce.this, "用户名和密码不能为空", Toast.LENGTH_SHORT).show();
        }
        else {
            AVQuery<AVObject> query = new AVQuery<>("user_info");
            query.whereEqualTo("name", name);
            query.countInBackground(new CountCallback() {
                @Override
                public void done(int i, AVException e) {
                    if (e == null) {
                        // 查询成功,输出计数
                        if (i == 0) {
                            baocun();
                        } else {
                            Toast.makeText(zhuce.this, "该用户名已被注册,换个名字试试", Toast.LENGTH_SHORT).show();

                        }
                    } else {
                        // 查询失败
                        Toast.makeText(zhuce.this, "连接失败,请检查网络设置", Toast.LENGTH_SHORT).show();

                    }

                }
            });
        }
    }
    //邮箱格式
    private boolean youxiang(String s){
        Matcher matcher=pa.matcher(s);
        return matcher.matches();
    }

}

登录界面代码如下:

package mountain_hua.train;

import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import com.avos.avoscloud.AVException;
import com.avos.avoscloud.AVObject;
import com.avos.avoscloud.AVQuery;
import com.avos.avoscloud.GetCallback;

/**
 * Created by dhs on 2018/5/15.
 */

public class denglu extends AppCompatActivity {
    private String name,pwd;
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.denglu);
        //登录按钮
        Button b1=(Button)findViewById(R.id.button4);
        b1.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {

                name=((EditText)findViewById(R.id.editText4)).getText().toString();
                pwd=((EditText)findViewById(R.id.editText5)).getText().toString();

                if(name.length()==0) {
                    Toast.makeText(denglu.this, "请输入用户名!", Toast.LENGTH_SHORT).show();
                }
                else if(pwd.length()==0){
                    Toast.makeText(denglu.this, "请输入密码!", Toast.LENGTH_SHORT).show();
                }
                else {

                    AVQuery<AVObject> query = new AVQuery<>("user_info");
                    query.whereEqualTo("name", name);
                    query.getFirstInBackground(new GetCallback<AVObject>() {
                        @Override
                        public void done(AVObject avObject, AVException e) {
                            // object 就是符合条件的第一个 AVObject
                            if (avObject.getString("pwd").equals(pwd)) {
                                Intent i1 = new Intent();
                                i1.putExtra("name", name);
                                i1.setClass(denglu.this, MainActivity.class);
                                startActivity(i1);
                            } else {
                                Toast.makeText(denglu.this, "用户名或密码不正确", Toast.LENGTH_SHORT).show();

                            }
                        }
                    });
                }

            }
        });
        //注册按钮
        Button b2=(Button)findViewById(R.id.button5);
        b2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent Int1=new Intent();
                Int1.setClass(denglu.this,zhuce.class);
                startActivity(Int1);
            }
        });
    }
}

(二)功能2——侧滑菜单栏

 

本部分实现了安卓的侧滑栏显示我们的菜单,包含了:列车信息,在线购票,购票记录,个人信息等。点击就可以进入相应的功能界面

本部分代码如下:

package mountain_hua.train;

import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.support.design.widget.NavigationView;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;

public class MainActivity extends AppCompatActivity
        implements NavigationView.OnNavigationItemSelectedListener {
        private String name;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        name=getIntent().getStringExtra("name");
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        
        DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
        ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
                this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
        drawer.setDrawerListener(toggle);
        toggle.syncState();

        NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
        navigationView.setNavigationItemSelectedListener(this);
    }

    @Override
    public void onBackPressed() {
        DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
        if (drawer.isDrawerOpen(GravityCompat.START)) {
            drawer.closeDrawer(GravityCompat.START);
        } else {
            super.onBackPressed();
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();
        if (id == R.id.action_settings) {
            Uri uri = Uri.parse("http://www.12306.cn/mormhweb/");
            Intent intent = new Intent(Intent.ACTION_VIEW, uri);
            startActivity(intent);
        }

        return super.onOptionsItemSelected(item);
    }

    @SuppressWarnings("StatementWithEmptyBody")
    @Override
    public boolean onNavigationItemSelected(MenuItem item) {
        int id = item.getItemId();
        if (id == R.id.train_info) {
            Intent t1=new Intent();
            t1.setClass(this,train_info.class);
            startActivity(t1);
        } else if (id == R.id.buyingticket) {
            Intent t1=new Intent();
            t1.setClass(this,buyingticket.class);
            t1.putExtra("name",name);
            startActivity(t1);
        } else if (id == R.id.person) {
            Intent t1=new Intent();
            t1.setClass(this,person.class);
            t1.putExtra("name",name);
            startActivity(t1);
        } else if (id == R.id.blue) {
            Intent t1=new Intent();
            t1.setClass(this,test1.class);
            t1.putExtra("name",name);
            startActivity(t1);
        }
        else if (id == R.id.el) {
            Intent t1=new Intent();
            t1.setClass(this,el.class);
            startActivity(t1);
        }

        DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
        drawer.closeDrawer(GravityCompat.START);
        return true;
    }
}

(三)功能3——显示列车信息

我设置了3个路线,如图,已广安——成都为例,点击相应的路线就会出现改路线的车次信息。


本部分的代码如下:

package mountain_hua.train;

import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.ImageButton;

/**
 * Created by dhs on 2018/3/22.
 */

public class train_info extends AppCompatActivity {
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.train_info);
        ImageButton ib1=(ImageButton)findViewById(R.id.imageButton1);
        ib1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent t1=new Intent();
                t1.setClass(train_info.this,train_info_1.class);
                startActivity(t1);
            }
        });
        ImageButton ib2=(ImageButton)findViewById(R.id.imageButton2);
        ib2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent t1=new Intent();
                t1.setClass(train_info.this,train_info_2.class);
                startActivity(t1);
            }
        });
        ImageButton ib3=(ImageButton)findViewById(R.id.imageButton3);
        ib3.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent t1=new Intent();
                t1.setClass(train_info.this,train_info_3.class);
                startActivity(t1);
            }
        });
    }
}

(四)功能4——在线购票之路线、日期选择

点击菜单栏的在线购票可以进入第一个购票页面,选择路线和日期。


本部分代码如下:

package mountain_hua.train;

import android.app.DatePickerDialog;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.DatePicker;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * Created by dhs on 2018/3/22.
 */

public class buyingticket extends AppCompatActivity {
    private Calendar cal;
    private int year,month,day;
    private String begin,dest,name;
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.buyingticket);
        name=getIntent().getStringExtra("name");
        final Spinner spinner=(Spinner) findViewById(R.id.spinner);
        final Spinner spinner2=(Spinner) findViewById(R.id.spinner2);
        final List<String>categories=new ArrayList<String>();
        categories.add("广安");
        categories.add("成都");
        categories.add("重庆");
        ArrayAdapter<String>dataAdapter=new ArrayAdapter<String>(buyingticket.this,android.R.layout.simple_spinner_item,categories);
        dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        spinner.setAdapter(dataAdapter);
        spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                //选择列表项的操作
                begin=categories.get(position);
                //Toast.makeText(buyingticket.this, "点击了" +begin, Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onNothingSelected(AdapterView<?> parent) {
                //未选中时候的操作
            }
        });
        spinner2.setAdapter(dataAdapter);
        spinner2.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                //选择列表项的操作
                dest=categories.get(position);
            }

            @Override
            public void onNothingSelected(AdapterView<?> parent) {
                //未选中时候的操作
            }
        });
        //日期选择(日期限制未设置):
        getDate();
       final TextView tx4=(TextView)findViewById(R.id.textView4);
        tx4.setText(year+"-"+(++month)+"-"+day);
        Button b1=(Button)findViewById(R.id.button3);
        b1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                DatePickerDialog.OnDateSetListener listener=new DatePickerDialog.OnDateSetListener() {

                    @Override
                    public void onDateSet(DatePicker arg0, int year, int month, int day) {
                        tx4.setText(year+"-"+(++month)+"-"+day);      //将选择的日期显示到TextView中,因为之前获取month直接使用,所以不需要+1,这个地方需要显示,所以+1
                    }
                };
                DatePickerDialog dialog=new DatePickerDialog(buyingticket.this, 0,listener,year,month,day);//后边三个参数为显示dialog时默认的日期,月份从0开始,0-11对应1-12个月
                dialog.show();
            }
        });
    //取消按钮
        Button b=(Button)findViewById(R.id.button);
        b.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
               finish();
            }
        });
     //查询按钮
        Button b2=(Button)findViewById(R.id.button2);
        b2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
               //查询操作
                if(begin==dest)
                {
                    Date date = new Date();
                    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    Toast.makeText(buyingticket.this, "起始站和终点站不应该相同"+sdf.format(date), Toast.LENGTH_SHORT).show();
                }else {
                    String way=begin+"——"+dest;
                    Intent t1=new Intent();
                    t1.setClass(buyingticket.this,buyingticket_1.class);
                    t1.putExtra("way",way);
                    t1.putExtra("date",tx4.getText());
                    t1.putExtra("name",name);
                    startActivity(t1);
                }

            }
        });
    }
    //获取日期
    private void getDate() {
        cal=Calendar.getInstance();
        year=cal.get(Calendar.YEAR);       //获取年月日时分秒
        Log.i("wxy","year"+year);
        month=cal.get(Calendar.MONTH);   //获取到的月份是从0开始计数
        day=cal.get(Calendar.DAY_OF_MONTH);
    }
}

(五)功能5——在线购票之车次选择

 

在选择好路线和日期后,进入车次选择,我设置的每个路线都有5趟车次,从早上八点到中午12点,一小时一趟。

本部分代码如下:

package mountain_hua.train;

import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.HashMap;

/**
 * Created by dhs on 2018/5/8.
 */

public class buyingticket_1 extends AppCompatActivity {
    private String way,name;
    private String date;
    private ListView lv2;
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.buyingticket_1);
        way=getIntent().getStringExtra("way");
        date=getIntent().getStringExtra("date");
        name=getIntent().getStringExtra("name");
        TextView t1=(TextView)findViewById(R.id.textView14);
        t1.setText(way);
        TextView t2=(TextView)findViewById(R.id.textView16);
        t2.setText(date);
        lv2 = (ListView) findViewById(R.id.lv2);/*定义一个动态数组*/
        ArrayList<HashMap<String, Object>> listItem = new ArrayList <HashMap<String,Object>>();/*在数组中存放数据*/
        for(int i=0;i<5;i++)
        {
            HashMap<String, Object> map = new HashMap<String, Object>();
            int j=i+1;
            int t=i+8;
            switch (way){
                case"广安——成都":
                    map.put("ItemTitle", "车次:GA to CD."+j);
                    break;
                case"成都——广安":
                    map.put("ItemTitle", "车次:CD to GA."+j);
                    break;
                case"广安——重庆":
                    map.put("ItemTitle", "车次:GA to CQ."+j);
                    break;
                case"重庆——成都":
                    map.put("ItemTitle", "车次:CQ to CD."+j);
                    break;
                case"重庆——广安":
                    map.put("ItemTitle", "车次:CQ to GA."+j);
                    break;
                case"成都——重庆":
                    map.put("ItemTitle", "车次:CD to CQ."+j);
                    break;
            }

            map.put("ItemText2", "发车时间:");
            map.put("ItemText",date+" "+t+":00:00");
            listItem.add(map);
        }
        //new String  数据来源, new int 数据到哪去
        SimpleAdapter mSimpleAdapter = new SimpleAdapter(this,listItem,R.layout.sample_adapter_item_1,
                new String[] {"ItemImage","ItemTitle","ItemText2", "ItemText"},
                new int[] {R.id.ItemImage,R.id.ItemTitle,R.id.ItemText2,R.id.ItemText});
        lv2.setAdapter(mSimpleAdapter);//为ListView绑定适配器
        lv2.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
                                    long arg3) {
                int j=arg2+1;
                int t=arg2+8;
                Intent it1=new Intent();
                it1.setClass(buyingticket_1.this,buyingticket_1_1.class);
                switch (way){
                    case"广安——成都":
                        it1.putExtra("way","GA to CD."+j);
                        break;
                    case"成都——广安":
                        it1.putExtra("way","CD to GA."+j);
                        break;
                    case"广安——重庆":
                        it1.putExtra("way","GA to CQ."+j);
                        break;
                    case"重庆——成都":
                        it1.putExtra("way","CQ to CD."+j);
                        break;
                    case"重庆——广安":
                        it1.putExtra("way","CQ to GA."+j);
                        break;
                    case"成都——重庆":
                        it1.putExtra("way","CD to CQ."+j);
                        break;
                }
                it1.putExtra("time",date+" "+t+":00:00");
                it1.putExtra("lc",way);
                it1.putExtra("name",name);
                startActivity(it1);
            }
        });

    }
}

(六)功能6——在线购票之座位选择,购票确认

 

用户选择车次后,进入此页面,选择车厢,排数,和座位号。并可以选择适合接收邮件提醒。如果开启邮件提醒。用户会在自己的邮箱内收到相应的购票信息,如下图:

 

本部分代码如下(本部分包含的代码量较多,提前预警):

package mountain_hua.train;

import android.content.DialogInterface;
import android.os.Bundle;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;

import com.avos.avoscloud.AVException;
import com.avos.avoscloud.AVObject;
import com.avos.avoscloud.AVQuery;
import com.avos.avoscloud.AVUser;
import com.avos.avoscloud.DeleteCallback;
import com.avos.avoscloud.FindCallback;
import com.avos.avoscloud.GetCallback;
import com.avos.avoscloud.SaveCallback;
import com.avos.avoscloud.SignUpCallback;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by dhs on 2018/5/13.
 */

public class buyingticket_1_1 extends AppCompatActivity {
    private String name,email,way;
    private String time;
    private String lc,cx,ps,zw;
    private String info;
    private boolean yx;//邮箱

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.buyingticket_1_1);
        way=getIntent().getStringExtra("way");
        time=getIntent().getStringExtra("time");
        lc=getIntent().getStringExtra("lc");
        name=getIntent().getStringExtra("name");
        //Toast.makeText(buyingticket_1_1.this, name+"cehi", Toast.LENGTH_SHORT).show();
        get_email();//获得邮箱
        TextView t1=(TextView)findViewById(R.id.textView20);
        t1.setText(way);
        TextView t2=(TextView)findViewById(R.id.textView21);
        t2.setText(time);
        //spinner
        final Spinner spinner3=(Spinner) findViewById(R.id.spinner3);
        final Spinner spinner4=(Spinner) findViewById(R.id.spinner4);
        final Spinner spinner5=(Spinner) findViewById(R.id.spinner5);
        final List<String> categories=new ArrayList<String>();
        final List<String> categories2=new ArrayList<String>();
        final List<String> categories3=new ArrayList<String>();
        for(int i=1;i<=10;i++){
            categories.add(i+"号车厢");
            categories2.add(i+"排");
        }
        categories3.add("A座");
        categories3.add("B座");
        categories3.add("C座");
        categories3.add("D座");
        categories3.add("E座");
        ArrayAdapter<String> dataAdapter=new ArrayAdapter<String>(buyingticket_1_1.this,android.R.layout.simple_spinner_item,categories);
        dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        spinner3.setAdapter(dataAdapter);
        spinner3.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                //选择列表项的操作
                cx=categories.get(position);
            }

            @Override
            public void onNothingSelected(AdapterView<?> parent) {
                //未选中时候的操作
            }
        });
        ArrayAdapter<String> dataAdapter2=new ArrayAdapter<String>(buyingticket_1_1.this,android.R.layout.simple_spinner_item,categories2);
        dataAdapter2.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        spinner4.setAdapter(dataAdapter2);
        spinner4.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                //选择列表项的操作
                ps=categories2.get(position);
            }

            @Override
            public void onNothingSelected(AdapterView<?> parent) {
                //未选中时候的操作
            }
        });
        ArrayAdapter<String> dataAdapter3=new ArrayAdapter<String>(buyingticket_1_1.this,android.R.layout.simple_spinner_item,categories3);
        dataAdapter3.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        spinner5.setAdapter(dataAdapter3);
        spinner5.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                //选择列表项的操作
                zw=categories3.get(position);
            }

            @Override
            public void onNothingSelected(AdapterView<?> parent) {
                //未选中时候的操作
            }
        });
        //check box
        CheckBox cb=(CheckBox)findViewById(R.id.checkBox);
        cb.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                if(isChecked){
                    yx=true;
                }else{
                    yx=false;
                }
            }
        });

       //确认按钮
        Button b1=(Button)findViewById(R.id.button7);
        b1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                new AlertDialog.Builder(buyingticket_1_1.this).setTitle("请确认信息")//设置对话框标题

                        .setMessage("您购买"+lc+"选择的车次是"+way+"  " +
                                "出发时间:"+time+"  "+
                                "车厢:"+cx+"  " +
                                "排数:"+ps+"  " +
                                "座位号:"+zw)//设置显示的内容
                        .setPositiveButton("确定",new DialogInterface.OnClickListener() {//添加确定按钮
                            @Override
                            public void onClick(DialogInterface dialog, int which) {//确定按钮的响应事件
                                // TODO Auto-generated method stub
                                
//保存数据
                                baocun();

                                               //发邮件
                                if(yx) {

                                    AVUser user = new AVUser();// 新建 AVUser 对象实例
                                    info = name+",您购买" + lc + "选择的车次是" + way + "  " +
                                            "出发时间:" + time + "  " +
                                            "车厢:" + cx + "  " +
                                            "排数:" + ps + "  " +
                                            "座位号:" + zw;
                                    user.setUsername(info);// 设置用户名
                                    user.setPassword("cat!@#123");// 设置密码
                                    user.setEmail(email);// 设置邮箱
                                    user.signUpInBackground(new SignUpCallback() {
                                        @Override
                                        public void done(AVException e) {
                                            if (e == null) {
                                                // 注册成功

                                                Toast.makeText(buyingticket_1_1.this, "邮件发送成功", Toast.LENGTH_SHORT).show();
                                            } else {
                                                // 失败的原因可能有多种,常见的是用户名已经存在。
                                                Toast.makeText(buyingticket_1_1.this, "邮箱发送失败,请检查网络或邮箱是否正确", Toast.LENGTH_SHORT).show();
                                            }
                                        }
                                    });
                                    //删除User,方便重新发邮件
                                    delete();

                                }
                                else {
                                    Toast.makeText(buyingticket_1_1.this, "购票成功", Toast.LENGTH_SHORT).show();
                                }


                            }

                        }).setNegativeButton("返回",new DialogInterface.OnClickListener() {//添加返回按钮
                    @Override
                    public void onClick(DialogInterface dialog, int which) {//响应事件
                        // TODO Auto-generated method stub
                    
}

                }).show();//在按键响应事件中显示此对话框
            }
        });

    }
    //删除操作
    void delete(){

        final AVQuery<AVUser> query1 = new AVQuery<>("_User");

        query1.whereEqualTo("email", email);
                query1.findInBackground(new FindCallback<AVUser>() {
            @Override
            public void done(List<AVUser> list, AVException e) {
                if(e==null)
                {
                query1.deleteAllInBackground(new DeleteCallback() {
                    @Override
                    public void done(AVException e) {

                    }
                });
                }
                else{

                }
            }
        });
    }
    //保存信息
    void baocun(){
        AVObject inf=new AVObject("info");
        inf.put("name",name);
        inf.put("lc",lc);
        inf.put("way",way);
        inf.put("zw",zw);
        inf.put("cx",cx);
        inf.put("ps",ps);
        inf.put("time",time);
        inf.saveInBackground(new SaveCallback() {
            @Override
            public void done(AVException e) {
                if(e==null){
                    Toast.makeText(buyingticket_1_1.this, "购票成功", Toast.LENGTH_SHORT).show();
                }
                else {
                    Toast.makeText(buyingticket_1_1.this, "购票失败,请检查网络", Toast.LENGTH_SHORT).show();
                }
            }
        });
    }
    //获得邮箱
    void get_email(){
        AVQuery<AVObject> query = new AVQuery<>("user_info");
        query.whereEqualTo("name",name);
        query.getFirstInBackground(new GetCallback<AVObject>() {
            @Override
            public void done(AVObject avObject, AVException e) {
                // object 就是符合条件的第一个 AVObject
                email=avObject.getString("email");

            }
        });
    }

}

(七)功能7——本地客户端查看购票记录

 

当用户购票完成后,可以返回菜单栏查看购票记录,系统会从云端自动加载购票记录到客户端。用户可以滑动查看

本部分代码如下:

package mountain_hua.train;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.Toast;

import com.avos.avoscloud.AVException;
import com.avos.avoscloud.AVObject;
import com.avos.avoscloud.AVQuery;
import com.avos.avoscloud.FindCallback;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
 * Created by dhs on 2018/3/22.
 */

public class person extends AppCompatActivity {
    private ListView lv;
    private String way;
    private String time;
    private String lc,cx,ps,zw;
    private String name,creatat;
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.person);
        name=getIntent().getStringExtra("name");
       // ArrayList<HashMap<String, Object>> listItem = new ArrayList <HashMap<String,Object>>();/*在数组中存放数据*/


        AVQuery<AVObject> query = new AVQuery<>("info");
        query.whereEqualTo("name",name);
        query.orderByDescending("createdAt");
        query.findInBackground(new FindCallback<AVObject>() {
            final ArrayList<HashMap<String, Object>> listItem = new ArrayList <HashMap<String,Object>>();/*在数组中存放数据*/
            @Override

            public void done(List<AVObject> list, AVException e) {
                for(AVObject account :list){
                    lc=account.getString("lc");
                    way=account.getString("way");
                    time=account.getString("time");
                    cx=account.getString("cx");
                    ps=account.getString("ps");
                    zw=account.getString("zw");
                    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    creatat=sdf.format(account.getDate("createdAt"));
                    HashMap<String, Object> map = new HashMap<String, Object>();
                    map.put("ItemImage", R.drawable.b2);//加入图片
                    map.put("ItemTitle", lc);
                    map.put("tx1","购票时间:");
                    map.put("tx2",creatat);
                    map.put("tx3","发车时间:");
                    map.put("ItemText2", "车次:"+way);
                    map.put("ItemText",time);
                    map.put("ItemText4", "车厢:"+cx);
                    map.put("ItemText5", "排数:"+ps);
                    map.put("ItemText6", "座位:"+zw);
                    listItem.add(map);
                    lv = (ListView) findViewById(R.id.lv);
                    //new String  数据来源, new int 数据到哪去
                    SimpleAdapter mSimpleAdapter = new SimpleAdapter(person.this,listItem,R.layout.sample_adapter_item,
                            new String[] {"ItemImage","ItemTitle","tx1","tx2","tx3","ItemText2", "ItemText","ItemText4","ItemText5","ItemText6"},
                            new int[] {R.id.ItemImage,R.id.ItemTitle,R.id.tx1,R.id.tx2,R.id.tx3,R.id.ItemText2,R.id.ItemText,R.id.ItemText4,R.id.ItemText5,R.id.ItemText6});
                    lv.setAdapter(mSimpleAdapter);//为ListView绑定适配器
                    lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                        @Override
                        public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
                                                long arg3) {
                        }
                    });
                }

                if (e == null) {

                    Toast.makeText(person.this, "查询成功", Toast.LENGTH_SHORT).show();
                } else {
                    Toast.makeText(person.this, "查询失败,请检查网络", Toast.LENGTH_SHORT).show();
                }
            }


        });

    }

}

(八)功能8——个人信息修改

 

从菜单栏进入个人信息修改界面,系统会先从云端加载个人信息(用户名我们设置的唯一且不可修改),可以修改密码和邮箱(邮箱会通过正则表达式确认是否正确,不正确会提示格式不正确)。

本部分代码如下:

package mountain_hua.train;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

import com.avos.avoscloud.AVException;
import com.avos.avoscloud.AVObject;
import com.avos.avoscloud.AVQuery;
import com.avos.avoscloud.GetCallback;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Created by dhs on 2018/3/21.
 */

public class test1  extends AppCompatActivity {
    private String name,email,pwd;
    private static final String EP="^[a-z0-9]+([._\\\\-]*[a-z0-9])*@([a-z0-9]+[-a-z0-9]*[a-z0-9]+.){1,63}[a-z0-9]+$";//邮箱格式
    private static final String EPP="[^a-zA-Z0-9#_~!$&'()*+,=;=:.\"(),:;<>@\\[\\]\\\\]+@[a-zA-Z0-9-]+(\\.[a-zA-Z0-9-]+)*$";
    private Pattern pa=Pattern.compile(EP);
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.test1);
        name=getIntent().getStringExtra("name");

        final EditText ed1=(EditText)findViewById(R.id.editText4);
        ed1.setKeyListener(null);
        final EditText ed2=(EditText)findViewById(R.id.editText5);
        final EditText ed3=(EditText)findViewById(R.id.editText);
        //
        AVQuery<AVObject> query = new AVQuery<>("user_info");
        query.whereEqualTo("name",name);
        query.getFirstInBackground(new GetCallback<AVObject>() {
            @Override
            public void done(AVObject avObject, AVException e) {
                // object 就是符合条件的第一个 AVObject
                email=avObject.getString("email");
                pwd=avObject.getString("pwd");
                if(e==null){
                    ed1.setText(name);
                    ed2.setText(pwd);
                    ed3.setText(email);
                }
            }
        });


        Button b1=(Button)findViewById(R.id.button5);
        b1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                AVQuery<AVObject> query = new AVQuery<>("user_info");
                query.whereEqualTo("name",name);
                query.getFirstInBackground(new GetCallback<AVObject>() {
                    @Override
                    public void done(final AVObject avObject, AVException e) {
                        // object 就是符合条件的第一个 AVObject
                                String s=ed3.getText().toString();
                                String m=ed2.getText().toString();
                              if(youxiang(s)&&m.length()!=0) {
                                  avObject.put("pwd", ed2.getText());
                                  avObject.put("email", ed3.getText());
                                  avObject.saveInBackground();

                                  if (e == null) {
                                      Toast.makeText(test1.this, "保存成功" , Toast.LENGTH_SHORT).show();
                                  } else {
                                      Toast.makeText(test1.this, "保存失败,请检查网络", Toast.LENGTH_SHORT).show();
                                  }
                              }
                              else if(m.length()==0) {
                                  Toast.makeText(test1.this,"密码不能为空", Toast.LENGTH_SHORT).show();
                              }
                              else {
                                  Toast.makeText(test1.this,"邮箱格式不正确", Toast.LENGTH_SHORT).show();
                              }
                    }
                });
            }
        });
    }
    //邮箱格式
    private boolean youxiang(String s){
        Matcher matcher=pa.matcher(s);
        return matcher.matches();
    }

}

(九)功能9——小组成员及分工查看

在这里我截取了各组员的QQ头像作为imageButton。点击各组员头像可以查看分工情况(其实都是我一人完成的,但组员也要有成绩呀)


本部分代码如下:

package mountain_hua.train;

import android.os.Bundle;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.AdapterView;
import android.widget.GridView;
import android.widget.SimpleAdapter;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by dhs on 2018/5/13.
 */

public class el extends AppCompatActivity {
    private GridView gridView;
    private List<Map<String, Object>> dataList;
    private SimpleAdapter adapter;

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.el);

        gridView = (GridView) findViewById(R.id.gridview);
        //初始化数据
        initData();

        String[] from={"img","text"};

        int[] to={R.id.img,R.id.text};

        adapter=new SimpleAdapter(this, dataList, R.layout.gridview_item, from, to);

        gridView.setAdapter(adapter);

        gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
                                    long arg3) {
                AlertDialog.Builder builder= new AlertDialog.Builder(el.this);
                switch (arg2){
                    case 0:
                        builder.setTitle("邓华山").setMessage("组长,代码撰写,文档撰写").create().show();
                        break;
                    case 1:
                        builder.setTitle("汪瑞").setMessage("组员,数据库构建,文档撰写").create().show();
                        break;
                    case 2:
                        builder.setTitle("旦增曲珍").setMessage("组员,信息采集,文档撰写").create().show();
                        break;
                    case 3:
                        builder.setTitle("赵振廷").setMessage("组员,测试bug,文档撰写").create().show();
                        break;
                    case 4:
                        builder.setTitle("伊娃").setMessage("组员,测试bug,文档撰写").create().show();
                        break;
                }

            }
        });
    }

    void initData() {
        //图标
        int icno[] = { R.drawable.dhs,R.drawable.wr,R.drawable.qz,R.drawable.zzt,R.drawable.yw,  };
        //图标下的文字
        String name[]={"邓华山","汪瑞","旦曾曲珍","赵振廷","伊娃",};
        dataList = new ArrayList<Map<String, Object>>();
        for (int i = 0; i <icno.length; i++) {
            Map<String, Object> map=new HashMap<String, Object>();
            map.put("img", icno[i]);
            map.put("text",name[i]);
            dataList.add(map);
        }


    }
}

第三部分 数据库

(一)leancloud数据库介绍:

下面这条 SQL 语句在绝大数的关系型数据库都可以执行,其结果是在 Todo 表里增加一条新数据:

+

INSERT INTO Todo (title, content) VALUES ('工程师周会', '每周工程师会议,周一下午 2 点')

+

使用传统的关系型数据库作为应用的数据源几乎无法避免以下步骤:

+

· 插入数据之前一定要先创建一个表结构,并且随着之后需求的变化,开发者需要不停地修改数据库的表结构,维护表数据。

· 每次插入数据的时候,客户端都需要连接数据库来执行数据的增删改查(CRUD)操作。

使用 LeanStorage,实现代码如下:

+

        AVObject todo = new AVObject("Todo");

        todo.put("title", "工程师周会");

        todo.put("content", "每周工程师会议,周一下午2点");

        todo.saveInBackground(new SaveCallback() {

            @Override

            public void done(AVException e) {

                if (e == null) {

                    // 存储成功

                } else {

                    // 失败的话,请检查网络环境以及 SDK 配置是否正确

                }

            }

        });

+

使用 LeanStorage 的特点在于:

+

· 不需要单独维护表结构。例如,为上面的 Todo 表新增一个 location 字段,用来表示日程安排的地点,那么刚才的代码只需做如下变动:

        AVObject todo = new AVObject("Todo");

        todo.put("title", "工程师周会");

        todo.put("content", "每周工程师会议,周一下午2点");

        todo.put("location", "会议室");// 只要添加这一行代码,服务端就会自动添加这个字段

        todo.saveInBackground(new SaveCallback() {

            @Override

            public void done(AVException e) {

                if (e == null) {

                    // 存储成功

                } else {

                    // 失败的话,请检查网络环境以及 SDK 配置是否正确

                }

            }

        });

+

· 数据可以随用随加,这是一种无模式化(Schema Free)的存储方式。

· 所有对数据的操作请求都通过 HTTPS 访问标准的 REST API 来实现。

· 各个平台或者语言开发的 SDK 在底层都是调用统一的 REST API,并提供完整的接口对数据进行增删改查。

LeanStorage 在结构化数据存储方面,与 DB 的区别在于:

+

1. Schema Free/Not free 的差异;

2. 数据接口上,LeanStorage 是面向对象的(数据操作接口都是基于 Object 的),开放的(所有移动端都可以直接访问),DB 是面向结构的,封闭的(一般在 Server 内部访问);

3. 数据之间关联的方式,DB 是主键外键模型,LeanStorage 则有自己的关系模型(Pointer、Relation 等);

LeanStorage 支持两种存储类型:

+

· 对象

· 文件

(二)构建用户信息表:

我们构建用户信息:namepwdemail,以及leancloud自动生成的createdAt,updatedAt.

如图:

字段

类型

主键

Notnull

默认

说明

Name

String

 

用户名

Pwd

String

 

密码

Email

String

 

电子邮箱

下图是我们的用户:

 

(三)构建购票信息表:

我们设置了nametimelc,way,zw,cx,ps,以及leancloud自动创建的createdAtupdatedAt

如图:

字段

类型

主键

Notnull

默认

说明

Name

String

 

用户名

Time

String

 

出发时间

Lc

String

 

路程

Way

String

 

车次

zw

String

 

座位号

cx

String

 

车厢号

ps

String

 

车厢的排数

下面是我们的购票信息:

 

第四部分 总结

此次课程设计大概花了四五天的课余时间吧,总的来说没遇到什么大问题,还是很顺利的

猜你喜欢

转载自blog.csdn.net/mountain_hua/article/details/80555812