修改头像,修改昵称

This commit is contained in:
BA7LZD 2020-05-27 18:31:02 +08:00
parent 8173441a3f
commit f3dfe74b42
33 changed files with 1126 additions and 102 deletions

View File

@ -57,7 +57,9 @@ dependencies {
//
implementation 'com.lzy.widget:ninegridview:0.2.0'
//sdk
implementation 'com.tencent.qcloud:cosxml:5.4.31'
implementation('com.tencent.qcloud:cosxml:5.4.31') {
exclude group: 'com.tencent.qcloud', module: 'mtaUtils' // mta
}
//
implementation 'com.sackcentury:shinebutton:1.0.0'
//

View File

@ -56,7 +56,7 @@
android:name=".gsv.SimpleDetailActivityMode2"
android:theme="@style/DetailTheme" />
<activity android:name=".comm.BaseActivity" />
<activity android:name=".ui.reg.login.RegActivity" />
<activity android:name=".ui.reg.RegActivity" />
</application>
</manifest>

View File

@ -1,6 +1,9 @@
package com.yuxihan.sdu.comm;
public class Const {
public static boolean NEED_RELOAD_PROFILE = false;
public static final String LOGIN_STATE = "LoginState";
public static final String LOGIN_TOKEN = "LoginToken";
public static final String LOGIN_USER_NAME = "LoginUserName";
@ -9,6 +12,6 @@ public class Const {
public static final int CAMERA_OK = 1;
public static final int PIC_OK = 2;
public static final String BUCKET_NAME = "a-1300518338";
}

View File

@ -11,6 +11,7 @@ import com.lzy.ninegrid.NineGridView;
import com.yuxihan.sdu.BuildConfig;
import com.yuxihan.sdu.R;
import com.yuxihan.sdu.comm.network.LoggingInterceptor;
import com.yuxihan.sdu.comm.util.UploadTencentSDK;
import java.io.IOException;
@ -24,17 +25,19 @@ import retrofit2.converter.gson.GsonConverterFactory;
public class SDUApp extends Application {
private static Retrofit mRetrofit;
private static Context appContext;
@Override
public void onCreate() {
super.onCreate();
SDUApp.appContext = getApplicationContext();
initApp();
}
private void initApp() {
initRetrofit();
initNineGrid();
UploadTencentSDK.init(getApplicationContext());
}
/**
@ -94,4 +97,8 @@ public class SDUApp extends Application {
.addConverterFactory(GsonConverterFactory.create())
.build();
}
public static Context getAppContext(){
return SDUApp.appContext;
}
}

View File

@ -0,0 +1,30 @@
package com.yuxihan.sdu.comm.network;
import com.yuxihan.sdu.comm.util.AccountUtils;
public class BaseRequestParams {
private String token;
private String userName;
public BaseRequestParams() {
this.token = AccountUtils.getCurToken();
this.userName = AccountUtils.getCurUserName();
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getToken() {
return token;
}
public void setToken(String token) {
this.token = token;
}
}

View File

@ -26,6 +26,7 @@ public class LoggingInterceptor implements Interceptor {
long t2 = System.nanoTime();
Log.i(TAG, String.format("Received response for %s in %.1fms%n%s",
response.request().url(), (t2 - t1) / 1e6d, response.headers()));
Log.i(TAG, response.toString());
return response;
}

View File

@ -39,11 +39,20 @@ public class AccountUtils {
String ret = SPUtils.getInstance().getString(Const.LOGIN_NICKNAME);
return DataUtil.isEmpty(ret) ? "" : ret;
}
public static void setCurNickname(String nickname) {
SPUtils.getInstance().put(Const.LOGIN_NICKNAME, nickname);
}
public static String getCurHeadUrl() {
String ret = SPUtils.getInstance().getString(Const.LOGIN_HEAD_URL);
return DataUtil.isEmpty(ret) ? "" : ret;
}
public static void setCurHeadUrl(String nickname) {
SPUtils.getInstance().put(Const.LOGIN_HEAD_URL, nickname);
}
public static String getCurToken() {
String ret = SPUtils.getInstance().getString(Const.LOGIN_TOKEN);
return DataUtil.isEmpty(ret) ? "" : ret;

View File

@ -0,0 +1,50 @@
package com.yuxihan.sdu.comm.util;
import android.content.Context;
import com.tencent.cos.xml.CosXmlService;
import com.tencent.cos.xml.CosXmlServiceConfig;
import com.tencent.cos.xml.transfer.TransferConfig;
import com.tencent.cos.xml.transfer.TransferManager;
import com.tencent.qcloud.core.auth.QCloudCredentialProvider;
import com.tencent.qcloud.core.auth.ShortTimeCredentialProvider;
import com.yuxihan.sdu.comm.SDUApp;
public class UploadTencentSDK {
public static TransferManager transferManager = null;
public static void init(Context appContext) {
String region = "ap-guangzhou";
// 创建 CosXmlServiceConfig 对象根据需要修改默认的配置参数
CosXmlServiceConfig serviceConfig = new CosXmlServiceConfig.Builder()
.setRegion(region)
.isHttps(true) // 使用 HTTPS 请求, 默认为 HTTP 请求
.builder();
String secretId = "AKIDwfARTHDAE4e4GE7XrwnOltlPr54rJgjW"; //永久密钥 secretId
String secretKey = "jGZfbJn34qQmuoTu75oNioeHfplSwCDy"; //永久密钥 secretKey
/**
* 初始化 {@link QCloudCredentialProvider} 对象来给 SDK 提供临时密钥
* @parma secretId 永久密钥 secretId
* @param secretKey 永久密钥 secretKey
* @param keyDuration 密钥有效期单位为秒
*/
QCloudCredentialProvider credentialProvider = new ShortTimeCredentialProvider(secretId,
secretKey, 300);
CosXmlService cosXmlService = new CosXmlService(appContext, serviceConfig,
credentialProvider);
TransferConfig transferConfig = new TransferConfig.Builder().build();
transferManager = new TransferManager(cosXmlService, transferConfig);
}
public static TransferManager getTransferManager() {
if (transferManager == null) {
UploadTencentSDK.init(SDUApp.getAppContext());
}
return transferManager;
}
}

View File

@ -0,0 +1,258 @@
package com.yuxihan.sdu.comm.widget;
import android.app.Dialog;
import android.content.Context;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import com.yuxihan.sdu.R;
/**
* description:自定义dialog
*/
public class CommonDialog extends Dialog {
private Context mContext;
/**
* 显示的图片
*/
private ImageView imageIv;
/**
* 显示的标题
*/
private TextView titleTv;
/**
* 显示的消息
*/
private TextView messageTv;
private EditText etContent;
/**
* 确认和取消按钮
*/
private Button negativeBn, positiveBn;
/**
* 按钮之间的分割线
*/
private View columnLineView;
public CommonDialog(Context context) {
super(context, R.style.CustomDialog);
mContext = context;
}
/**
* 都是内容数据
*/
private String message;
private String title;
private String positive, negative;
private String hint;
private int imageResId = -1;
/**
* 底部是否只有一个按钮
*/
private boolean isSingle = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout_custom_dialog);
//按空白处不能取消动画
setCanceledOnTouchOutside(false);
//初始化界面控件
initView();
//初始化界面数据
refreshView();
//初始化界面控件的事件
initEvent();
}
/**
* 初始化界面的确定和取消监听器
*/
private void initEvent() {
//设置确定按钮被点击后向外界提供监听
positiveBn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (onClickBottomListener != null) {
onClickBottomListener.onPositiveClick(etContent.getText().toString());
}
}
});
//设置取消按钮被点击后向外界提供监听
negativeBn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (onClickBottomListener != null) {
onClickBottomListener.onNegativeClick();
}
}
});
}
/**
* 初始化界面控件的显示数据
*/
private void refreshView() {
//如果用户自定了title和message
if (!TextUtils.isEmpty(title)) {
titleTv.setText(title);
titleTv.setVisibility(View.VISIBLE);
} else {
titleTv.setVisibility(View.GONE);
}
if (!TextUtils.isEmpty(message)) {
messageTv.setText(message);
}
//如果设置按钮的文字
if (!TextUtils.isEmpty(positive)) {
positiveBn.setText(positive);
} else {
positiveBn.setText("确定");
}
if (!TextUtils.isEmpty(hint)) {
etContent.setHint(hint);
}
if (!TextUtils.isEmpty(negative)) {
negativeBn.setText(negative);
} else {
negativeBn.setText("取消");
}
// if (imageResId != -1) {
// imageIv.setImageResource(imageResId);
// imageIv.setVisibility(View.VISIBLE);
// } else {
// imageIv.setVisibility(View.GONE);
// }
/**
* 只显示一个按钮的时候隐藏取消按钮回掉只执行确定的事件
*/
if (isSingle) {
columnLineView.setVisibility(View.GONE);
negativeBn.setVisibility(View.GONE);
} else {
negativeBn.setVisibility(View.VISIBLE);
columnLineView.setVisibility(View.VISIBLE);
}
etContent.setFocusable(true);
etContent.setFocusableInTouchMode(true);
etContent.requestFocus();
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
}
@Override
public void show() {
super.show();
refreshView();
}
/**
* 初始化界面控件
*/
private void initView() {
negativeBn = (Button) findViewById(R.id.negative);
positiveBn = (Button) findViewById(R.id.positive);
titleTv = (TextView) findViewById(R.id.title);
messageTv = (TextView) findViewById(R.id.message);
etContent = (EditText) findViewById(R.id.et_content);
imageIv = (ImageView) findViewById(R.id.image);
columnLineView = findViewById(R.id.column_line);
}
/**
* 设置确定取消按钮的回调
*/
public OnClickBottomListener onClickBottomListener;
public CommonDialog setOnClickBottomListener(OnClickBottomListener onClickBottomListener) {
this.onClickBottomListener = onClickBottomListener;
return this;
}
public interface OnClickBottomListener {
/**
* 点击确定按钮事件
*/
public void onPositiveClick(String etContent);
/**
* 点击取消按钮事件
*/
public void onNegativeClick();
}
public String getMessage() {
return message;
}
public CommonDialog setMessage(String message) {
this.message = message;
return this;
}
public String getTitle() {
return title;
}
public CommonDialog setTitle(String title) {
this.title = title;
return this;
}
public String getPositive() {
return positive;
}
public CommonDialog setPositive(String positive) {
this.positive = positive;
return this;
}
public String getNegative() {
return negative;
}
public CommonDialog setNegative(String negative) {
this.negative = negative;
return this;
}
public CommonDialog setEtHint(String hint) {
this.hint = hint;
return this;
}
public int getImageResId() {
return imageResId;
}
public boolean isSingle() {
return isSingle;
}
public CommonDialog setSingle(boolean single) {
isSingle = single;
return this;
}
public CommonDialog setImageResId(int imageResId) {
this.imageResId = imageResId;
return this;
}
}

