Android:答题APP的设计与实现(mysql+jsp+Android) Android:答题APP的设计与实现(mysql+jsp+Android)

Android:答题APP的设计与实现(mysql+jsp+Android)

还没有整理完,待续……
学校开了Android课,最后让交一个大作业。正好拿来练练手,记录下思路。也希望能给有需要的朋友们一些帮助。恩,纯小白教程,大神们可以绕路了。
作业的题目是这样的:
考试APP系统:
1)要求有用户登陆功能:从远程服务器进行登陆验证。
2)要有考试测试界面,主要是选择、判断、简答题目测试。
3)要有统计成绩界面和错题显示界面。
评分标准:
1、界面设计占评分的30%
2、系统运行正确; 功能完善;工作量充分; 系统实现有一定的技术的难度。50%
3、要求有适当的系统主要模块的文档说明和代码注释。
4、直接将数据库文件(数据库一定要备份成SQL语句格式,指明数据库)和项目文件提交。

乍一看挺简单的,真要研究起来,写的实用一些,还真有点不知如何下手,那跟着我的思路,一起来吧!恩,不想看思路的,可以直接戳Android源码下载源码来看了。

下载地址:

如果不嫌弃的话,可以直接下载。
没有积分的话……帮忙点个赞,然后留个邮箱,我发给你哈~~
https://download.csdn.net/download/zheng_weichao/10310185

功能需求设计:

  • 登录注册
  • 答题:选择题,判断题,简答题
  • 答题得分计算
  • 错题查看

最后效果

这里写图片描述

总体思路

总体思路是这样的,App通过http连接服务器,进行登录或者注册服务,登录成功之后,服务器查询数据库并以json的形式返回试题数据。App接收数据之后,解析并存到本地数据库,然后展示给用户答题。点击交卷按钮后,进行评分并可进行错题查看。内容比较杂乱,大家可以根据目录来快速查看自己需要或者感兴趣的地方。

数据库设计

首先,就登录注册的功能来说,得先有一个用户表,包含用户名,密码,id号这些基本的内容。我在这里又加了一个权限字段,用来返回状态。(设置权限字段,方便日后进行扩展,可设置用不同数字代表不同等级或身份)

tbl_user_info

字段 类型 含义
id int(自增长主键) 用户唯一标识符
username varchar 用户
password varchar 密码
perssion varchar(默认为0) 权限

其次,就是题库了。为了使项目具有实用性,减小安装包体积,便于更新修正,题库同样也需要放在服务器上才合适。

tbl_question

字段 类型 含义
id int(自增长主键) 题目唯一标识id
q_type: int 题型: 1:选择 2:判断 3:简答
title: varchar 问题
optionA: varchar 选项A
optionB: varchar 选项B
optionC: varchar 选项C
optionD: varchar 选项D
tips: varchar 提示
answer: varchar 答案
explain: varchar 解释
write_answer: varchar 你的答案

jsp程序

jsp依赖了两个jar包,分别是连接mysql的驱动:mysql-connector-java-5.1.34-bin还有生成json用的:json 。为了减少代码的耦合性,这里采用MVC模式进行设计。(自以为是MVC)。目录结构如下:
jsp目录结构

登录注册

连接数据库

数据库操作类,封装了连接,查询,关闭数据库的方法。大家如果使用这部分代码,别忘了把数据库连接常量改成自己的。

//****连接数据库**DBManager***
public class DBManager {

    // 数据库连接常量
    public static final String DRIVER = "com.mysql.jdbc.Driver";
    public static final String USER = "root";
    public static final String PASS = "root";
    public static final String URL = "jdbc:mysql://localhost:3306/shop";

    // 静态成员,支持单态模式
    private static DBManager per = null;
    private Connection conn = null;
    private Statement stmt = null;

    // 单态模式-懒汉模式
    private DBManager() {
    }

    public static DBManager createInstance() {
        if (per == null) {
            per = new DBManager();
            per.initDB();
        }
        return per;
    }

