Tinder
登录/注册模块
- shape实现渐变背景
<!--res/drawable/bg_register.xml 创建shape文件-->
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<gradient
android:angle="90" <!--渐变角度:垂直-->
android:endColor="@color/c1"
android:startColor="@color/colorAccent"></gradient>
</shape>
<!--res\layout\activity_register.xml 在布局文件中修改背景-->
android:background="@drawable/bg_register"
<!--清单文件 application 修改主题-->
android:theme="@style/Theme.AppCompat.NoActionBar"
- shape/自定义控件实现圆角UI
//导入包,注意版本号与项目一致
implementation 'com.android.support:design:29.0.0'
implementation "com.android.support:cardview-v7:29.0.0"
<!--头像圆角:设置CardView属性实现圆角-->
app:cardCornerRadius="@dimen/d10"
<!--输入框圆角:shape背景-->
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@android:color/white" />
<corners
android:bottomLeftRadius="25dp"
android:bottomRightRadius="25dp"
android:topLeftRadius="25dp"
android:topRightRadius="25dp"/>
</shape>
<!--按钮圆角背景实现类似-->
//在Activity的onCreate中修改状态栏颜色
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
Window window = getWindow();
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
window.setStatusBarColor(Color.TRANSPARENT);//状态栏透明
View view = window.getDecorView();
view.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
}
- 选择头像/输入框监听/登录注册业务
//选择头像
private void selectPhoto() {
Intent intent = new Intent(Intent.ACTION_PICK);
intent.setDataAndType(MediaStore.Images.Media.INTERNAL_CONTENT_URI, "image/*");
startActivityForResult(intent, 100);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
if (requestCode == 100) {
if (resultCode == RESULT_OK) {
Uri data1 = data.getData();
ivPhoto.setImageURI(data1);
// getmPersenter().uploadImage(Utils.getDataUrl(this, data1));
}
}
}
//输入框监听
public class RegisterActivity implements View.OnClickListener, TextWatcher {
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void afterTextChanged(Editable editable) {
name = getEditText(etName);
email = getEditText(etEmail);
pass = getEditText(etPass);
if (name.length() > 0 && email.length() > 0 && pass.length() >= 6) {
btRegister.setBackgroundResource(R.drawable.bg_btn_register);
} else {
btRegister.setBackgroundResource(R.drawable.bg_bt_register_not);
}
}
}
//跳转
public void startIntnet(Class<?> cls) {
Intent intent = new Intent();
intent.setClass(this, cls);
startActivity(intent);
}
//清单文件中修改启动模式
<activity
android:name=".ui.user.LoginActivity"
android:launchMode="singleTask" />
<activity
android:name=".ui.user.RegisterActivity"
android:launchMode="singleTask"
android:windowSoftInputMode="adjustPan|stateHidden" />
- mvp
//数据父类class BaseModel<T>
public class BaseModel<T> {
private int code;
private String message;
private T data;
-
-
-
}
//interface BaseView<T>
public interface BaseView<T> {
void setData(T data,String action);
void error(String e);
}
//管理者 class BasePersenter<V extends BaseView>
public class BasePersenter<V extends BaseView> {
private V mBaseView;
public void bindView(V view) {
if (view != null) {
this.mBaseView = view;
}
}
public void unBindView() {
mBaseView = null;
}
public V getmBaseView() {
return mBaseView;
}
}
********
public abstract class BaseActivity<V extends BaseView, P extends BasePersenter>
extends AppCompatActivity implements BaseView {
private P mPersenter;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(getLayoutId());
if (mPersenter == null) {
mPersenter = createPersenter();
mPersenter.bindView(this);
}
initView();
initData();
}
public abstract P createPersenter();
public P getmPersenter() {
return mPersenter;
}
public abstract int getLayoutId();
public abstract void initView();
public abstract void initData();
}
public class MainActivity extends BaseActivity<MainView, MainPersenter> implements MainView, View.OnClickListener
public class MainModel
public interface MainView extends BaseView
public class MainPersenter extends BasePersenter<MainView>
- 网络请求
//网络请求库
implementation 'com.squareup.okhttp3:okhttp:3.10.0'
implementation 'com.squareup.retrofit2:retrofit:2.3.0'
implementation 'com.squareup.retrofit2:adapter-rxjava2:2.3.0'
implementation 'com.squareup.retrofit2:converter-gson:2.3.0'
implementation 'com.squareup.okhttp3:logging-interceptor:3.7.0'
implementation 'io.reactivex.rxjava2:rxjava:2.1.1'
implementation 'io.reactivex.rxjava2:rxandroid:2.0.1'
//网络请求工具类
public class HttpUtils {
private static OkHttpClient okHttpClient;
/**
* 生产环境
*/
private static final String BASE_URL = "http://101.132.114.122:8099/";
/**
* 测试环境
*/
private static final String BASE_URL_TEST = "http://101.132.114.122:8099/";
public static String isTest(boolean isTest) {
if (isTest) {
return BASE_URL_TEST;
} else {
return BASE_URL;
}
}
public static <T> T createApi(Class<T> tClass) {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(isTest(true))
.client(getClient())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.build();
return retrofit.create(tClass);
}
private static synchronized OkHttpClient getClient() {
if (okHttpClient == null) {
okHttpClient = new OkHttpClient.Builder()
.retryOnConnectionFailure(true)
.readTimeout(20, TimeUnit.SECONDS)
.connectTimeout(20, TimeUnit.SECONDS)
.addInterceptor(getInterceptor())
.build();
}
return okHttpClient;
}
/**
* 拦截器
*
* @return
*/
private static Interceptor getInterceptor() {
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(
message -> Log.e("http:=====>", message)
);
return interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
}
public static <T> void sendHttp(Observable<T> observable, final ResponseListenter<T> listenter) {
observable.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<T>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(T t) {
if (listenter != null) {
listenter.onSccess(t);
}
}
@Override
public void onError(Throwable e) {
Log.e("tag", "=========>" + e);
if (listenter != null) {
listenter.onFail(e.getMessage());
}
}
@Override
public void onComplete() {
}
});
}
}
//监听器
public interface ResponseListenter<T> {
void onSccess(T data);
void onFail(String e);
}
//API管理类
public interface ApiService {
@FormUrlEncoded
@POST("/user/register")
Observable<BaseModel<RegisterModel>> getRegister(@Field("user_type") int userType,
@Field("photo") String photo,
@Field("name") String name,
@Field("email") String email,
@Field("password") String pass);
@FormUrlEncoded
@POST("/user/login")
Observable<BaseModel<LoginModel>> getLogin(@Field("user_type") int userType,
@Field("email") String email,
@Field("password") String pass);
@GET("/user/public_user_list")
Observable<BaseModel<List<MainModel>>> getPublicList(
@Query("token") String token,
@Query("page") int page,
@Query("pageSize") int pageSize);
---
---
---
}
//使用
/**
* 发起注册
*/
public void sendRegister(String photo, String name, String email, String pass) {
HttpUtils.sendHttp(HttpUtils.createApi(ApiService.class)
.getRegister(1, photo, name, email, pass),
new ResponseListenter<BaseModel<RegisterModel>>() {
@Override
public void onSccess(BaseModel<RegisterModel> data) {
if (!Utils.isEmpty(data)) {
if (data.getCode() == 200) {
RegisterModel model = data.getData();
if (getmBaseView() != null) {
getmBaseView().setData(model.getToken(), SEND_REGISTER);
}
}
}
}
@Override
public void onFail(String e) {
if (getmBaseView() != null) {
getmBaseView().error(e);
}
}
});
}
//Activity:
@Override
public void setData(Object data, String action) {
if (action.equals(UPLOAD_IMAGE)) {
photo = (String) data;
return;
}
if (data != null) {
String token = (String) data;
SharedPreferencesUtils.saveToken(this, "token", token);
startIntnet(MainActivity.class, true);
}
}
@Override
public void error(String e) {
Log.e("error", "" + e);
}