这是一个用MVP模式写的登录注册,包括手机号、密码验证,登陆成功后跳转到商品列表页面。先看一下效果:


正如我们看到的一样,在登陆界面点击注册会跳转到注册页面,注册成功后会跳转到登录界面,登录成功后会跳转到商品列表界面。在登录注册的过程中手机号和密码使用正则表达式进行了验证,使用OKhttp请求的网络,RecyclerView展示的数据,Springview执行上拉刷新和下拉加载。下面看代码:

MainActivity

public class MainActivity extends AppCompatActivity implements LoginView, View.OnClickListener {
    EditText loginMobile;
    EditText loginPwd;
    Button login;
    Button reg;
    private LoginPresenter presenter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
        presenter = new LoginPresenter(this, this);
    }

    private void initView() {
        login = (Button) findViewById(R.id.login);
        reg = (Button) findViewById(R.id.reg);
        loginMobile = (EditText) findViewById(R.id.login_mobile);
        loginPwd = (EditText) findViewById(R.id.login_pwd);
        reg.setOnClickListener(this);
        login.setOnClickListener(this);
    }

    /**
     * 点击事件
     * @param view
     */
    @Override
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.reg:
                goToRegist();
                break;
            case R.id.login:
                presenter.Loogin();
                break;
        }
    }

    /**
     * 跳转到注册页面
     */
    private void goToRegist() {
        Intent intent = new Intent(this, RegistActivity.class);
        startActivity(intent);
    }

    /**
     * 获取输入的手机号
     * @return
     */
    @Override
    public String getMobile() {
        return loginMobile.getText().toString().trim();
    }

    /**
     * 获取输入的密码
     * @return
     */
    @Override
    public String getPassword() {
        return loginPwd.getText().toString().trim();
    }

    /**
     * 跳转到商品详情页
     */
    @Override
    public void goToShopList() {
        Intent intent = new Intent(this, ShopListActivity.class);
        startActivity(intent);
    }

    /**
     * 吐丝信息
     * @param msg
     */
    @Override
    public void Show(String msg) {
        Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
    }

    /**
     * 防止内存泄露
     */
    @Override
    protected void onDestroy() {
        super.onDestroy();
        presenter.detach();
    }
}
登陆的view

public interface LoginView {
    String getMobile();
    String getPassword();
    void goToShopList();
    void Show(String msg);
}
登陆的model

public class LoginModel implements LoginModelCallback {
    Handler handler = new Handler(Looper.getMainLooper());

    @Override
    public void login(String mobile, String password, final OnNetListener<LoginBean> onNetListener) {
        OkHttpUtils.getOkHttpUtils().doGet("http://" + "?mobile=" + mobile + "&password=" + password, new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {

            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                String result = response.body().string();
                Gson gson = new Gson();
                final LoginBean loginBean = gson.fromJson(result, LoginBean.class);
                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        onNetListener.onSuccess(loginBean);
                    }
                });
            }
        });
    }
}

public interface LoginModelCallback {
    void login(String mobile, String password, OnNetListener<LoginBean> onNetListener);
}
登陆的presenter

public class LoginPresenter {
    private LoginModel loginModel;
    private LoginView view;
    private Context context;
    public LoginPresenter(LoginView view,Context context) {
        this.view = view;
        this.context = context;
        loginModel = new LoginModel();
    }
    public void Loogin(){
        //获取输入的手机号
        final String mobile = view.getMobile();
        //获取输入的密码
        final String password = view.getPassword();
        loginModel.login(mobile, password, new OnNetListener<LoginBean>() {
            @Override
            public void onSuccess(LoginBean loginBean) {
               //校验手机号,请往下看
                boolean ismobile = isMobile(mobile);
                /**
                 * 实现手机号和验证码本地校验功能(包括空判断、手机号码采用正则表达式校验,符合手机号码规范、密码不能少于6位数
                 */
                if(ismobile && !TextUtils.isEmpty(mobile) && !TextUtils.isEmpty(password) && password.length()>=6){
                    //吐丝登陆成功信息
                    view.Show(loginBean.getMsg());
                    //跳转到登录界面
                    view.goToShopList();
                }else{
                    //土司不合法信息
                    Toast.makeText(context,loginBean.getMsg(),Toast.LENGTH_SHORT).show();
                    return;
                }
            }
            @Override
            public void onFailure(Exception e) {

            }
        });
    }

