引言

本周我们主要进行进行页面设计与代码编写,在前两天的工作中我们主要进行了以下工作:

  • 页面的初步设计与逻辑交互设计
  • 客户端代码编写
  • 后台代码编写

在这里,我对自己主要从事的工作,即APP端登录界面以及内部处理逻辑代码的编写,做一个详细的介绍。




在编写登录代码之前,我和王宁先定义了一些基类:

ios 开发代码获取app数据 app使用的开发代码都是啥_Text

BaseActivity为Activity定义了一个基类,内部为setContentView设置了getLayoutId抽象函数,从而使得Activity可以快速设置layout。

BaseApplication重写了Application类,因为app启动率先调用Application的onCreate函数,故重写这个函数,在里面做一些全局初始化。

BaseFragment'为Fragment定义基类,原理与BaseActivity相似。




一、登录界面的编写:




根据之前的界面设计,登录界面如下所示。


ios 开发代码获取app数据 app使用的开发代码都是啥_登录界面_02




登录界面由app logo作为大背景,使用手机号和密码进行登录,手机号和密码输入完毕后,点击登录按钮后,即可进行登录操作。

若没有账号,则点击下方的注册按钮,跳转到注册页面进行注册。


Android的界面布局文件是xml文件,android studio环境提供了图形化的布局文件编写,但考虑到该APP可能安装在不同屏幕的手机上,需要保证布局的灵活与精确性,所以主要还是采用手动编写代码的方式进行。

根据我的设计,中间的logo采用ImageView控件来实现,两个输入框采用EditText控件实现,三个按钮采用Button控件来实现,整体的布局控制选择纵向的LinearLayout,通过调整不同组件的layout_weight(即权重)属性,就可以控制组件的相对大小,可以自动适应不同尺寸的屏幕。整个界面的蓝色背景只要调整最上次LinearLayout的背景颜色就可以实现。

这一还有一个小技巧要特别说一下,两个输入框是带有图标的,而Android并没有自带的这种组件,所以我选择使用一个横向的LinearLayout,将一个ImageView和EditText放在一起,同时将该LinearLayout的背景设为绘制的椭圆,通过精细调整组件的尺寸,就可以达到理想的效果。

源代码如下所示:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/login_bg"
    android:orientation="vertical">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@color/login_bg"
            android:gravity="center"
            android:orientation="vertical">

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="270dp"
                android:gravity="center_horizontal|bottom"
                android:orientation="vertical"
                android:padding="40dp">

                <ImageView
                    android:layout_width="wrap_content"
                    android:layout_height="120dp"
                    android:src="@drawable/login_logo" />
            </LinearLayout>

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical">

                <LinearLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginLeft="56dp"
                    android:layout_marginRight="56dp"
                    android:background="@drawable/edittext_blue_bord_bg"
                    android:orientation="horizontal">

                    <ImageView
                        android:layout_width="16dp"
                        android:layout_height="16dp"
                        android:layout_margin="16dp"
                        android:src="@drawable/login_userid_icon" />

                    <EditText
                        android:id="@+id/loginAccountEditText"
                        android:layout_width="match_parent"
                        android:layout_height="match_parent"
                        android:layout_marginRight="16dp"
                        android:background="@null"
                        android:hint="手机号"
                        android:textColor="@color/black"
                        android:textColorHint="@color/text_hint_gray"
                        android:textSize="16sp" />
                </LinearLayout>

                <LinearLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginLeft="56dp"
                    android:layout_marginRight="56dp"
                    android:layout_marginTop="16dp"
                    android:background="@drawable/edittext_blue_bord_bg"
                    android:orientation="horizontal">

                    <ImageView
                        android:layout_width="16dp"
                        android:layout_height="16dp"
                        android:layout_margin="16dp"
                        android:src="@drawable/login_password_icon" />

                    <EditText
                        android:id="@+id/loginPasswordEditText"
                        android:layout_width="match_parent"
                        android:layout_height="match_parent"
                        android:layout_marginRight="16dp"
                        android:background="@null"
                        android:hint="密码(6-16位英文和数字)"
                        android:textColor="@color/black"
                        android:textColorHint="@color/text_hint_gray"
                        android:textSize="16sp" />
                </LinearLayout>

                <Button
                    android:id="@+id/loginLoginButton"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginLeft="56dp"
                    android:layout_marginRight="56dp"
                    android:layout_marginTop="16dp"
                    android:background="@drawable/login_button_bg"
                    android:gravity="center"
                    android:onClick="login"
                    android:text="登陆"
                    android:textColor="@color/white"
                    android:textSize="16sp" />

                <LinearLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginLeft="56dp"
                    android:layout_marginRight="56dp"
                    android:layout_marginTop="16dp"
                    android:paddingBottom="16dp">

                    <Button
                        android:id="@+id/loginForgetButton"
                        android:layout_width="0dp"
                        android:layout_height="wrap_content"
                        android:layout_weight="1"
                        android:background="@color/transparent"
                        android:gravity="center"
                        android:text="忘记密码"
                        android:textColor="@color/login_button_default_blue"
                        android:textSize="16sp" />

                    <Button
                        android:id="@+id/loginRegisterButton"
                        android:layout_width="0dp"
                        android:layout_height="wrap_content"
                        android:layout_weight="1"
                        android:background="@color/transparent"
                        android:gravity="center"
                        android:onClick="goToRegister"
                        android:text="注册"
                        android:textColor="@color/login_button_default_blue"
                        android:textSize="16sp" />
                </LinearLayout>
            </LinearLayout>
        </LinearLayout>
    </LinearLayout>
