MVP登录注册、跳转
这是一个用MVP模式写的登录注册,包括手机号、密码验证,登陆成功后跳转到商品列表页面。先看一下效果:正如我们看到的一样,在登陆界面点击注册会跳转到注册页面,注册成功后会跳转到登录界面,登录成功后会跳转到商品列表界面。在登录注册的过程中手机号和密码使用正则表达式进行了验证,使用OKhttp请求的网络,RecyclerView展示的数据,Springview执行上拉刷新和下拉加载。下面
·
这是一个用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) { /* 移动:134、135、136、137、138、139、150、151、157(TD)、158、159、187、188 联通:130、131、132、152、155、156、185、186 电信:133、153、180、189、(1349卫通) 总结起来就是第一位必定为1,第二位必定为3或5或8,其他位置的可以为0-9 */ String num = "[1][358]\\d{9}";//"[1]"代表第1位为数字1,"[358]"代表第二位可以为3、5、8中的一个,"\\d{9}"代表后面是可以是0~9的数字,有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) { /* 移动:134、135、136、137、138、139、150、151、157(TD)、158、159、187、188 联通:130、131、132、152、155、156、185、186 电信:133、153、180、189、(1349卫通) 总结起来就是第一位必定为1,第二位必定为3或5或8,其他位置的可以为0-9 */ String num = "[1][358]\\d{9}";//"[1]"代表第1位为数字1,"[358]"代表第二位可以为3、5、8中的一个,"\\d{9}"代表后面是可以是0~9的数字,有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); } }
更多推荐



所有评论(0)