    /**
     * 防止内存泄露
     */
    public void detach(){
        this.view = null;
    }

    /**
     * 校验手机号
     */
    public static boolean isMobile(String number) {
    /*
    移动:134135136137138139150151157(TD)158159187188
    联通:130131132152155156185186
    电信:133153180189、(1349卫通)
    总结起来就是第一位必定为1,第二位必定为358,其他位置的可以为0-9
    */
        String num = "[1][358]\\d{9}";//"[1]"代表第1位为数字1"[358]"代表第二位可以为358中的一个,"\\d{9}"代表后面是可以是09的数字,有9位。
        if (TextUtils.isEmpty(number)) {
            return false;
        } else {
            //matches():字符串是否在给定的正则表达式匹配
            return number.matches(num);
        }
    }
}
注册的Activity

public class RegistActivity extends AppCompatActivity implements RegistView{

    @BindView(R.id.reg_mobile)
    EditText regMobile;
    @BindView(R.id.reg_pwd)
    EditText regPwd;
    @BindView(R.id.btn_reg)
    Button btnReg;
    private RegistPresenter presenter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_regist);
        ButterKnife.bind(this);
        presenter = new RegistPresenter(this,this);

    }

    /**
     * 注册
     */
    @OnClick(R.id.btn_reg)
    public void onViewClicked() {
        presenter.regist();
    }

    @Override
    public String getMobile() {
        return regMobile.getText().toString().trim();
    }

    @Override
    public String getPassword() {
        return regPwd.getText().toString().trim();
    }
    /**
     *  跳转
     */
    @Override
    public void goToLogin() {
           Intent intent = new Intent(this, MainActivity.class);
           startActivity(intent);
    }

    @Override
    public void Show(String msg) {
        Toast.makeText(this,msg,Toast.LENGTH_SHORT).show();
    }
    /**
     * 防止内存泄露
     */
    @Override
    protected void onDestroy() {
        super.onDestroy();
        presenter.detach();
    }
}
注册的view接口

public interface RegistView {
    String getMobile();
    String getPassword();
    void goToLogin();
    void Show(String msg);
}
注册的model

public class RegistModel implements RegistModelCallback{
    Handler handler = new Handler(Looper.getMainLooper());
    @Override
    public void regist(String mobile, String password, final OnNetListener<RegistBean> onNetListener) {
        OkHttpUtils.getOkHttpUtils().doGet("http://120" + "?mobile=" + mobile + "&password=" + password, new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {

            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                 String result = response.body().string();
                Gson gson=new Gson();
                final RegistBean registBean = gson.fromJson(result, RegistBean.class);
                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        onNetListener.onSuccess(registBean);
                    }
                });
            }
        });
    }
}
public interface RegistModelCallback {
    void regist(String mobile, String password, OnNetListener<RegistBean> onNetListener);
}
注册的presenter

public class RegistPresenter {
    Context context;
    private RegistView registView;
    private RegistModel registModel;

    public RegistPresenter(RegistView registView, Context context) {
        this.registView = registView;
        this.context = context;
        registModel = new RegistModel();
    }

    public void regist() {
        final String mobile = registView.getMobile();
        final String password = registView.getPassword();
        registModel.regist(mobile, password, new OnNetListener<RegistBean>() {
            @Override
            public void onSuccess(RegistBean registBean) {

                boolean ismobile = isMobile(mobile);
                /**
                 * 实现手机号和验证码本地校验功能(包括空判断、手机号码采用正则表达式校验,符合手机号码规范、密码不能少于6位数
                 */
                if(ismobile && !TextUtils.isEmpty(mobile) && !TextUtils.isEmpty(password) && password.length()>=6){
                    registView.goToLogin();
                    registView.Show(registBean.getMsg());
                }else{
                    Toast.makeText(context,registBean.getMsg(),Toast.LENGTH_SHORT).show();
                    return;
                 }
            }
            @Override
            public void onFailure(Exception e) {

            }
        });
    }

