所需要的各种依赖:
compile 'io.reactivex.rxjava2:rxjava:2.0.7' compile 'io.reactivex.rxjava2:rxandroid:2.0.1' compile 'com.squareup.retrofit2:retrofit:2.1.0' compile 'com.squareup.retrofit2:adapter-rxjava2:2.2.0' compile 'com.squareup.retrofit2:converter-gson:2.1.0' compile 'com.squareup.retrofit2:converter-scalars:2.1.0' compile 'com.jakewharton:butterknife:8.8.1' compile 'com.android.support:recyclerview-v7:26.0.0-alpha1' compile 'com.nostra13.universalimageloader:universal-image-loader:1.9.5' compile 'com.facebook.fresco:fresco:0.12.0' compile 'com.github.bumptech.glide:glide:3.7.0' compile 'org.greenrobot:eventbus:3.1.1' compile 'com.android.support:design:26.0.0-alpha1' annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'retrofit封装:ApiService、BaseObserver、RetrofitManager
public interface ApiService { @GET Observable<String> get(@Url String url, @QueryMap Map<String, String> map); @FormUrlEncoded @POST Observable<String> post(@Url String url, @FieldMap Map<String, String> map); }
public abstract class BaseObserver<T> implements Observer<String> { @Override public void onSubscribe(Disposable d) { } @Override public void onNext(String s) { try { Type genType = getClass().getGenericSuperclass(); Type[] params = ((ParameterizedType) genType).getActualTypeArguments(); Class entityClass = (Class) params[0]; Gson gson = new Gson(); T t = (T) gson.fromJson(s, entityClass); success(t); } catch (Exception e) { failure(1001); e.printStackTrace(); } } @Override public void onError(Throwable e) { try { if (e != null) { if (e instanceof HttpException) { failure(HTTP_ERROR); } else if (e instanceof SocketException) { failure(NET_WORK_ERROR); } else { failure(UNKNOW_ERROR); } } else { failure(UNKNOW_ERROR); } e.printStackTrace(); } catch (Exception e1) { failure(UNKNOW_ERROR); e1.printStackTrace(); } } @Override public void onComplete() { } // /** * code * 1000 UNKNOW_ERROR 未知错误 * 1001 json 转化异常 parse error * 1002 当前网络不可用 java.net.SocketException: Network is unreachable 超时 * 1003 服务器不可用 401 402 403 500 502 503 504 * * @param code */ public static final int UNKNOW_ERROR = 1000; public static final int JSON_FORMAT_ERROR = 1001; public static final int NET_WORK_ERROR = 1002; public static final int HTTP_ERROR = 1003; public abstract void success(T t); public abstract void failure(int code); }
public class RetrofitManager { public static OkHttpClient client = new OkHttpClient.Builder() .build(); public static ApiService apiService = new Retrofit.Builder() .baseUrl("http://120.27.23.105/") .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) .addConverterFactory(ScalarsConverterFactory.create()) .client(client) .build() .create(ApiService.class); public static void get(String url, Map<String,String> map, Observer observer){ apiService.get(url,map) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(observer); } public static void post(String url,Map<String,String> map,Observer observer){ apiService.post(url,map) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(observer); } }utils工具类:App、CustomLinearLayout、LoginMD5;
public class App extends Application { @Override public void onCreate() { super.onCreate(); Fresco.initialize(this); } }
public class CustomLinearLayout extends LinearLayout { private int i=1; private EditText et; public CustomLinearLayout(Context context) { super(context); } public CustomLinearLayout(final Context context, @Nullable AttributeSet attrs) { super(context, attrs); View view = View.inflate(context, R.layout.custom_linearlayout,null); addView(view); Button jia = view.findViewById(R.id.jia); Button jian = view.findViewById(R.id.jian); et = view.findViewById(R.id.edit); et.setText("1"); jia.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { i = Integer.parseInt(et.getText().toString().trim()); i++; et.setText(i+""); if(countListener!=null){ countListener.setCount(i); } } }); jian.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { i = Integer.parseInt(et.getText().toString().trim()); if(i>1){ i--; }else{ Toast.makeText(context,"数量不能小于1",Toast.LENGTH_SHORT).show(); } et.setText(i+""); if(countListener!=null){ countListener.setCount(i); } } }); } public CustomLinearLayout(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } CountListener countListener; public void getCount(CountListener countListener){ this.countListener = countListener; } public interface CountListener{ void setCount(int i); } public void setText(String count){ et.setText(count); } }
public class LoginMD5 { /** * 对外提供getMD5(String)方法 * @author randyjia * */ public static String getMD5(String val){ MessageDigest md5 = null; try { md5 = MessageDigest.getInstance("MD5"); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } md5.update(val.getBytes()); byte[] m = md5.digest();//加密 return getString(m); } private static String getString(byte[] b){ StringBuffer sb = new StringBuffer(); for(int i = 0; i < b.length; i ++){ sb.append(b[i]); } return sb.toString(); } }ManActivity:登录页面
public class MainActivity extends AppCompatActivity implements LoginPresenter.ILoginView { private long extime=0; @BindView(R.id.et_name) EditText etName; @BindView(R.id.et_pwd) EditText etPwd; @BindView(R.id.bt_login) Button btLogin; @BindView(R.id.bt_regist) TextView btRegist; @BindView(R.id.forgetFive) TextView forgetFive; LoginPresenter loginPresenter; private String name; private String pwd; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ButterKnife.bind(this); loginPresenter=new LoginPresenter(this); } @OnClick({R.id.bt_login, R.id.bt_regist}) public void onViewClicked(View view) { switch (view.getId()) { case R.id.bt_login: name = etName.getText().toString().trim(); pwd = etPwd.getText().toString().trim(); loginPresenter.getData(name, pwd); break; case R.id.bt_regist: startActivity(new Intent(MainActivity.this,RegisterActivity.class)); break; } } @Override public void success(String s) { if("登录成功".equals(s)){ LoginMD5.getMD5(name); Toast.makeText(MainActivity.this,s,Toast.LENGTH_SHORT).show(); //跳转到列表页面 Intent intent = new Intent(MainActivity.this, LieBiaoActivity.class); startActivity(intent); }else{ Toast.makeText(MainActivity.this,s,Toast.LENGTH_SHORT).show(); } } @Override public void failed(String s) { Toast.makeText(MainActivity.this,s,Toast.LENGTH_SHORT).show(); } @Override public void getname(String s) { Toast.makeText(MainActivity.this,s,Toast.LENGTH_SHORT).show(); } @Override public void getpwd(String s) { Toast.makeText(MainActivity.this,s,Toast.LENGTH_SHORT).show(); } //销毁防止内存泄漏 @Override protected void onDestroy() { super.onDestroy(); loginPresenter.detach(); } public boolean onKeyDown(int keyCode, KeyEvent event){ if(keyCode== KeyEvent.KEYCODE_BACK){ exit(); return false; } return super.onKeyDown(keyCode,event); } public void exit(){ if((System.currentTimeMillis()-extime>2000)){ Toast.makeText(getApplicationContext(), "再按一次退出程序", Toast.LENGTH_SHORT).show(); extime=System.currentTimeMillis(); }else{ finish(); System.exit(0); } } }activity_main:布局文件
<RelativeLayout android:layout_width="match_parent" android:layout_height="50dp"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:text="淘宝登录" android:textColor="#000" android:textSize="20sp" /> </RelativeLayout> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:layout_marginTop="60dp" android:orientation="horizontal"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="账号" android:textSize="20sp" /> <EditText android:id="@+id/et_name" android:layout_width="250dp" android:layout_height="wrap_content" android:layout_marginRight="20dp" android:hint="请输入你的账号" /> </LinearLayout> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:orientation="horizontal"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="密码" android:textSize="20sp" /> <EditText android:id="@+id/et_pwd" android:layout_width="250dp" android:layout_height="wrap_content" android:layout_marginRight="20dp" android:hint="请输入你的密码" android:inputType="textPassword" /> </LinearLayout> <Button android:id="@+id/bt_login" android:layout_width="350dp" android:layout_height="50sp" android:layout_gravity="center_horizontal" android:layout_marginTop="30dp" android:background="@drawable/shape_activity" android:text="登录" android:textColor="#888888" android:textSize="20sp" /> <RelativeLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="10dp" android:orientation="horizontal"> <TextView android:id="@+id/bt_regist" android:layout_width="wrap_content" android:layout_height="wrap_content" android:padding="10dp" android:text="注册账号" /> <TextView android:id="@+id/forgetFive" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:padding="10dp" android:text="忘记密码" /> </RelativeLayout>Model层:LoginModel
public class LoginModel { //登录的数据 public void getData(String name, String pwd, final ILoginModel iLoginModel){ Map<String,String> map=new HashMap<>(); map.put("mobile",name); map.put("password",pwd); RetrofitManager.get("user/login",map, new BaseObserver<LoginBean>() { @Override public void success(LoginBean loginBean) { if(iLoginModel!=null){ iLoginModel.success(loginBean); } } @Override public void failure(int code) { } }); }
public interface ILoginModel { void success(LoginBean loginBean); } }Presenter层,LoginPresenter
public class LoginPresenter { ILoginView iLoginView; LoginModel loginModel; public LoginPresenter(ILoginView iLoginView) { this.iLoginView = iLoginView; loginModel=new LoginModel(); } public void getData(String name,String pwd){ //判断用户名为空 if(TextUtils.isEmpty(name)){ if(iLoginView!=null){ iLoginView.getname("用户名不能为空"); return; } } //判断密码是否为空 if(TextUtils.isEmpty(pwd)){ if(iLoginView!=null){ iLoginView.getpwd("密码不能为空"); } } //调用M层数据 loginModel.getData(name, pwd, new LoginModel.ILoginModel() { @Override public void success(LoginBean loginBean) { if(iLoginView!=null){ iLoginView.success(loginBean.getMsg()); } } }); } //内存泄漏 解绑 public void detach(){ iLoginView=null; } public interface ILoginView { void success(String s); void failed(String s); void getname(String s); void getpwd(String s); } }RegisterActivity:注册的页面
public class RegisterActivity extends AppCompatActivity implements RegistPrestener.IRegistView { @BindView(R.id.name) EditText name; @BindView(R.id.pwd) EditText pwd; @BindView(R.id.mpwd) EditText mpwd; @BindView(R.id.email) EditText email; @BindView(R.id.regist) Button regist; private RegistPrestener registPrestener; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_register); ButterKnife.bind(this); registPrestener=new RegistPrestener(this); } @Override public void success(String s) { if(("注册成功").equals(s)){ Toast.makeText(RegisterActivity.this, s, Toast.LENGTH_SHORT).show(); finish(); }else{ Toast.makeText(RegisterActivity.this, s, Toast.LENGTH_SHORT).show(); } } @Override public void failed(String s) { Toast.makeText(RegisterActivity.this, s, Toast.LENGTH_SHORT).show(); } @Override public void getname(String s) { Toast.makeText(RegisterActivity.this, s, Toast.LENGTH_SHORT).show(); } @Override public void getpwd(String s) { Toast.makeText(RegisterActivity.this, s, Toast.LENGTH_SHORT).show(); } @Override public void email(String s) { Toast.makeText(RegisterActivity.this, s, Toast.LENGTH_SHORT).show(); } @Override public void confrim(String s) { Toast.makeText(RegisterActivity.this, s, Toast.LENGTH_SHORT).show(); } //防止内存泄漏 @Override protected void onDestroy() { super.onDestroy(); registPrestener.detach(); } }register_main:注册的布局文件
<RelativeLayout android:layout_width="match_parent" android:layout_height="50dp"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:text="淘宝注册" android:textColor="#000" android:textSize="20sp" /> </RelativeLayout> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:layout_marginTop="60dp" android:orientation="horizontal"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="账号" android:textSize="20sp" /> <EditText android:id="@+id/name" android:layout_width="250dp" android:layout_height="wrap_content" android:layout_marginRight="20dp" android:hint="请输入你的账号" /> </LinearLayout> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:orientation="horizontal"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="密码" android:textSize="20sp" /> <EditText android:id="@+id/pwd" android:layout_width="250dp" android:layout_height="wrap_content" android:layout_marginRight="20dp" android:hint="请输入你的密码" /> </LinearLayout> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:orientation="horizontal"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="确认密码" android:textSize="20sp" /> <EditText android:id="@+id/mpwd" android:layout_width="250dp" android:layout_height="wrap_content" android:layout_marginRight="20dp" android:hint="请再次输入你的密码" /> </LinearLayout> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:orientation="horizontal"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="邮箱" android:textSize="20sp" /> <EditText android:id="@+id/email" android:layout_width="250dp" android:layout_height="wrap_content" android:layout_marginRight="20dp" android:hint="请输入你的邮箱" /> </LinearLayout> <Button android:id="@+id/regist" android:layout_width="350dp" android:layout_height="50sp" android:layout_gravity="center_horizontal" android:layout_marginTop="30dp" android:background="@drawable/shape_activity" android:text="注册" android:textColor="#888888" android:textSize="20sp" />Model层:RegisterModel
public class RegistModel { //注册的数据 public void getData(String name, String pwd, final IRgistModel iRgistModel){ Map<String ,String> map=new HashMap<>(); map.put("mobile",name); map.put("password",pwd); RetrofitManager.get("user/reg",map, new BaseObserver<RegisterBean>() { @Override public void success(RegisterBean registerBean) { if(iRgistModel!=null){ iRgistModel.success(registerBean); } } @Override public void failure(int code) { } }); }
public interface IRgistModel{ void success(RegisterBean registerBean); } }Presenter:RegisterPresenter
public class RegistPrestener { IRegistView iRegistView; RegistModel registModel; public RegistPrestener(IRegistView iRegistView) { this.iRegistView = iRegistView; registModel=new RegistModel(); } public void getData(String name,String pwd,String mpwd,String email){ //判断用户名不能为空 if(TextUtils.isEmpty(name)){ if(iRegistView!=null){ iRegistView.getname("用户名不能为空"); return; } } //判断密码不能为空 if(TextUtils.isEmpty(pwd)){ if(iRegistView!=null){ iRegistView.getpwd("密码不能为空"); return; } //判断输入二次密码 if(TextUtils.isEmpty(mpwd)){ if(iRegistView!=null){ iRegistView.confrim("确认密码不能为空"); return; } if(!mpwd.equals(pwd)){ if(iRegistView!=null){ iRegistView.confrim("两次密码不一样"); return; } } } boolean email1=isEmail(email); if(!email1){ if(iRegistView!=null){ iRegistView.email("邮箱格式不正确"); return; } } }; //调用m层数据 registModel.getData(name,pwd, new RegistModel.IRgistModel() { @Override public void success(RegisterBean registerBean) { if(iRegistView!=null){ iRegistView.success(registerBean.getMsg()); } } }); } //防止内存泄漏 public void detach(){ iRegistView=null; } //邮箱 public boolean isEmail(String email){ String str = "^([a-zA-Z0-9_\\-\\.]+)@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.)|(([a-zA-Z0-9\\-]+\\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\\]?)$"; Pattern p = Pattern.compile(str); Matcher m = p.matcher(email); return m.matches(); } public interface IRegistView { void success(String s); void failed(String s); void getname(String s); void getpwd(String s); void email(String s); void confrim(String s); } }LieBiaoActivity:列表的页面
public class LieBiaoActivity extends AppCompatActivity implements LieBiaoPrestener.ILiebiaoView{ @BindView(R.id.rv) RecyclerView rv; private LieBiaoPrestener lieBiaoPrestener; private LieBiaoAdapter lieBiaoAdapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_lie_biao); ButterKnife.bind(this); lieBiaoPrestener=new LieBiaoPrestener(this); lieBiaoPrestener.getdata(); } @Override public void success(List<DataDataBean.DataBean> dataBeans) { rv.setLayoutManager(new LinearLayoutManager(this)); lieBiaoAdapter = new LieBiaoAdapter(LieBiaoActivity.this, dataBeans); rv.setAdapter(lieBiaoAdapter); } //销毁防止内存泄漏 @Override protected void onDestroy() { super.onDestroy(); lieBiaoPrestener.detach(); } }
lie_biao_activity:
<android.support.v7.widget.RecyclerView android:id="@+id/rv" android:layout_width="match_parent" android:layout_height="match_parent"></android.support.v7.widget.RecyclerView>
Model层:LieBiaoModel
public class LieBiaoModel { //列表的数据 public void getData(final ILiebiaoModel iLiebiaoModel){ Map<String ,String> map=new HashMap<>(); map.put("pscid","1"); map.put("page","1"); map.put("source","android"); RetrofitManager.get("product/getProducts",map, new BaseObserver<DataDataBean>() { @Override public void success(DataDataBean dataDataBean) { if(iLiebiaoModel!=null){ iLiebiaoModel.success(dataDataBean); } } @Override public void failure(int code) { } }); }
public interface ILiebiaoModel{ void success(DataDataBean dataDataBean); } }Presenter:LieBiaoPresenter
public class LieBiaoPrestener { LieBiaoModel lieBiaoModel; ILiebiaoView iLiebiaoView; public LieBiaoPrestener(ILiebiaoView iLiebiaoView) { this.iLiebiaoView = iLiebiaoView; lieBiaoModel=new LieBiaoModel(); } //数据传到view层 public void getdata(){ lieBiaoModel.getData(new LieBiaoModel.ILiebiaoModel() { @Override public void success(DataDataBean dataDataBean) { if(iLiebiaoView!=null){ iLiebiaoView.success(dataDataBean.getData()); } } }); } public void detach(){ iLiebiaoView=null; } public interface ILiebiaoView{ void success(List<DataDataBean.DataBean> dataBeans); } }LieBiaoAdapter:
public class LieBiaoAdapter extends RecyclerView.Adapter { private Context context; private List<DataDataBean.DataBean> dataDataBean; private static final int MAX_HEAP_SIZE = (int) Runtime.getRuntime().maxMemory(); public static final int MAX_DISK_CACHE_SIZE = 40 * ByteConstants.MB; public static final int MAX_MEMORY_CACHE_SIZE = MAX_HEAP_SIZE / 4; private static final String IMAGE_PIPELINE_CACHE_DIR = "imagepipeline_cache"; private static ImagePipelineConfig sImagePipelineConfig; private static ImagePipelineConfig sOkHttpImagePipelineConfig; public LieBiaoAdapter(Context context, List<DataDataBean.DataBean> dataDataBean) { this.context = context; this.dataDataBean = dataDataBean; } @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view=View.inflate(context, R.layout.liebiao_item,null); return new ViewHolder1(view); } @Override public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) { ViewHolder1 holder1= (ViewHolder1) holder; //设置数据 String[] split = dataDataBean.get(position).getImages().split("\\|"); holder1.imageView.setImageURI(Uri.parse(split[0])); holder1.price.setText(dataDataBean.get(position).getPrice()+""); holder1.title.setText(dataDataBean.get(position).getTitle()); //点击事件 holder1.linearLayout.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Intent intent = new Intent(context,XiangQingActivity.class); intent.putExtra("pid",dataDataBean.get(position).getPscid()+""); context.startActivity(intent); } }); } @Override public int getItemCount() { return dataDataBean.size(); } class ViewHolder1 extends RecyclerView.ViewHolder { SimpleDraweeView imageView; TextView title; TextView price; LinearLayout linearLayout; public ViewHolder1(View itemView) { super(itemView); imageView = itemView.findViewById(R.id.simpleDrawee); title = itemView.findViewById(R.id.title_t); price = itemView.findViewById(R.id.price); linearLayout = itemView.findViewById(R.id.linear); } } }
Liebiao_item:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:orientation="horizontal" android:id="@+id/linear" android:gravity="center_vertical" android:layout_height="match_parent"> <com.facebook.drawee.view.SimpleDraweeView android:layout_width="100dp" android:layout_height="100dp" android:id="@+id/simpleDrawee"/> <LinearLayout android:orientation="vertical" android:layout_width="match_parent" android:layout_height="wrap_content"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/price" android:text="价格" /> <TextView android:layout_marginTop="20dp" android:text="标题" android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/title_t" /> </LinearLayout> </LinearLayout>
custom_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:orientation="horizontal"> <Button android:layout_width="35dp" android:layout_height="35dp" android:text="-" android:id="@+id/jian" /> <EditText android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/edit" /> <Button android:text="+" android:id="@+id/jia" android:layout_width="35dp" android:layout_height="35dp" /> </LinearLayout>