View File

@ -2,27 +2,38 @@ package com.yuxihan.sdu.data;
import com.yuxihan.sdu.data.model.DataBean;
import com.yuxihan.sdu.data.model.LoginParams;
import com.yuxihan.sdu.data.model.RegParams;
import com.yuxihan.sdu.data.model.UpdateNicknameParams;
import com.yuxihan.sdu.data.model.UpdateUserHeadParams;
import retrofit2.Call;
import retrofit2.http.Body;
import retrofit2.http.GET;
import retrofit2.http.POST;
import retrofit2.http.Query;
public interface UpdateService {
@POST("addUser")
Call<DataBean> addUser(
//内部是请求的参数
@Query("userName") String userName,
@Query("password") String password
Call<DataBean> reg(
@Body RegParams params
);
@POST("login")
Call<DataBean> login(
//内部是请求的参数
@Query("userName") String userName,
@Query("password") String password
@Body LoginParams params
);
@GET("hi")
Call<DataBean> hi(
);
@POST("/updateUserHead")
Call<DataBean> updateUserHead(
@Body UpdateUserHeadParams params
);
@POST("/updateName")
Call<DataBean> updateNickname(
@Body UpdateNicknameParams params
);
}

View File

@ -0,0 +1,21 @@
package com.yuxihan.sdu.data.model;
import com.yuxihan.sdu.comm.network.BaseRequestParams;
public class LoginParams extends BaseRequestParams {
private String password;
public LoginParams(String userName, String password) {
super.setUserName(userName);
this.password = password;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}

View File

@ -1,10 +1,10 @@
package com.yuxihan.sdu.data.model;
import java.util.Objects;
public class LoginRetVo {
private String token;
private String nickname;
private String userHead;
public String getToken() {
return token;
@ -14,23 +14,28 @@ public class LoginRetVo {
this.token = token;
}
public String getNickname() {
return nickname;
}
public void setNickname(String nickname) {
this.nickname = nickname;
}
public String getUserHead() {
return userHead;
}
public void setUserHead(String userHead) {
this.userHead = userHead;
}
@Override
public String toString() {
return "LoginRetVo{" +
"token='" + token + '\'' +
", nickname='" + nickname + '\'' +
", userHead='" + userHead + '\'' +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
LoginRetVo that = (LoginRetVo) o;
return Objects.equals(token, that.token);
}
@Override
public int hashCode() {
return Objects.hash(token);
}
}

View File

@ -0,0 +1,32 @@
package com.yuxihan.sdu.data.model;
import com.yuxihan.sdu.comm.network.BaseRequestParams;
public class RegParams extends BaseRequestParams {
private String password;
private String verificationCode;
public RegParams(String userName, String password,String verificationCode) {
super.setUserName(userName);
this.password = password;
this.verificationCode = verificationCode;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getVerificationCode() {
return verificationCode;
}
public void setVerificationCode(String verificationCode) {
this.verificationCode = verificationCode;
}
}

View File

@ -0,0 +1,24 @@
package com.yuxihan.sdu.data.model;
import com.yuxihan.sdu.comm.network.BaseRequestParams;
public class UpdateNicknameParams extends BaseRequestParams {
public UpdateNicknameParams(String nickname) {
this.nickname = nickname;
}
/**
* userHead : 123
*/
private String nickname;
public String getNickname() {
return nickname;
}
public void setNickname(String nickname) {
this.nickname = nickname;
}
}

View File

@ -0,0 +1,24 @@
package com.yuxihan.sdu.data.model;
import com.yuxihan.sdu.comm.network.BaseRequestParams;
public class UpdateUserHeadParams extends BaseRequestParams {
public UpdateUserHeadParams(String userHead) {
this.userHead = userHead;
}
/**
* userHead : 123
*/
private String userHead;
public String getUserHead() {
return userHead;
}
public void setUserHead(String userHead) {
this.userHead = userHead;
}
}

View File

@ -16,6 +16,7 @@ import androidx.lifecycle.ViewModelProvider;
import com.bumptech.glide.Glide;
import com.yuxihan.sdu.R;
import com.yuxihan.sdu.comm.BaseFragment;
import com.yuxihan.sdu.comm.Const;
import com.yuxihan.sdu.comm.util.AccountUtils;
import com.yuxihan.sdu.comm.util.DataUtil;
import com.yuxihan.sdu.ui.info.InfoEditActivity;
@ -26,6 +27,9 @@ import de.hdodenhof.circleimageview.CircleImageView;
public class AccountFragment extends BaseFragment implements View.OnClickListener {
private AccountViewModel accountViewModel;
private CircleImageView civHead;
private TextView tvUserName;
private TextView tvNickName;
public View onCreateView(@NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
@ -40,14 +44,12 @@ public class AccountFragment extends BaseFragment implements View.OnClickListene
final TextView textView = root.findViewById(R.id.text_notifications);
root.findViewById(R.id.text_sign_out).setOnClickListener(this);
root.findViewById(R.id.rl_personal_info).setOnClickListener(this);
TextView tvNickName = root.findViewById(R.id.tv_nick_name);
tvNickName.setText(AccountUtils.getCurNickname());
TextView tvUserName = root.findViewById(R.id.tv_user_name);
tvUserName.setText(getString(R.string.account_show, AccountUtils.getCurUserName()));
CircleImageView civHead = root.findViewById(R.id.civ_head);
if (!DataUtil.isEmpty(AccountUtils.getCurHeadUrl())) {
Glide.with(this).load(AccountUtils.getCurHeadUrl()).into(civHead);
}
tvNickName = root.findViewById(R.id.tv_nick_name);
tvUserName = root.findViewById(R.id.tv_user_name);
civHead = root.findViewById(R.id.civ_head);
setPersonalInfo();
accountViewModel.getText().observe(getViewLifecycleOwner(), new Observer<String>() {
@Override
public void onChanged(@Nullable String s) {
@ -76,4 +78,23 @@ public class AccountFragment extends BaseFragment implements View.OnClickListene
break;
}
}
@Override
public void onResume() {
super.onResume();
if (Const.NEED_RELOAD_PROFILE) {
setPersonalInfo();
}
}
/**
* 设置个人信息
*/
private void setPersonalInfo() {
if (!DataUtil.isEmpty(AccountUtils.getCurHeadUrl())) {
Glide.with(this).load(AccountUtils.getCurHeadUrl()).placeholder(R.drawable.ic_head_default).into(civHead);
}
tvUserName.setText(getString(R.string.account_show, AccountUtils.getCurUserName()));
tvNickName.setText(AccountUtils.getCurNickname());
}
}

View File

@ -2,8 +2,14 @@ package com.yuxihan.sdu.ui.info;
import android.content.Context;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;
import com.bumptech.glide.Glide;
import com.luck.picture.lib.PictureSelector;
@ -13,52 +19,135 @@ import com.luck.picture.lib.entity.LocalMedia;
import com.luck.picture.lib.listener.OnResultCallbackListener;
import com.yuxihan.sdu.R;
import com.yuxihan.sdu.comm.BaseActivity;
import com.yuxihan.sdu.comm.Const;
import com.yuxihan.sdu.comm.SDUApp;
import com.yuxihan.sdu.comm.util.AccountUtils;
import com.yuxihan.sdu.comm.util.DataUtil;
import com.yuxihan.sdu.comm.util.GlideEngine;
import com.yuxihan.sdu.comm.widget.ActionSheetDialog;
import com.yuxihan.sdu.comm.widget.CommonDialog;
import java.io.File;
import java.util.List;
import de.hdodenhof.circleimageview.CircleImageView;
public class InfoEditActivity extends BaseActivity {
public class InfoEditActivity extends BaseActivity implements View.OnClickListener {
private static final String TAG = "InfoEditActivity";
private Context mContext = InfoEditActivity.this;
private InfoEditViewModel infoEditViewModel;
CircleImageView civ_head;
private TextView nickname;
private TextView userName;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_info_edit);
infoEditViewModel = new ViewModelProvider(this, new InfoEditViewModelFactory())
.get(InfoEditViewModel.class);
initView();
}
private void initView() {
nickname = findViewById(R.id.tv_nick_name);
nickname.setText(AccountUtils.getCurNickname());
userName = findViewById(R.id.tv_user_name);
userName.setText(AccountUtils.getCurUserName());
civ_head = findViewById(R.id.civ_head);
String[] fileFrom = new String[]{"相机", "图库"};
if (!DataUtil.isEmpty(AccountUtils.getCurHeadUrl())) {
Glide.with(InfoEditActivity.this).load(AccountUtils.getCurHeadUrl()).placeholder(R.drawable.ic_head_default).into(civ_head);
}
//头像控件点击事件
findViewById(R.id.rl_head_icon).setOnClickListener(new View.OnClickListener() {
findViewById(R.id.rl_head_icon).setOnClickListener(this);
findViewById(R.id.rl_nick_name).setOnClickListener(this);
infoEditViewModel.getUpdateUserHead().observe(this, new Observer<UpdateUserHeadState>() {
@Override
public void onClick(View view) {
ActionSheetDialog actionSheetDialog = new ActionSheetDialog(
mContext).builder().setCancelable(false)
.setCanceledOnTouchOutside(true);
for (int i = 0; i < fileFrom.length; i++) {
actionSheetDialog.addSheetItem(fileFrom[i],
ActionSheetDialog.SheetItemColor.Blue,
new ActionSheetDialog.OnSheetItemClickListener() {
@Override
public void onClick(int which) {
getFile(which);
}
});
public void onChanged(UpdateUserHeadState updateUserHeadState) {
if (!DataUtil.isEmpty(updateUserHeadState.getUpdatedUrl())) {
Glide.with(InfoEditActivity.this).load(updateUserHeadState.getUpdatedUrl()).placeholder(R.drawable.ic_head_default).into(civ_head);
AccountUtils.setCurHeadUrl(updateUserHeadState.getUpdatedUrl());
Const.NEED_RELOAD_PROFILE = true;
}
actionSheetDialog.show();
}
});
infoEditViewModel.getUpdateNicknameState().observe(this,
new Observer<UpdateNicknameState>() {
@Override
public void onChanged(UpdateNicknameState updateNicknameState) {
nickname.setText(updateNicknameState.getNickname());
AccountUtils.setCurNickname(updateNicknameState.getNickname());
Const.NEED_RELOAD_PROFILE = true;
}
});
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.rl_head_icon:
updateUserHead();
break;
case R.id.rl_nick_name:
updateNickname();
break;
default:
break;
}
}
/**
* 修改头像
*/
private void updateUserHead() {
String[] fileFrom = new String[]{"相机", "图库"};
ActionSheetDialog actionSheetDialog = new ActionSheetDialog(
mContext).builder().setCancelable(false)
.setCanceledOnTouchOutside(true);
for (String s : fileFrom) {
actionSheetDialog.addSheetItem(s,
ActionSheetDialog.SheetItemColor.Blue,
new ActionSheetDialog.OnSheetItemClickListener() {
@Override
public void onClick(int which) {
getFile(which);
}
});
}
actionSheetDialog.show();
}
/**
* 修改昵称
*/
private void updateNickname() {
final CommonDialog dialog = new CommonDialog(InfoEditActivity.this);
dialog.setImageResId(R.mipmap.ic_launcher)
.setTitle("修改昵称")
.setEtHint("请输入新昵称")
.setSingle(false).setOnClickBottomListener(new CommonDialog.OnClickBottomListener() {
@Override
public void onPositiveClick(String result) {
dialog.dismiss();
if (!TextUtils.isEmpty(result)){
infoEditViewModel.updateNickname(result);
}
}
@Override
public void onNegativeClick() {
dialog.dismiss();
}
}).show();
}
//处理点击事件
/**
* 获取裁减的文件
*/
private void getFile(int index) {
switch (index) {
case 1:
@ -89,13 +178,13 @@ public class InfoEditActivity extends BaseActivity {
.synOrAsy(true)//同步true或异步false 压缩 默认同步
.glideOverride(120, 120)// glide 加载宽高越小图片列表越流畅但会影响列表图片浏览的清晰度
//.selectionMedia(picList)// 是否传入已选图片
.minimumCompressSize(100)// 小于100kb的图片不压缩
//.minimumCompressSize(100)// 小于100kb的图片不压缩
.loadImageEngine(GlideEngine.createGlideEngine())
.isEnableCrop(true)//是否开启裁剪
.circleDimmedLayer(true)// 是否开启圆形裁剪
.showCropGrid(false)
.showCropFrame(false)
.withAspectRatio(1,1)
.withAspectRatio(1, 1)
.forResult(new PicResultCallback());//结果回调
}
@ -117,15 +206,16 @@ public class InfoEditActivity extends BaseActivity {
.maxSelectNum(1)// 最大图片选择数量
.isZoomAnim(true)// 图片列表点击 缩放效果 默认true
.synOrAsy(true)//同步true或异步false 压缩 默认同步
.minimumCompressSize(100)// 小于100kb的图片不压缩
//.minimumCompressSize(100)// 小于100kb的图片不压缩
.isEnableCrop(true)//是否开启裁剪
.circleDimmedLayer(true)// 是否开启圆形裁剪
.showCropGrid(false)
.showCropFrame(false)
.withAspectRatio(1,1)
.withAspectRatio(1, 1)
.forResult(new CameraResultCallback());//结果回调
}
/**
* 图库返回结果回调
*/
@ -146,7 +236,7 @@ public class InfoEditActivity extends BaseActivity {
Log.i(TAG, "宽高: " + media.getWidth() + "x" + media.getHeight());
Log.i(TAG, "Size: " + media.getSize());
//TODO:上传 media.getCompressPath()
Glide.with(InfoEditActivity.this).load(media.getCompressPath()).into(civ_head);
infoEditViewModel.upload(File.separator + AccountUtils.getCurUserName() + File.separator + System.currentTimeMillis(), media.getCompressPath());
}
}
@ -157,7 +247,7 @@ public class InfoEditActivity extends BaseActivity {
}
/**
* 返回结果回调
* 返回结果回调
*/
private class CameraResultCallback implements OnResultCallbackListener<LocalMedia> {
@ -176,7 +266,7 @@ public class InfoEditActivity extends BaseActivity {
Log.i(TAG, "宽高: " + media.getWidth() + "x" + media.getHeight());
Log.i(TAG, "Size: " + media.getSize());
//TODO:上传 media.getCompressPath()
Glide.with(InfoEditActivity.this).load(media.getCompressPath()).into(civ_head);
infoEditViewModel.upload(File.separator + AccountUtils.getCurUserName() + File.separator + System.currentTimeMillis(), media.getCompressPath());
}
}
@ -185,4 +275,6 @@ public class InfoEditActivity extends BaseActivity {
Log.i(TAG, "PictureSelector Cancel");
}
}
}

View File

@ -0,0 +1,133 @@
package com.yuxihan.sdu.ui.info;
import android.util.Log;
import android.widget.Toast;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
import com.tencent.cos.xml.exception.CosXmlClientException;
import com.tencent.cos.xml.exception.CosXmlServiceException;
import com.tencent.cos.xml.listener.CosXmlProgressListener;
import com.tencent.cos.xml.listener.CosXmlResultListener;
import com.tencent.cos.xml.model.CosXmlRequest;
import com.tencent.cos.xml.model.CosXmlResult;
import com.tencent.cos.xml.transfer.COSXMLUploadTask;
import com.tencent.cos.xml.transfer.TransferState;
import com.tencent.cos.xml.transfer.TransferStateListener;
import com.yuxihan.sdu.comm.Const;
import com.yuxihan.sdu.comm.SDUApp;
import com.yuxihan.sdu.comm.util.UploadTencentSDK;
import com.yuxihan.sdu.data.UpdateService;
import com.yuxihan.sdu.data.model.DataBean;
import com.yuxihan.sdu.data.model.UpdateNicknameParams;
import com.yuxihan.sdu.data.model.UpdateUserHeadParams;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
public class InfoEditViewModel extends ViewModel {
private MutableLiveData<UpdateUserHeadState> updateUserHead = new MutableLiveData<>();
private MutableLiveData<UpdateNicknameState> updateNicknameState = new MutableLiveData<>();
public MutableLiveData<UpdateNicknameState> getUpdateNicknameState() {
return updateNicknameState;
}
MutableLiveData<UpdateUserHeadState> getUpdateUserHead() {
return updateUserHead;
}
public void updateNickname(String nickname) {
UpdateService updateService = SDUApp.getRetrofit().create(UpdateService.class);
Call<DataBean> call = updateService.updateNickname(new UpdateNicknameParams(nickname));
call.enqueue(new Callback<DataBean>() {
@Override
public void onResponse(Call<DataBean> call, Response<DataBean> response) {
//请求成功返回是一个封装为DataBean的响应
Log.e("TAG", "接口返回内容 ===== " + response.body().getResult());
if ("0".equals(response.body().getErrCode())) {
updateNicknameState.setValue(new UpdateNicknameState(nickname));
} else {
Toast.makeText(SDUApp.getAppContext(), "保存失败,请重新登陆后再试!", Toast.LENGTH_LONG).show();
}
}
@Override
public void onFailure(Call<DataBean> call, Throwable t) {
//请求失败
Log.e("TAG", "请求失败:" + t.getMessage());
Toast.makeText(SDUApp.getAppContext(), "服务器开小差了!", Toast.LENGTH_LONG).show();
}
});
}
private void updateUserHead(String accessUrl) {
UpdateService updateService = SDUApp.getRetrofit().create(UpdateService.class);
Call<DataBean> call = updateService.updateUserHead(new UpdateUserHeadParams(accessUrl));
call.enqueue(new Callback<DataBean>() {
@Override
public void onResponse(Call<DataBean> call, Response<DataBean> response) {
//请求成功返回是一个封装为DataBean的响应
Log.e("TAG", "接口返回内容 ===== " + response.body().getResult());
if ("0".equals(response.body().getErrCode())) {
updateUserHead.setValue(new UpdateUserHeadState(accessUrl));
} else {
Toast.makeText(SDUApp.getAppContext(), "保存失败,请重新登陆后再试!", Toast.LENGTH_LONG).show();
}
}
@Override
public void onFailure(Call<DataBean> call, Throwable t) {
//请求失败
Log.e("TAG", "请求失败:" + t.getMessage());
Toast.makeText(SDUApp.getAppContext(), "服务器开小差了!", Toast.LENGTH_LONG).show();
}
});
}
/**
* 上传
*
* @params cosPath 上传到 COS 的路径
* @params localPath 本地文件路径
*/
public void upload(String cosPath, String localPath) {
// 开始上传并返回生成的 COSXMLUploadTask
COSXMLUploadTask cosxmlUploadTask =
UploadTencentSDK.getTransferManager().upload(Const.BUCKET_NAME, cosPath,
localPath, null);
// 设置上传状态监听
cosxmlUploadTask.setTransferStateListener(new TransferStateListener() {
@Override
public void onStateChanged(final TransferState state) {
}
});
// 设置上传进度监听
cosxmlUploadTask.setCosXmlProgressListener(new CosXmlProgressListener() {
@Override
public void onProgress(final long complete, final long target) {
}
});
// 设置结果监听
cosxmlUploadTask.setCosXmlResultListener(new CosXmlResultListener() {
@Override
public void onSuccess(CosXmlRequest request, CosXmlResult result) {
updateUserHead(result.accessUrl);
}
@Override
public void onFail(CosXmlRequest request, CosXmlClientException exception,
CosXmlServiceException serviceException) {
Toast.makeText(SDUApp.getAppContext(), "头像上传失败,请重试!", Toast.LENGTH_LONG).show();
}
});
}
}

View File

@ -0,0 +1,23 @@
package com.yuxihan.sdu.ui.info;
import androidx.annotation.NonNull;
import androidx.lifecycle.ViewModel;
import androidx.lifecycle.ViewModelProvider;
/**
* ViewModel provider factory to instantiate LoginViewModel.
* Required given LoginViewModel has a non-empty constructor
*/
public class InfoEditViewModelFactory implements ViewModelProvider.Factory {
@NonNull
@Override
@SuppressWarnings("unchecked")
public <T extends ViewModel> T create(@NonNull Class<T> modelClass) {
if (modelClass.isAssignableFrom(InfoEditViewModel.class)) {
return (T) new InfoEditViewModel();
} else {
throw new IllegalArgumentException("Unknown ViewModel class");
}
}
}

View File

@ -0,0 +1,17 @@
package com.yuxihan.sdu.ui.info;
public class UpdateNicknameState {
private String nickname;
public UpdateNicknameState(String accessUrl) {
nickname = accessUrl;
}
public String getNickname() {
return nickname;
}
public void setNickname(String nickname) {
this.nickname = nickname;
}
}

View File

@ -0,0 +1,17 @@
package com.yuxihan.sdu.ui.info;
public class UpdateUserHeadState {
private String updatedUrl;
public UpdateUserHeadState(String accessUrl) {
updatedUrl = accessUrl;
}
public String getUpdatedUrl() {
return updatedUrl;
}
public void setUpdatedUrl(String updatedUrl) {
this.updatedUrl = updatedUrl;
}
}

View File

@ -26,7 +26,8 @@ import com.yuxihan.sdu.MainActivity;
import com.yuxihan.sdu.R;
import com.yuxihan.sdu.comm.BaseActivity;
import com.yuxihan.sdu.data.model.LoggedInUser;
import com.yuxihan.sdu.ui.reg.login.RegActivity;
import com.yuxihan.sdu.ui.info.InfoEditViewModelFactory;
import com.yuxihan.sdu.ui.reg.RegActivity;
public class LoginActivity extends BaseActivity {

View File

@ -12,6 +12,7 @@ import com.yuxihan.sdu.comm.util.FormatUtils;
import com.yuxihan.sdu.data.UpdateService;
import com.yuxihan.sdu.data.model.DataBean;
import com.yuxihan.sdu.data.model.LoggedInUser;
import com.yuxihan.sdu.data.model.LoginParams;
import retrofit2.Call;
import retrofit2.Callback;
@ -40,7 +41,7 @@ public class LoginViewModel extends ViewModel {
public void login(final String username, String password) {
UpdateService updateService = SDUApp.getRetrofit().create(UpdateService.class);
Call<DataBean> call = updateService.login(username, password);
Call<DataBean> call = updateService.login(new LoginParams(username, password));
call.enqueue(new Callback<DataBean>() {
@Override
public void onResponse(Call<DataBean> call, Response<DataBean> response) {
@ -48,10 +49,13 @@ public class LoginViewModel extends ViewModel {
Log.e("TAG", "接口返回内容 ===== " + response.body().getResult());
if ("0".equals(response.body().getErrCode())) {
String token = response.body().getResult().getToken();
String nickName = response.body().getResult().getNickname();
String userHead = response.body().getResult().getUserHead();
loggedInUser.setValue(new LoggedInUser(username, username));
AccountUtils.saveLoginState(username, token, "雨曦大魔王", null);
AccountUtils.saveLoginState(username, token, nickName, userHead);
} else {
loggedInUser.setValue(new LoggedInUser(username, "用户名/密码 错误!", false));
loggedInUser.setValue(new LoggedInUser(username, response.body().getErrMsg(),
false));
}
}

View File

@ -1,5 +1,7 @@
package com.yuxihan.sdu.ui.reg.login;
package com.yuxihan.sdu.ui.reg;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.text.Editable;
@ -7,6 +9,7 @@ import android.text.TextWatcher;
import android.view.KeyEvent;
import android.view.View;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ProgressBar;
@ -21,6 +24,7 @@ import androidx.lifecycle.ViewModelProvider;
import com.gyf.immersionbar.ImmersionBar;
import com.yuxihan.sdu.R;
import com.yuxihan.sdu.comm.BaseActivity;
import com.yuxihan.sdu.data.model.LoggedInUser;
import com.yuxihan.sdu.ui.login.LoginActivity;
public class RegActivity extends BaseActivity {
@ -41,6 +45,7 @@ public class RegActivity extends BaseActivity {
final TextView btGetVerification = findViewById(R.id.bt_get_verification);
btGetVerification.setEnabled(false);
btGetVerification.setTextColor(getResources().getColor(R.color.gray));
final EditText etVerification = findViewById(R.id.et_verification);
final Button loginButton = findViewById(R.id.login);
final ProgressBar loadingProgressBar = findViewById(R.id.loading);
@ -89,7 +94,7 @@ public class RegActivity extends BaseActivity {
@Override
public void afterTextChanged(Editable s) {
regViewModel.loginDataChanged(usernameEditText.getText().toString(),
passwordEditText.getText().toString());
passwordEditText.getText().toString(), etVerification.getText().toString());
}
};
usernameEditText.addTextChangedListener(afterTextChangedListener);
@ -99,8 +104,9 @@ public class RegActivity extends BaseActivity {
@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if (actionId == EditorInfo.IME_ACTION_DONE) {
regViewModel.login(usernameEditText.getText().toString(),
passwordEditText.getText().toString());
regViewModel.reg(usernameEditText.getText().toString(),
passwordEditText.getText().toString(),
etVerification.getText().toString());
}
return false;
}
@ -110,12 +116,39 @@ public class RegActivity extends BaseActivity {
@Override
public void onClick(View v) {
loadingProgressBar.setVisibility(View.VISIBLE);
regViewModel.login(usernameEditText.getText().toString(),
passwordEditText.getText().toString());
InputMethodManager manager =
((InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE));
if (manager != null) {
manager.hideSoftInputFromWindow(loginButton.getWindowToken(),
InputMethodManager.HIDE_NOT_ALWAYS);
}
regViewModel.reg(usernameEditText.getText().toString(),
passwordEditText.getText().toString(), etVerification.getText().toString());
}
});
regViewModel.getLoggedInUser().observe(this, new Observer<LoggedInUser>() {
@Override
public void onChanged(LoggedInUser loginResult) {
if (loginResult == null) {
return;
}
loadingProgressBar.setVisibility(View.GONE);
if (loginResult.isLoginSuccess()) {
// startActivity(new Intent(getApplicationContext(), LoginActivity.class));
Toast.makeText(RegActivity.this, "注册成功!",
Toast.LENGTH_LONG).show();
setResult(Activity.RESULT_OK);
finish();
} else {
Toast.makeText(RegActivity.this, loginResult.getDisplayName(),
Toast.LENGTH_LONG).show();
}
}
});
}
private void updateUiWithUser() {
startActivity(new Intent(getApplicationContext(), LoginActivity.class));
}

View File

@ -1,4 +1,4 @@
package com.yuxihan.sdu.ui.reg.login;
package com.yuxihan.sdu.ui.reg;
import androidx.annotation.Nullable;
@ -12,6 +12,7 @@ class RegFormState {
private Integer passwordError;
private boolean isDataValid;
private boolean isPhoneNumberValid;
private boolean isVerificationCodeValid;
RegFormState(@Nullable Integer usernameError, @Nullable Integer passwordError) {
this.usernameError = usernameError;
@ -46,4 +47,11 @@ class RegFormState {
public void setPhoneNumberValid(boolean phoneNumberValid) {
isPhoneNumberValid = phoneNumberValid;
}
public void setVerificationCodeValid(boolean isVerificationCodeValid) {
this.isVerificationCodeValid = isVerificationCodeValid;
}
public boolean isVerificationCodeValid() {
return isVerificationCodeValid;
}
}

View File

@ -0,0 +1,74 @@
package com.yuxihan.sdu.ui.reg;
import android.text.TextUtils;
import android.util.Log;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
import com.yuxihan.sdu.comm.SDUApp;
import com.yuxihan.sdu.comm.util.FormatUtils;
import com.yuxihan.sdu.data.UpdateService;
import com.yuxihan.sdu.data.model.DataBean;
import com.yuxihan.sdu.data.model.LoggedInUser;
import com.yuxihan.sdu.data.model.RegParams;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
public class RegViewModel extends ViewModel {
private MutableLiveData<LoggedInUser> loggedInUser = new MutableLiveData<>();
private MutableLiveData<RegFormState> regFormState = new MutableLiveData<>();
public MutableLiveData<LoggedInUser> getLoggedInUser() {
return loggedInUser;
}
LiveData<RegFormState> getRegFormState() {
return regFormState;
}
public void reg(String username, String password, String verificationCode) {
UpdateService updateService = SDUApp.getRetrofit().create(UpdateService.class);
Call<DataBean> call = updateService.reg(new RegParams(username, password,verificationCode));
call.enqueue(new Callback<DataBean>() {
@Override
public void onResponse(Call<DataBean> call, Response<DataBean> response) {
//请求成功返回是一个封装为DataBean的响应
Log.e("TAG", "接口返回内容 ===== " + response.body().getResult());
if ("0".equals(response.body().getErrCode())) {
String token = response.body().getResult().getToken();
loggedInUser.setValue(new LoggedInUser(username, username));
} else {
loggedInUser.setValue(new LoggedInUser(username, response.body().getErrMsg(), false));
}
}
@Override
public void onFailure(Call<DataBean> call, Throwable t) {
//请求失败
Log.e("TAG", "请求失败:" + t.getMessage());
loggedInUser.setValue(new LoggedInUser(username, "\"服务器开小差了!\"", false));
}
});
}
public void loginDataChanged(String username, String verificationCode, String password) {
RegFormState regFormState = new RegFormState(true);
regFormState.setPhoneNumberValid(FormatUtils.isMobileNO(username));
regFormState.setVerificationCodeValid(isVerificationCode(verificationCode));
this.regFormState.setValue(regFormState);
}
/**
* 验证码是否有效
*/
public static boolean isVerificationCode(String verificationCode) {
if (TextUtils.isEmpty(verificationCode)) return false;
else return verificationCode.length() == 6;
}
}

View File

@ -1,4 +1,4 @@
package com.yuxihan.sdu.ui.reg.login;
package com.yuxihan.sdu.ui.reg;
import androidx.annotation.NonNull;
import androidx.lifecycle.ViewModel;

View File

@ -1,29 +0,0 @@
package com.yuxihan.sdu.ui.reg.login;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
import com.yuxihan.sdu.comm.util.FormatUtils;
public class RegViewModel extends ViewModel {
private MutableLiveData<RegFormState> regFormState = new MutableLiveData<>();
LiveData<RegFormState> getRegFormState() {
return regFormState;
}
public void login(String username, String password) {
}
public void loginDataChanged(String username, String password) {
RegFormState regFormState = new RegFormState(true);
regFormState.setPhoneNumberValid(FormatUtils.isMobileNO(username));
this.regFormState.setValue(regFormState);
}
}

View File

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item>
<shape android:shape="rectangle" >
<gradient
android:endColor="#000000"
android:startColor="#000000" />
</shape>
</item>
<item android:bottom="2dp">
<shape android:shape="rectangle" >
<gradient
android:endColor="#eeeeee"
android:startColor="#eeeeee" />
</shape>
</item>
</layer-list>

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#ffffff" />
<stroke
android:width="0.8dp"
android:color="#ffffff" />
<!-- 圆角 -->
<corners android:radius="6dp" />
</shape>

View File

@ -79,6 +79,7 @@
<RelativeLayout
android:layout_width="match_parent"
android:id="@+id/rl_nick_name"
android:layout_height="50dp">
<TextView
@ -91,6 +92,7 @@
android:textSize="16sp" />
<TextView
android:id="@+id/tv_nick_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"

View File

@ -0,0 +1,111 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:background="@drawable/bg_white_round_corner"
android:focusable="true"
android:focusableInTouchMode="true"
android:minWidth="260dp"
android:orientation="vertical"
android:paddingTop="16dp">
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:layout_marginBottom="16dp"
android:gravity="center"
android:textColor="#333333"
android:textSize="18sp"
android:visibility="visible"
tools:text="消息提示" />
<ImageView
android:id="@+id/image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:layout_marginBottom="10dp"
android:maxWidth="150dp"
android:maxHeight="150dp"
android:visibility="gone"
tools:src="@drawable/wel_icon" />
<TextView
android:id="@+id/message"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:gravity="center|left"
android:lineSpacingExtra="3dp"
android:lineSpacingMultiplier="1.2"
android:textColor="#999999"
android:textSize="14dp"
tools:text="提示消息提示消息提示消息提示消息提示消息提示消息提示消息提示消息" />
<EditText
android:id="@+id/et_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="20dp"
android:layout_marginEnd="20dp"
android:background="@drawable/bg_et_orange"
android:textColor="#333333"
android:textSize="20sp" />
<View
android:layout_width="match_parent"
android:layout_height="1px"
android:layout_marginTop="16dp"
android:background="#E4E4E4" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:id="@+id/negative"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_weight="1"
android:background="@null"
android:gravity="center"
android:paddingTop="16dp"
android:paddingBottom="16dp"
android:singleLine="true"
android:textColor="#999999"
android:textSize="16sp"
tools:text="No" />
<View
android:id="@+id/column_line"
android:layout_width="1px"
android:layout_height="match_parent"
android:background="#E4E4E4" />
<Button
android:id="@+id/positive"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginRight="10dp"
android:layout_weight="1"
android:background="@null"
android:gravity="center"
android:paddingTop="16dp"
android:paddingBottom="16dp"
android:singleLine="true"
android:textColor="#38ADFF"
android:textSize="16sp"
tools:text="Yes" />
</LinearLayout>
</LinearLayout>

View File

@ -17,6 +17,18 @@
<item name="android:windowFullscreen">true</item>
</style>
<style name="CustomDialog" parent="android:style/Theme.Dialog">
<!--背景颜色及和透明程度-->
<item name="android:windowBackground">@android:color/transparent</item>
<!--是否去除标题 -->
<item name="android:windowNoTitle">true</item>
<!--是否去除边框-->
<item name="android:windowFrame">@null</item>
<!--是否浮现在activity之上-->
<item name="android:windowIsFloating">true</item>
<!--是否模糊-->
<item name="android:backgroundDimEnabled">true</item>
</style>
<!-- ActionSheet进出动画 -->
<style name="ActionSheetDialogAnimation" parent="@android:style/Animation.Dialog">