    /**
     * 防止内存泄露
     */
    public void detach() {
        this.registView = null;
    }
    /**
     * 校验手机号
     * @param number
     * @return
     */
    public static boolean isMobile(String number) {
    /*
    移动:134135136137138139150151157(TD)158159187188
    联通:130131132152155156185186
    电信:133153180189、(1349卫通)
    总结起来就是第一位必定为1,第二位必定为358,其他位置的可以为0-9
    */
        String num = "[1][358]\\d{9}";//"[1]"代表第1位为数字1"[358]"代表第二位可以为358中的一个,"\\d{9}"代表后面是可以是09的数字,有9位。
        if (TextUtils.isEmpty(number)) {
            return false;
        } else {
            //matches():字符串是否在给定的正则表达式匹配
            return number.matches(num);
        }
    }
}
商品列表的Activity

public class ShopListActivity extends AppCompatActivity implements ShopListView{

    private RecyclerView recyclerView;
    List<ShopListBean.DataBean> list=new ArrayList<>();
    private ShopPresenter presenter;
    private MyAdapter adapter;
    private SpringView spring;
    int num=1;//默认页数唯一
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_shop_list);
        presenter = new ShopPresenter(this);
        presenter.getData("1");

        recyclerView = (RecyclerView) findViewById(R.id.recycler);
        spring = (SpringView) findViewById(R.id.spring);
        //设置布局管理器
        recyclerView.setLayoutManager(new LinearLayoutManager(this));
        //设置适配器
        adapter = new MyAdapter(this,list);
        recyclerView.setAdapter(adapter);
        //RecyclerView设置分割线
        recyclerView.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL));
        /**
         * 设置头部样式
         */
        spring.setHeader(new DefaultHeader(this));
        /**
         * 设置底部样式
         */
        spring.setFooter(new DefaultFooter(this));
        /**
         * 上拉刷新、下拉加载
         */
        spring.setListener(new SpringView.OnFreshListener() {
            @Override
            public void onRefresh() {
                presenter.getData("1");
                spring.onFinishFreshAndLoad();
            }

            @Override
            public void onLoadmore() {
                num++;
                final String page=String.valueOf(num);
                presenter.getData(page);
                Toast.makeText(ShopListActivity.this,page,Toast.LENGTH_SHORT).show();
                spring.onFinishFreshAndLoad();

            }
        });
    }

    /**
     * 将数据加入集合
     * @param bean
     */
    @Override
    public void show(ShopListBean bean) {
        list.addAll(bean.getData());
        adapter.notifyDataSetChanged();

    }

    /**
     * 防止内存泄露
     */
    @Override
    protected void onDestroy() {
        super.onDestroy();
        presenter.detach();
    }
}
商品列表的view

public interface ShopListView {
    void show(ShopListBean bean);
}
商品列表的model

public class ShopModel implements ShopModelCallback {
    Handler handler = new Handler(Looper.getMainLooper());
    @Override
    public void getData(String page,final OnNetListener<ShopListBean> onNetListener) {
        OkHttpUtils.getOkHttpUtils().doGet("http://12?pscid=39&page="+page, new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {

            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                String result = response.body().string();
                Gson gson=new Gson();
                final ShopListBean shopListBean = gson.fromJson(result, ShopListBean.class);
                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        onNetListener.onSuccess(shopListBean);
                    }
                });
            }
        });
    }
}
public interface ShopModelCallback {
    void getData(String page, OnNetListener<ShopListBean> onNetListener);
}
商品列表的presenter

public class ShopPresenter {
    private ShopListView view;
    private ShopModel model;

    public ShopPresenter(ShopListView view) {
        this.view = view;
        model = new ShopModel();
    }