    // 加载驱动
    public void initDB() {
        try {
            Class.forName("com.mysql.jdbc.Driver");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    // 连接数据库,获取句柄+对象
    public void connectDB() {
        System.out.println("Connecting to database...");
        try {
            conn = DriverManager.getConnection(URL, USER, PASS);
            stmt = conn.createStatement();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        System.out.println("SqlManager:Connect to database successful.");
    }

    // 关闭数据库 关闭对象,释放句柄
    public void closeDB() {
        System.out.println("Close connection to database..");
        try {
            stmt.close();
            conn.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        System.out.println("Close connection successful");
    }

    // 查询
    public ResultSet executeQuery(String sql) {
        ResultSet rs = null;
        try {
            rs = stmt.executeQuery(sql);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return rs;
    }

    // 增添/删除/修改
    public int executeUpdate(String sql) {
        int ret = 0;
        try {
            ret = stmt.executeUpdate(sql);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return ret;
    }
}
  • 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
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81

登录

客户端提交过来一个用户名,一个密码,jsp连接数据库查询,如果两者都符合,返回登录成功信息,否则返回登录失败信息。(我这里用权限来代表,当权限>-1即为登录成功)。

注册

客户端同样提交过来一个用户名,一个密码,但是需要首先查询数据库,看看该用户名是否已被注册,若没有,则执行数据库插入操作。成功则返回注册成功,否则返回失败信息。

//****服务代码****
public class StartService {
    /**
     * 登录方法
     * @param username
     * @param password
     * @return 登录成功与否
     */
    public HashMap<String, String> login(String username, String password) {

        HashMap<String, String> hashMap = new HashMap<String, String>();
        // 获取Sql查询语句
        String logSql = "select perssion from userinfo where username ='"
                + username + "' and password ='" + password + "'";
        System.out.println(logSql);
        // 获取DB对象
        DBManager sql = DBManager.createInstance();
        sql.connectDB();

        hashMap.put("permission", "-1");
        hashMap.put("username", username);

        // 操作DB对象
        try {
            ResultSet rs = sql.executeQuery(logSql);
            if (rs.next()) {
                hashMap.put("permission", rs.getInt(1) + "");
                System.out.print("权限===" + rs.getInt(1) + "\t");
                sql.closeDB();
                return hashMap;
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        sql.closeDB();
        return hashMap;
    }

    /**
     * 注册方法
     * @param username
     * @param password
     * @return 注册成功与否
     */
    public HashMap<String, String> register(String username, String password) {

        HashMap<String, String> hashMap = new HashMap<String, String>();
        hashMap.put("username", username);
        hashMap.put("msg", "notok");
        if (this.namerepeat(username)) {
            hashMap.put("msg", "rename");
        } else {
            // 获取Sql查询语句
            String regSql = "insert into userinfo(username,password) values('"
                    + username + "','" + password + "')";
            System.out.println(regSql);

            // 获取DB对象
            DBManager sql = DBManager.createInstance();
            sql.connectDB();

            int ret = sql.executeUpdate(regSql);
            if (ret != 0) {
                hashMap.put("msg", "ok");
                sql.closeDB();
                return hashMap;
            }
            sql.closeDB();
        }

        return hashMap;
    }

    /**
     * 检测该账户是否已经注册
     * 
     * @param username
     * @return 注册状态
     */
    public Boolean namerepeat(String username) {
        String checkSql = "select username from userinfo where username ='"
                + username + "'";
        // 获取Sql查询语句
        System.out.println(checkSql);

        // 获取DB对象
        DBManager sql = DBManager.createInstance();
        sql.connectDB();

        // 操作DB对象
        try {
            ResultSet rs = sql.executeQuery(checkSql);
            if (rs.next()) {

                sql.closeDB();
                return true;
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        sql.closeDB();
        return false;
    }
}
  • 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
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104

登录注册部分的代码基本一样,只把 serv.login变成serv.reglet就可以了。

//****登录代码****
String username = request.getParameter("username");
String password = request.getParameter("password");
username = new String(username.getBytes("ISO-8859-1"), "UTF-8");
System.out.println("客户端参数:" + username + "  ======  " + password);
    // 新建服务对象,默认权限为-1(未登录状态)
    StartService serv = new StartService();
    int permission = -1;
    HashMap<String, String> logiii = serv.login(username, password);
    String a = logiii.get("username");
    // 登陆验证处理(权限>-1为登录成功)
    if ("-1".equals(logiii.get("permission"))) {
        // 登录失败
        System.out.print("登录失败Failed");
    } else {
        // 登陆成功
        permission = Integer.parseInt(logiii.get("permission"));
    }
    JSONObject jsonObj = new JSONObject();
    try {
        jsonObj.put("username", username);
        jsonObj.put("permission", permission);
        System.out.println(jsonObj);
        // 返回信息到客户端
        response.setCharacterEncoding("UTF-8");
        response.setContentType("text/html");
        PrintWriter out = response.getWriter();
        out.print(jsonObj);
        out.flush();
        out.close();
    } catch (JSONException e) {
        e.printStackTrace();
    }
  • 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
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33

json格式设计

注册结果

{
    "username": "001",
    "msg": "ok"
}
  • 1
  • 2
  • 3
  • 4

登录结果

{
    "username": "001",
    "permission": 0
}
  • 1
  • 2
  • 3
  • 4

答题

json格式设计

{
    "status": ok,  //连接状态
    "code": "200"   //错误代码
    "messages": [   //题目内容
        {
            "_id": 1,   //题目id
            "title": "1+1=?"  //题目
            "q_type": 0,  //题目类型
            "optionA": "1",  //A选项
            "optionB": "2",  //B选项
            "optionC": "3",  //C选项
            "optionD": "4",  //D选项
            "tips”:"这么简单还要提示?",  //提示
            "answer": "B",  //答案
        },
        {
            "_id": 2,
             "title": "2+2=?" 
            "q_type": 0, 
            "optionA": "1", 
            "optionB": "2", 
            "optionC": "3", 
            "optionD": "4",
            "tips":"这么简单还要提示?",  
            "answer": "D",
        }
    ],
}
  • 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
  • 26
  • 27
  • 28

Android程序设计

恩,这才是全文的重点好不好?毕竟这是Android课的大作业诶。开发工具Android studio,依赖的库比较多,所以代码相当简单。话不多说,开撸了!

应该有哪些界面?

  • SplashActivity(启动页面):展示下logo,还可以做一些耗时操作。
  • LoginActivity(登录页面):用来登录
  • SignupActivity(注册页面):用来注册
  • AnswerActivity(答题页面):答题,上面设置的viewpager绑定的fragment。
  • GradeActivity(得分页面):答题结束后用来展示分数。
  • AnswerFragment:绑定在AnswerActivity之上,根据题目数量动态创建

    关系图大概就是下面这个样子。
    答题app设计

用到了哪些知识?依赖了什么第三方框架?

恩……这部分是写在文档里的,想了想,一并拿出来吧。工程联网部分依赖以okhttp为基础的OkGo框架,数据库部分采用GreenDao框架。其他的,都是特别基础的一些知识,大致如下:

  1. 页面intent跳转,参数的传递
  2. 联网操作以及json数据的解析
  3. sqlite数据库的连接以及增删改查
  4. viewpager与fragment的绑定。
  5. 计时器的设计实现
  6. 主题样式的自定义设置
  7. 自定义对话框
  8. 背景选择器selector的使用
  9. 页面跳转动画效果的设计与实现
  10. listview数据填充及优化

页面详解

BaseActivity(Activity基类)

为了让增强代码可读性,减少重复代码,所以把一些共性代码做了抽取。

public abstract class BaseActivity extends FragmentActivity implements View.OnClickListener {
    @Override
    protected final void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //得到布局文件
        setContentView(getLayoutId());

        //初始化
        initView();
        initData();
        initListener();
    }

    /**
     * @return 布局文件id
     */
    abstract int getLayoutId();

    /**
     * 初始化View
     */
    void initView() {
    }

    /**
     * 初始化界面数据
     */
    void initData() {
    }

    /**
     * 绑定监听器与适配器
     */
    void initListener() {
    }

    /**
     * 对统一的按钮进行统一处理
     *
     * @param v 点击的View
     */
    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            default:
                processClick(v);
                break;
        }
    }

    /**
     * 点击事件
     *
     * @param v 点击的View
     */
    void processClick(View v) {
    }
}
  • 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
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58

SplashActivity(启动页面)

绑定activity_splash布局文件,延时2秒钟跳转主页面。

public class SplashActivity extends BaseActivity {

    @Override
    int getLayoutId() {
        return R.layout.activity_splash;
    }
    @Override
    void initData() {
        //延时2s,跳转。
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                //跳转主页面
                Intent intent = new Intent(SplashActivity.this, MainActivity.class);
                startActivity(intent);
                finish();
            }
        }, 2000);
    }

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

LoginActivity(登录页面)

java代码LoginActivity.java

public class LoginActivity extends BaseActivity {
    private static final int REQUEST_SIGNUP = 0;
    EditText et_username;
    EditText et_password;
    Button btn_login;
    TextView tv_signup;

    @Override
    int getLayoutId() {
        return R.layout.activity_login;
    }

    @Override
    void initView() {
        //通过id找控件
        et_username = (EditText) findViewById(R.id.input_username);
        et_password = (EditText) findViewById(R.id.input_password);
        btn_login = (Button) findViewById(R.id.btn_login);
        tv_signup = (TextView) findViewById(R.id.link_signup);
    }

    @Override
    void initListener() {
        //登录按钮,注册链接设置点击监听事件
        btn_login.setOnClickListener(this);
        tv_signup.setOnClickListener(this);
    }

    @Override
    void processClick(View v) {
        switch (v.getId()) {
            //点击登录按钮,执行登录操作
            case R.id.btn_login:
                login();
                break;
            //如果点击了注册链接,则跳转到注册页面
            case R.id.link_signup:
                Intent intent = new Intent(getApplicationContext(), SignupActivity.class);
                startActivityForResult(intent, REQUEST_SIGNUP);
                finish();
                //动画效果
                overridePendingTransition(R.anim.push_left_in, R.anim.push_left_out);
                break;
            default:
                break;
        }
    }

    /**
     * 登录方法
     */
    public void login() {
        //如果内容不合法,则直接返回,显示错误。
        if (!validate()) {
            onLoginFailed();
            return;
        }
        //输入合法,将登录按钮置为不可用,显示圆形进度对话框
        btn_login.setEnabled(false);
        final ProgressDialog progressDialog = new ProgressDialog(LoginActivity.this, R.style.AppTheme_Dark_Dialog);
        progressDialog.setIndeterminate(true);
        progressDialog.setMessage("登录中...");
        progressDialog.show();
        //获取输入内容
        String username = et_username.getText().toString().trim();
        String password = et_password.getText().toString().trim();
        //联网,获取数据
        OkGo.get(CONFIG.URL_LOGIN)
                .params("username", username)
                .params("password", password)
                .execute(new StringCallback() {
                    @Override
                    public void onSuccess(String s, Call call, Response response) {
                        Gson gson = new Gson();
                        JsonLoginBean jsonLoginBean = gson.fromJson(s, JsonLoginBean.class);
                        //如果得到权限>0,则登录成功。
                        if (jsonLoginBean.getPermission() > 0) {
                            Log.e("zwc", "onSuccess: ===");
                            onLoginSuccess();
                            progressDialog.dismiss();
                        } else {
                            onLoginFailed();
                            progressDialog.dismiss();
                        }
                    }
                });
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == REQUEST_SIGNUP) {
            if (resultCode == RESULT_OK) {
                this.finish();
            }
        }
    }

    /**
     * 重写返回键的返回方法
     */
    @Override
    public void onBackPressed() {
        // Disable going back to the MainActivity
        moveTaskToBack(true);
    }

    /**
     * 登录成功
     */
    public void onLoginSuccess() {
        btn_login.setEnabled(true);
        Intent intent = new Intent(LoginActivity.this, MainActivity.class);
        startActivity(intent);
        finish();
    }

    /**
     * 登录失败
     */
    public void onLoginFailed() {
        Toast.makeText(getBaseContext(), "登陆失败", Toast.LENGTH_LONG).show();
        btn_login.setEnabled(true);
    }

    /**
     * @return 判断是否账号密码是否合法
     */
    public boolean validate() {
        //设置初值,默认为合法
        boolean valid = true;

        //获取输入内容
        String email = et_username.getText().toString().trim();
        String password = et_password.getText().toString().trim();

        //判断账号
        if (email.isEmpty()) {
            et_username.setError("请输入你的账号");
            valid = false;
        } else {
            et_username.setError(null);
        }
        //判断密码
        if (password.isEmpty()) {
            et_password.setError("请输入你的密码");
            valid = false;
        } else {
            et_password.setError(null);
        }

        return valid;
    }
}
  • 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
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153

布局文件activity_login.xml

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:fitsSystemWindows="true">
    <LinearLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:paddingTop="56dp"
        android:paddingLeft="24dp"
        android:paddingRight="24dp">

        <ImageView android:src="@drawable/logo"
            android:layout_width="wrap_content"
            android:layout_height="72dp"
            android:layout_marginBottom="24dp"
            android:layout_gravity="center_horizontal" />

        <!--  账号 -->
        <android.support.design.widget.TextInputLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="8dp"
            android:layout_marginBottom="8dp">
            <EditText
                android:id="@+id/input_username"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:inputType="number"
                android:hint="账号" />
        </android.support.design.widget.TextInputLayout>

        <!-- 密码 -->
        <android.support.design.widget.TextInputLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="8dp"
            android:layout_marginBottom="8dp">
            <EditText android:id="@+id/input_password"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:inputType="textPassword"
                android:hint="密码"/>
        </android.support.design.widget.TextInputLayout>

        <android.support.v7.widget.AppCompatButton
            android:id="@+id/btn_login"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="24dp"
            android:layout_marginBottom="24dp"
            android:padding="12dp"
            android:text="登陆"/>

        <TextView android:id="@+id/link_signup"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_marginBottom="24dp"
            android:text="没有账号?创建一个"
            android:gravity="center"
            android:textSize="16dip"/>
    </LinearLayout>
</ScrollView>
  • 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
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64

SignupActivity(注册页面)

SignupActivity.java

public class SignupActivity extends BaseActivity {

    EditText _nameText;
    EditText _emailText;
    EditText _passwordText;
    EditText _reEnterPasswordText;
    Button _signupButton;
    TextView _loginLink;

    @Override
    int getLayoutId() {
        return R.layout.activity_signup;
    }

    @Override
    void initView() {
        //根据id找控件
        _nameText = (EditText) findViewById(R.id.input_name);
        _emailText = (EditText) findViewById(R.id.input_username);
        _passwordText = (EditText) findViewById(R.id.input_password);
        _reEnterPasswordText = (EditText) findViewById(R.id.input_reEnterPassword);
        _signupButton = (Button) findViewById(R.id.btn_signup);
        _loginLink = (TextView) findViewById(R.id.link_login);
        _signupButton.setOnClickListener(this);
        _loginLink.setOnClickListener(this);
    }

    @Override
    void processClick(View v) {
        switch (v.getId()) {
            case R.id.btn_signup:
                signup();
                break;
            case R.id.link_login:
                //点击登录连接,跳转到登录页面
                Intent intent = new Intent(getApplicationContext(), LoginActivity.class);
                startActivity(intent);
                finish();
                overridePendingTransition(R.anim.push_left_in, R.anim.push_left_out);
                break;
            default:
                break;
        }
    }

    public void signup() {
        //判断是否合法
        if (!validate()) {
            onSignupFailed(0);
            return;
        }
        _signupButton.setEnabled(false);

        //显示圆形进度条对话框
        final ProgressDialog progressDialog = new ProgressDialog(SignupActivity.this,
                R.style.AppTheme_Dark_Dialog);
        progressDialog.setIndeterminate(true);
        progressDialog.setMessage("创建账号...");
        progressDialog.show();
        //获取数据
        String username = _nameText.getText().toString();
        String password = _passwordText.getText().toString();
//      联网获取数据
        OkGo.get(CONFIG.URL_SIGNUP)
                .params("username", username)
                .params("password", password)
                .execute(new StringCallback() {
                    @Override
                    public void onSuccess(String s, Call call, Response response) {
                        Gson gson = new Gson();
                        JsonSignupBean jsonSignupBean = gson.fromJson(s, JsonSignupBean.class);
                        //如果得到返回消息为ok,则注册成功。
                        if (jsonSignupBean.getMsg().equals("ok")) {
                            Log.e("zwc", "onSuccess: 注册成功");
                            onSignupSuccess();
                            //对话框消失
                            progressDialog.dismiss();
                        } else {
                            onSignupFailed(1);
                            progressDialog.dismiss();
                        }
                    }
                });
    }

    /**
     * 登陆成功
     */
    public void onSignupSuccess() {
        _signupButton.setEnabled(true);

        Intent intent = new Intent(SignupActivity.this, MainActivity.class);
        startActivity(intent);
        finish();
    }

    /**
     * 注册失败,按钮置为可用
     * 依据传参不同,进行不同吐司
     */
    public void onSignupFailed(int i) {
        if (i == 1) {
            Toast.makeText(getBaseContext(), "该用户名已经被注册", Toast.LENGTH_LONG).show();
        } else {
            Toast.makeText(getBaseContext(), "注册失败", Toast.LENGTH_LONG).show();
        }
        _signupButton.setEnabled(true);
    }

    /**
     * @return 输入内容是否合法
     */
    public boolean validate() {
        boolean valid = true;
        //从控件中获取数据
        String name = _nameText.getText().toString();
        String password = _passwordText.getText().toString();
        String reEnterPassword = _reEnterPasswordText.getText().toString();
        //检测账号是否正确
        if (name.isEmpty()) {
            _nameText.setError("账号不能为空");
            valid = false;
        } else {
            _nameText.setError(null);
        }
        //检测密码是否正确
        if (password.isEmpty()) {
            _passwordText.setError("请输入密码");
            valid = false;
        } else {
            _passwordText.setError(null);
        }
        //检测重复密码是否正确
        if (reEnterPassword.isEmpty() || !(reEnterPassword.equals(password))) {
            _reEnterPasswordText.setError("两次密码不一致");
            valid = false;
        } else {
            _reEnterPasswordText.setError(null);
        }
        return valid;
    }
}
  • 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
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142

布局文件 activity_signup.xml

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:fitsSystemWindows="true">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:paddingLeft="24dp"
        android:paddingRight="24dp"
        android:paddingTop="56dp">

        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="72dp"
            android:layout_gravity="center_horizontal"
            android:layout_marginBottom="24dp"
            android:src="@drawable/logo" />

        <!-- 账号 -->
        <android.support.design.widget.TextInputLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginBottom="8dp"
            android:layout_marginTop="8dp">

            <EditText
                android:id="@+id/input_name"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:hint="账号"
                android:inputType="textPersonName" />
        </android.support.design.widget.TextInputLayout>

        <!-- 密码 -->
        <android.support.design.widget.TextInputLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginBottom="8dp"
            android:layout_marginTop="8dp">

            <EditText
                android:id="@+id/input_password"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:hint="密码"
                android:inputType="textPassword" />
        </android.support.design.widget.TextInputLayout>

        <!-- 重复密码 -->
        <android.support.design.widget.TextInputLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginBottom="8dp"
            android:layout_marginTop="8dp">

            <EditText
                android:id="@+id/input_reEnterPassword"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:hint="重复密码"
                android:inputType="textPassword" />
        </android.support.design.widget.TextInputLayout>

        <android.support.v7.widget.AppCompatButton
            android:id="@+id/btn_signup"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_marginBottom="24dp"
            android:layout_marginTop="24dp"
            android:padding="12dp"
            android:text="创建账号" />

        <TextView
            android:id="@+id/link_login"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_marginBottom="24dp"
            android:gravity="center"
            android:text="已有账号?马上登陆"
            android:textSize="16dip" />

    </LinearLayout>
</ScrollView>
  • 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
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86

AnswerActivity ,AnswerFragment(答题页面)

回答问题的页面。当到达AnswerActivity页面的时候,会联网获取题目数据,并将题目存入本地数据库。然后通过viewpager绑定n个AnswerFragment,对题目进行展示。作答后,进行存库操作。(n由题目数量决定)

public class AnswerActivity extends BaseActivity implements Chronometer.OnChronometerTickListener {

    private Chronometer chronometer;
    private ViewPager vp_answer;
    private ArrayList<Fragment> fragmentlists;
    private int minute = 0;
    private int second = 0;
    private AlertDialog.Builder builder;
    private ArrayList<String> a;
    private Button btn_previous;
    private Button btn_submit;
    private Button btn_next;
    private int nowpager = 0;
    private List<QuestBean> messages;
    private String type;

    @Override
    int getLayoutId() {
        return R.layout.activity_answer;
    }

    /**
     * 初始化布局
     */
    @Override
    void initView() {
        chronometer = (Chronometer) findViewById(R.id._chro_exam);
        vp_answer = (ViewPager) findViewById(R.id.vp_answer);
        btn_previous = (Button) findViewById(R.id._btn_previous);
        btn_submit = (Button) findViewById(R.id._btn_submit);
        btn_next = (Button) findViewById(R.id._btn_next);
//        获取传递来的变量
        type = getIntent().getExtras().get("type").toString().trim();

//      联网获取数据
        initNet(type);

        btn_previous.setOnClickListener(this);
        btn_submit.setOnClickListener(this);
        btn_next.setOnClickListener(this);
        vp_answer.setOnPageChangeListener(new MyOnPageChangeListener());
        setChronometer();
    }

    /**
     * 设置计时器
     */
    private void setChronometer() {
        chronometer.setText(nowtime());
        chronometer.start();
        chronometer.setOnChronometerTickListener(this);
        chronometer.setOnClickListener(this);
    }

    /**
     * 计时器规则
     *
     * @param chronometer
     */
    @Override
    public void onChronometerTick(Chronometer chronometer) {
        second++;
        if (second == 59) {
            minute++;
            second = 00;
        }
    }

    /**
     * 现在时间
     *
     * @return
     */
    private String nowtime() {
        if (second < 10) {
            return (minute + ":0" + second);
        } else {
            return (minute + ":" + second);
        }
    }

    /**
     * 初始化网络连接
     * @param type
     */
    private void initNet(String type) {
        a = new ArrayList<>();
        fragmentlists = new ArrayList<>();
        Log.e("zwc", "initNet: 开始联网…………");
        //进度条对话框
        final ProgressDialog progressDialog = new ProgressDialog(AnswerActivity.this, R.style.AppTheme_Dark_Dialog);
        progressDialog.setIndeterminate(true);
        progressDialog.setMessage("获取题目中...");
        progressDialog.show();
//        联网
        OkGo.get(CONFIG.URL_GETQUEST1)
                .params("type", type)
                .execute(new StringCallback() {
                    @Override
                    public void onSuccess(String s, Call call, Response response) {
                        Log.i("zwc", "onSuccess: ========---------======" + s);
                        //gson解析
                        Gson gson = new Gson();
                        JsonQuestBean jsonQuestBean = gson.fromJson(s, JsonQuestBean.class);
                        messages = jsonQuestBean.getMessages();
                        for (int i = 0; i < messages.size(); i++) {
                            QuestBean questBeanQ = messages.get(i);
                            questBeanQ.setId(i);
                            fragmentlists.add(new AnswerFragment(questBeanQ));
                            LoveDao.insertLove(questBeanQ);
                            a.add(questBeanQ.getId() + "");
                            Log.e("zwc", i + "ooooooonSuccessssssssssss: " + questBeanQ.getId() + questBeanQ.getTitle());
                        }
//                        设置适配器
                        vp_answer.setAdapter(new MainAdapter(getSupportFragmentManager()));
                        progressDialog.dismiss();
                    }

                    @Override
                    public void onError(Call call, Response response, Exception e) {
                        Log.i("zwc", "onError///////////////////");
                    }
                });
        Log.e("zwc", "initNet: 联网结束…………");
    }

    /**
     * viewpager适配器
     */
    class MainAdapter extends FragmentPagerAdapter {

        public MainAdapter(FragmentManager fm) {
            super(fm);
        }

        //获取条目
        @Override
        public Fragment getItem(int position) {
            return fragmentlists.get(position);
        }

        //数目
        @Override
        public int getCount() {
            return fragmentlists.size();
        }
    }

    @Override
    void processClick(View v) {
        switch (v.getId()) {
//            点击上一题按钮
            case R.id._btn_previous:
//                如果是第一题,则谈吐司提醒,否则上移一道题
                if (nowpager == 0) {
                    Toast.makeText(AnswerActivity.this, "已经到头啦!", Toast.LENGTH_SHORT).show();
                } else {
                    vp_answer.setCurrentItem(--nowpager);
                }
                break;
//            点击提交按钮
            case R.id._btn_submit:
//                简答题不进行提交评分
                if (type.equals("3")) {
                    Toast.makeText(this, "简答题目前暂不支持评分", Toast.LENGTH_SHORT).show();
                    return;
                }
//                否则初始化并展示提交对话框
                initAlertDialog();
                builder.show();
                break;
//            点击下一题按钮
            case R.id._btn_next:
//                如果是最后一题,则谈吐司提醒,否则下移一道题
                if (nowpager == fragmentlists.size()) {
                    Toast.makeText(AnswerActivity.this, "已经是最后一题了!", Toast.LENGTH_SHORT).show();
                } else {
                    vp_answer.setCurrentItem(++nowpager);
                }
                break;
            default:
                break;
        }
    }

    // 弹出是否确认交卷的对话框
    private void initAlertDialog() {
        //新建对话框
        builder = new AlertDialog.Builder(AnswerActivity.this);
        builder.setTitle("提示");
        builder.setMessage("是否确定交卷?");
        builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                // TODO: 2017/6/14 交卷操作
//                计算分数
                int grade = 0;
//                判断题
                if (type.equals("2")) {
                    for (int i = 0; i < messages.size(); i++) {
//                        查询
                        QuestBean questBeenA = LoveDao.queryLove(Integer.parseInt(a.get(i)));
//                        判断
                        if (questBeenA.getAnswer().equals("对") && questBeenA.getMyanswer().equals("A") || questBeenA.getAnswer().equals("错") && questBeenA.getMyanswer().equals("B")) {
                            grade += 20;
                        }
                        ;
                    }
                }
//                选择题
                else {
                    for (int i = 0; i < messages.size(); i++) {
                        QuestBean questBeenA = LoveDao.queryLove(Integer.parseInt(a.get(i)));
                        if (questBeenA.getAnswer().equals(questBeenA.getMyanswer())) {
                            grade += 20;
                        }
                        ;
                    }
                }

//                传递分数
                Intent intent = new Intent(AnswerActivity.this, GradeActivity.class);
                intent.putExtra("grade", "" + grade);
//                传递题目列表
                intent.putStringArrayListExtra("timu", a);
                startActivity(intent);
                finish();
            }

        });
        builder.setNegativeButton("取消", null);
    }

    /**
     * viewpager监听事件
     */
    private class MyOnPageChangeListener implements ViewPager.OnPageChangeListener {
        @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
        }

        @Override
        public void onPageSelected(int position) {
            nowpager = position;
        }

        @Override
        public void onPageScrollStateChanged(int state) {

        }
    }
  • 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
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235
  • 236
  • 237
  • 238
  • 239
  • 240
  • 241
  • 242
  • 243
  • 244
  • 245
  • 246
  • 247
  • 248
  • 249
  • 250
  • 251

恩,现在就写了这么多,对于作业来说应该是绰绰有余了。不过还是有很多需要改善的地方。以后有时间的话,会继续完善一下。最后,本文挺长的。真诚的感谢一下你能看到这里。

猜你喜欢

转载自blog.csdn.net/qq_27248989/article/details/80647928
今日推荐