</LinearLayout>



二、内部处理逻辑代码的编写:


在之前的详细设计中,已经完成了登录的详细设计。


伪代码如下所示:

1.检查网络是否可用,不可用跳转到9

2.检查账户输入是否合法,不合法跳转到9

3.检查密码输入是否合法,不合法跳转到9

4.建立链表,将账户和密码存入其中

5.调用网络工具类的相应接口,等待返回结果

6.判断返回结果是否成功,不成功跳转到9

7.验证返回的用户数据是否为空,为空跳转到9

8.登录成功,跳转到主界面

9.登录失败

UML的活动图如下所示:


ios 开发代码获取app数据 app使用的开发代码都是啥_android_03


以此为基础,编写的代码如下所示:


package com.example.sdu.myflag.activity;

import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.*;
import android.view.View.OnClickListener;

import com.example.sdu.myflag.R;
import com.example.sdu.myflag.base.BaseActivity;
import com.example.sdu.myflag.base.BaseApplication;
import com.example.sdu.myflag.util.BaseTools;
import com.example.sdu.myflag.util.NetUtil;
import com.example.sdu.myflag.util.NetUtil.*;

import org.json.*;

import java.io.IOException;
import java.io.InputStream;
import java.util.*;

import okhttp3.Response;

/**
 * Created by Administrator on 2016/8/17.
 */
public class LoginActivity extends BaseActivity {
    private EditText accountEditText, passwordEditText;
    private Button forgetButton;
    private String account, password;

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

    @Override
    public void afterCreate(Bundle savedInstanceState) {
        //获取各组件id
        accountEditText = (EditText) findViewById(R.id.loginAccountEditText);
        passwordEditText = (EditText) findViewById(R.id.loginPasswordEditText);
        forgetButton = (Button) findViewById(R.id.loginForgetButton);
        setButtonListener();
    }

    public void goToRegister(View v) {
        startNewActivity(RegisterActivity.class);
    }

    public void login(View v) {
        if (getText()) {
            List<Param> params = new LinkedList<Param>();
            params.add(new Param("phone", account));
            params.add(new Param("password", password));

            LoginResult loginResult = new LoginResult();
            try {
                NetUtil.getResult(NetUtil.loginUrl, params, loginResult);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    //为各个按钮设置监听器
    private void setButtonListener() {
        forgetButton.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {

            }
        });
    }

    //获取各EditText中的值,并进行合法性校验,合法返回true
    //不合法返回false,并用Toast进行提醒
    private boolean getText() {
        account = accountEditText.getText().toString();
        password = passwordEditText.getText().toString();
        if (!BaseTools.isNetworkAvailable(LoginActivity.this)) {
            Toast.makeText(this, "当前网络不可用!", Toast.LENGTH_SHORT).show();
            return false;
        } else if (account.isEmpty()) {
            Toast.makeText(this, "手机号不能为空!", Toast.LENGTH_SHORT).show();
            return false;
        } else if (password.isEmpty()) {
            Toast.makeText(this, "密码不能为空!", Toast.LENGTH_SHORT).show();
            return false;
        }

        return true;
    }

    private class LoginResult implements CallBackForResult {

        @Override
        public void onFailure(final IOException e) {
            LoginActivity.this.runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    Toast.makeText(LoginActivity.this, e.getMessage(), Toast.LENGTH_LONG).show();
                }
            });
        }

        @Override
        public void onSuccess(Response response) {
            if (response.isSuccessful()) {
                try {
                    JSONObject jsonObject = new JSONObject(response.body().string());
                    String user = jsonObject.getString("user");
                    if (user.equals("")) {
                        LoginActivity.this.runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                Toast.makeText(LoginActivity.this, "用户名或密码错误", Toast.LENGTH_LONG).show();
                            }
                        });
                    } else {
                        JSONObject userJson = new JSONObject(user);
                        SharedPreferences preferences = BaseApplication.getInstance().getSharedPreferences("User", Context.MODE_PRIVATE);
                        SharedPreferences.Editor editor = preferences.edit();
                        editor.putString("uid", userJson.getInt("uid") + "").apply();
                        editor.putString("phone", userJson.getString("phone")).apply();
                        editor.putString("nickname", userJson.getString("nickname")).apply();
                        editor.putString("information", userJson.getString("information")).apply();
                        editor.putString("email", userJson.getString("email")).apply();
                        editor.putString("password", password).apply();

                        LoginActivity.this.runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                Toast.makeText(LoginActivity.this, "登陆成功", Toast.LENGTH_LONG).show();
                            }
                        });
                        startNewActivity(MainActivity.class);
                        LoginActivity.this.finish();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        }
    }

}




在我编写好登录代码,王宁编写好注册代码后,我们进行了代码互查和互测,我们采用白盒测试技术中的基本路径覆盖设计测试用例。针对不同的输入信息,设计了多组测试数据,然后再真机上对每一组数据进行实际测试,检查后台返回数据是否,直到登录注册界面测试运行无误。





总结

应该说,这两天代码的编写工作进行的比较顺利,这得益于前期做了良好的界面设计和详细设计,大大减少了编码的工作量,保证了工作进度。总体来说前两天的工作进度还是可以的,希望这周剩下的时间我能够完成好剩下的任务。