    public void getData(String page) {
        model.getData(page, new OnNetListener<ShopListBean>() {
            @Override
            public void onSuccess(ShopListBean bean) {
                view.show(bean);
            }

            @Override
            public void onFailure(Exception e) {

            }
        });
    }

    public void detach() {
        this.view = null;
    }
}
RecyclerView的适配器

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {
    Context context;
    List<ShopListBean.DataBean> list;

    public MyAdapter(Context context, List<ShopListBean.DataBean> list) {
        this.context = context;
        this.list = list;
    }

    @Override
    public MyAdapter.MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View inflate = LayoutInflater.from(context).inflate(R.layout.item_layout, null);
        return new MyViewHolder(inflate);
    }

    @Override
    public void onBindViewHolder(MyAdapter.MyViewHolder holder, int position) {
        String[] url = list.get(position).getImages().split("\\|");
        ImageLoader.getInstance().displayImage(url[0], holder.iv);
        holder.title.setText(list.get(position).getTitle());
        holder.newPrice.setText("" + list.get(position).getBargainPrice() + "");
        holder.oldPrice.setText("" + list.get(position).getPrice() + "");
        holder.oldPrice.getPaint().setFlags(Paint.STRIKE_THRU_TEXT_FLAG); //中间横线
    }

    @Override
    public int getItemCount() {
        return list == null ? 0 : list.size();
    }

    class MyViewHolder extends RecyclerView.ViewHolder {

        private final TextView title;
        private final TextView newPrice;
        private final TextView oldPrice;
        private final ImageView iv;

        public MyViewHolder(View itemView) {
            super(itemView);
            title = itemView.findViewById(R.id.tv_lv_title);
            newPrice = itemView.findViewById(R.id.tv_lv_new_price);
            oldPrice = itemView.findViewById(R.id.tv_lv_old_price);
            iv = itemView.findViewById(R.id.iv_lv);

        }
    }
}
OKhttp封装

public class OkHttpUtils {
    private static OkHttpUtils okHttpUtils;
    private final OkHttpClient client;
    //打印log的类,OKhttp里有依赖
    private static HttpLoggingInterceptor logging;
    private OkHttpUtils() {
        logging = new HttpLoggingInterceptor();
        logging.setLevel(HttpLoggingInterceptor.Level.BODY);
        client = new OkHttpClient.Builder().addInterceptor(logging).build();
    }

    public static OkHttpUtils getOkHttpUtils() {
        if (okHttpUtils == null) {
            synchronized (OkHttpUtils.class) {
                if (okHttpUtils == null) {
                    okHttpUtils = new OkHttpUtils();
                }
            }
        }
        return okHttpUtils;
    }

    /**
     * GET请求
     *
     * @param url
     * @param callback
     */
    public void doGet(String url, Callback callback) {
        Request request = new Request.Builder().url(url).build();
        client.newCall(request).enqueue(callback);
    }

    /**
     * POST请求
     */
    public void doPost(String url, Map<String, String> params, Callback callback) {
        if (params == null) {
            throw new RuntimeException("参数为空了");
        }
        FormBody.Builder builder = new FormBody.Builder();
        for (Map.Entry<String, String> entry : params.entrySet()) {
            builder.add(entry.getKey(), entry.getValue());
        }
        FormBody formBody = builder.build();
        Request request = new Request.Builder().url(url).post(formBody).build();
        client.newCall(request).enqueue(callback);
    }
}
public interface OnNetListener<T> {
     void onSuccess(T t);

     void onFailure(Exception e);
}
ImageLoder初始化

public class APP extends Application{
    @Override
    public void onCreate() {
        super.onCreate();
        ImageLoaderConfiguration configuration = new ImageLoaderConfiguration.Builder(this).build();
        ImageLoader.getInstance().init(configuration);
    }
}

Logo

这里是“一人公司”的成长家园。我们提供从产品曝光、技术变现到法律财税的全栈内容,并连接云服务、办公空间等稀缺资源,助你专注创造,无忧运营。

更多推荐