diff --git a/app/build.gradle b/app/build.gradle index 909911f..624d1fc 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -23,7 +23,7 @@ android { sourceSets { main { res { - srcDirs 'src/main/res', 'src/main/res/layout/resetpwd', 'src/main/res/layout/resetpwd/layout', 'src/main/res/layout/main', 'src/main/res/layout/main/layout', 'src/main/res/layout/main/layout/forum', 'src/main/res/layout/main/layout/forum/layout', 'src/main/res/layout/main/layout/visitor', 'src/main/res/layout/main/layout/visitor/layout' + srcDirs 'src/main/res', 'src/main/res/layout/resetpwd', 'src/main/res/layout/resetpwd/layout', 'src/main/res/layout/main', 'src/main/res/layout/main/layout', 'src/main/res/layout/main/layout/forum', 'src/main/res/layout/main/layout/forum/layout', 'src/main/res/layout/main/layout/visitor', 'src/main/res/layout/main/layout/visitor/layout','src/main/res/layout/main/layout/info','src/main/res/layout/main/layout/info/layout' } } } diff --git a/app/src/main/java/com/community/pocket/data/main/info/InfoRequest.java b/app/src/main/java/com/community/pocket/data/main/info/InfoRequest.java new file mode 100644 index 0000000..ece9480 --- /dev/null +++ b/app/src/main/java/com/community/pocket/data/main/info/InfoRequest.java @@ -0,0 +1,50 @@ +package com.community.pocket.data.main.info; + + +import com.community.pocket.R; +import com.community.pocket.data.model.MyInfo; +import com.community.pocket.ui.main.ui.info.InfoResponse; + +import java.util.ArrayList; +import java.util.Random; + +/** + * 个人信息请求接口 + * TODO 完善逻辑 + */ +public class InfoRequest { + private static volatile InfoRequest instance; + + private InfoRequest() { + } + + public static InfoRequest getInstance() { + if (instance == null) { + instance = new InfoRequest(); + } + return instance; + } + + //修改密码 + public InfoResponse modifyPwd(String oldpwd, String newpwd) { + return new InfoResponse().setSuccess(R.string.modify_pwd_ok); + } + + //获取个人信息 + public InfoResponse loadInfo() { + MyInfo myInfo = new MyInfo(); + myInfo.setUsername("fff"); + myInfo.setCreditScore(new Random().nextInt(100)); + myInfo.setRecentPosts(new Random().nextInt(100)); + myInfo.setRecentVisitors(new Random().nextInt(100)); + myInfo.setMobie("123456"); + myInfo.setEmail("abc@qq.com"); + myInfo.setScoreHistory(new ArrayList() {{ + for (int i = 0; i < 100; i++) { + add(new Random().nextInt(100)); + } + }}); + + return new InfoResponse().setSuccess(R.string.load_info_ok).setBody(myInfo); + } +} diff --git a/app/src/main/java/com/community/pocket/data/model/MyInfo.java b/app/src/main/java/com/community/pocket/data/model/MyInfo.java new file mode 100644 index 0000000..819e6b3 --- /dev/null +++ b/app/src/main/java/com/community/pocket/data/model/MyInfo.java @@ -0,0 +1,87 @@ +package com.community.pocket.data.model; + +import java.util.List; + +public class MyInfo { + //用户名 + private String username; + //信用分 + private Integer creditScore; + //头像 + private String headImg; + //最近发帖数 + private Integer recentPosts; + //最近访客数 + private Integer recentVisitors; + //手机号 + private String mobie; + //邮箱 + private String email; + + //信用分历史记录 + private List scoreHistory; + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public Integer getCreditScore() { + return creditScore; + } + + public void setCreditScore(Integer creditScore) { + this.creditScore = creditScore; + } + + public String getHeadImg() { + return headImg; + } + + public void setHeadImg(String headImg) { + this.headImg = headImg; + } + + public Integer getRecentPosts() { + return recentPosts; + } + + public void setRecentPosts(Integer recentPosts) { + this.recentPosts = recentPosts; + } + + public Integer getRecentVisitors() { + return recentVisitors; + } + + public void setRecentVisitors(Integer recentVisitors) { + this.recentVisitors = recentVisitors; + } + + public String getMobie() { + return mobie; + } + + public void setMobie(String mobie) { + this.mobie = mobie; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public List getScoreHistory() { + return scoreHistory; + } + + public void setScoreHistory(List scoreHistory) { + this.scoreHistory = scoreHistory; + } +} diff --git a/app/src/main/java/com/community/pocket/ui/main/ui/forum/data/ForumDataActivity.java b/app/src/main/java/com/community/pocket/ui/main/ui/forum/data/ForumDataActivity.java index 6ea0636..0b1c5c7 100644 --- a/app/src/main/java/com/community/pocket/ui/main/ui/forum/data/ForumDataActivity.java +++ b/app/src/main/java/com/community/pocket/ui/main/ui/forum/data/ForumDataActivity.java @@ -53,17 +53,17 @@ public class ForumDataActivity extends BaseActivity { private ForumDataViewModel viewModel; - //关闭回帖窗口按钮 - private Button close; - //回帖按钮 private Button reply; + //弹窗控制 private Handler handler; + //打开回贴弹窗按钮 @ViewInject(R.id.open_reply) private Button openReply; + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -155,7 +155,8 @@ public class ForumDataActivity extends BaseActivity { View alertView = View.inflate(this, R.layout.forum_replay, null); editText = alertView.findViewById(R.id.post_content); - close = alertView.findViewById(R.id.close); + //关闭回帖窗口按钮 + Button close = alertView.findViewById(R.id.close); reply = alertView.findViewById(R.id.reply); reply.setOnClickListener(new View.OnClickListener() { @Override diff --git a/app/src/main/java/com/community/pocket/ui/main/ui/info/InfoFormState.java b/app/src/main/java/com/community/pocket/ui/main/ui/info/InfoFormState.java new file mode 100644 index 0000000..6ba5428 --- /dev/null +++ b/app/src/main/java/com/community/pocket/ui/main/ui/info/InfoFormState.java @@ -0,0 +1,49 @@ +package com.community.pocket.ui.main.ui.info; + +import androidx.annotation.Nullable; + +/** + * 修改密码表单校验状态 + */ +class InfoFormState { + //旧密码 + @Nullable + private Integer oldPwdError; + //新密码 + @Nullable + private Integer newPwdError; + //确认新密码 + @Nullable + private Integer confirmNewPwdError; + + private boolean isDataValid; + + InfoFormState(@Nullable Integer oldPwdError, @Nullable Integer newPwdError, @Nullable Integer confirmNewPwdError) { + this.oldPwdError = oldPwdError; + this.newPwdError = newPwdError; + this.confirmNewPwdError = confirmNewPwdError; + } + + InfoFormState(boolean isDataValid) { + this.isDataValid = isDataValid; + } + + @Nullable + Integer getOldPwdError() { + return oldPwdError; + } + + @Nullable + Integer getNewPwdError() { + return newPwdError; + } + + @Nullable + Integer getConfirmNewPwdError() { + return confirmNewPwdError; + } + + boolean isDataValid() { + return isDataValid; + } +} diff --git a/app/src/main/java/com/community/pocket/ui/main/ui/info/InfoFragment.java b/app/src/main/java/com/community/pocket/ui/main/ui/info/InfoFragment.java index 4865bdd..2ec9177 100644 --- a/app/src/main/java/com/community/pocket/ui/main/ui/info/InfoFragment.java +++ b/app/src/main/java/com/community/pocket/ui/main/ui/info/InfoFragment.java @@ -3,17 +3,31 @@ package com.community.pocket.ui.main.ui.info; import android.content.Intent; import android.os.Build; import android.os.Bundle; +import android.os.Handler; +import android.os.Looper; +import android.os.Message; +import android.text.Editable; +import android.text.TextWatcher; import android.view.View; +import android.widget.Button; +import android.widget.EditText; import android.widget.ImageView; import android.widget.TextView; +import android.widget.Toast; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.RequiresApi; +import androidx.appcompat.app.AlertDialog; +import androidx.lifecycle.Observer; +import androidx.lifecycle.ViewModelProvider; import com.community.pocket.R; +import com.community.pocket.data.model.MyInfo; import com.community.pocket.ui.BaseFragment; +import com.community.pocket.ui.listener.MyTextChange; import com.community.pocket.ui.login.LoginActivity; +import com.community.pocket.util.PropertiesUtil; import com.github.mikephil.charting.charts.LineChart; import com.github.mikephil.charting.data.Entry; import com.github.mikephil.charting.data.LineData; @@ -25,7 +39,7 @@ import org.xutils.view.annotation.ViewInject; import java.util.ArrayList; import java.util.List; -import java.util.Random; +import java.util.Objects; /** * 我的信息框架 @@ -53,21 +67,195 @@ public class InfoFragment extends BaseFragment { @ViewInject(R.id.recentVisitors) private TextView recentVisitors; + //手机号 + @ViewInject(R.id.mobie) + private TextView mobie; + + //邮箱 + @ViewInject(R.id.email) + private TextView email; + + //信用分活动图表 @ViewInject(R.id.chart) private LineChart lineChart; + //原密码 + private EditText oldPwd; + + //新密码 + private EditText newPwd; + + //确认新密码 + private EditText confirmNewPwd; + + //修改密码按钮 + private Button modifyPwdBtn; + + //打开修改密码弹窗 + @ViewInject(R.id.open_modify_password) + private Button openModify; + + private InfoViewModel viewModel; + + //注销登录 + @ViewInject(R.id.logout) + private Button logout; + + private Handler handler; + @RequiresApi(api = Build.VERSION_CODES.KITKAT) @Override public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); - nickname.setText(getString(R.string.nick_name, "。。。。。。")); - creditScore.setText(getString(R.string.credit_score, 0)); + viewModel = new ViewModelProvider(this, new InfoViewModelFactory()).get(InfoViewModel.class); + + viewModel.loadInfo(); + + //监听修改密码表单状态 + viewModel.getModifyFormState().observe(getViewLifecycleOwner(), new Observer() { + @Override + public void onChanged(InfoFormState infoFormState) { + if (infoFormState == null) { + return; + } + if (infoFormState.getOldPwdError() != null) { + oldPwd.setError(getString(infoFormState.getOldPwdError(), PropertiesUtil.getIntValue("password.length"))); + } + + if (infoFormState.getNewPwdError() != null) { + newPwd.setError(getString(infoFormState.getNewPwdError(), PropertiesUtil.getIntValue("password.length"))); + } + + if (infoFormState.getConfirmNewPwdError() != null) { + if (infoFormState.getConfirmNewPwdError() == R.string.invalid_password) { + confirmNewPwd.setError(getString(infoFormState.getConfirmNewPwdError(), PropertiesUtil.getIntValue("password.length"))); + } else { + confirmNewPwd.setError(getString(infoFormState.getConfirmNewPwdError())); + } + } + + modifyPwdBtn.setEnabled(infoFormState.isDataValid()); + } + }); + + //监听修改密码的请求状态 + viewModel.getModifyResponse().observe(getViewLifecycleOwner(), new Observer() { + @Override + public void onChanged(InfoResponse infoResponse) { + if (infoResponse == null) { + return; + } + + if (infoResponse.getSuccess() != null) { + handler.sendEmptyMessage(0); + Toast.makeText(getContext(), infoResponse.getSuccess(), Toast.LENGTH_LONG).show(); + logout(logout); + } + + if (infoResponse.getError() != null) { + Toast.makeText(getContext(), infoResponse.getError(), Toast.LENGTH_LONG).show(); + } + + } + }); + + //监听个人信息请求状态 + viewModel.getInfoResponse().observe(getViewLifecycleOwner(), new Observer>() { + @Override + public void onChanged(InfoResponse myInfoInfoResponse) { + if (myInfoInfoResponse == null) { + return; + } - recentPosts.setText(getString(R.string.recent_posts, 0)); - recentVisitors.setText(getString(R.string.recent_visitors, 0)); + if (myInfoInfoResponse.getSuccess() != null) { + Toast.makeText(getContext(), R.string.load_info_ok, Toast.LENGTH_LONG).show(); + loadInfo(myInfoInfoResponse.getBody()); + } - loadChart(); + if (myInfoInfoResponse.getError() != null) { + Toast.makeText(getContext(), R.string.load_info_fail, Toast.LENGTH_LONG).show(); + } + } + }); + + //打开修改密码弹窗 + openModify.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + openModifyPassword(); + } + }); + + } + + /** + * 加载个人信息 + * + * @param myInfo 个人信息 + */ + private void loadInfo(MyInfo myInfo) { + nickname.setText(getString(R.string.nick_name, myInfo.getUsername())); + creditScore.setText(getString(R.string.credit_score, myInfo.getCreditScore())); + recentVisitors.setText(getString(R.string.recent_visitors, myInfo.getRecentVisitors())); + recentPosts.setText(getString(R.string.recent_posts, myInfo.getRecentPosts())); + mobie.setText(myInfo.getMobie()); + email.setText(myInfo.getEmail()); + + loadChart(myInfo.getScoreHistory()); + } + + /** + * 打开修改密码弹窗 + */ + @RequiresApi(api = Build.VERSION_CODES.KITKAT) + private void openModifyPassword() { + View view = View.inflate(getContext(), R.layout.modify_password, null); + //原密码 + oldPwd = view.findViewById(R.id.old_password); + //新密码 + newPwd = view.findViewById(R.id.new_password); + //确认新密码 + confirmNewPwd = view.findViewById(R.id.new_confirm_password); + + TextWatcher textWatcher = new MyTextChange() { + @Override + public void afterTextChanged(Editable s) { + viewModel.modifyPwdChanged(oldPwd.getText().toString(), newPwd.getText().toString(), confirmNewPwd.getText().toString()); + } + }; + oldPwd.addTextChangedListener(textWatcher); + newPwd.addTextChangedListener(textWatcher); + confirmNewPwd.addTextChangedListener(textWatcher); + + //修改密码按钮 + modifyPwdBtn = view.findViewById(R.id.modify_password); + modifyPwdBtn.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + viewModel.modifyPwd(oldPwd.getText().toString(), newPwd.getText().toString()); + } + }); + + AlertDialog.Builder alert = new AlertDialog.Builder(Objects.requireNonNull(getContext())); + final AlertDialog alertDialog = alert.setTitle(R.string.modify_password).setView(view).create(); + + handler = new Handler(Looper.getMainLooper()) { + @Override + public void handleMessage(@NonNull Message msg) { + alertDialog.dismiss(); + } + }; + + Button close = view.findViewById(R.id.close); + close.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + handler.sendEmptyMessage(0); + } + }); + + alertDialog.show(); } /** @@ -80,12 +268,12 @@ public class InfoFragment extends BaseFragment { } //加载图表数据 - private void loadChart() { + private void loadChart(List values) { LineData lineData = new LineData(); List entries = new ArrayList<>(); - //TODO 测试数据 - for (int i = 0; i < 100; i++) { - entries.add(new Entry(i, new Random().nextInt(100))); + + for (int i = 0; i < values.size(); i++) { + entries.add(new Entry(i, values.get(i))); } LineDataSet lineDataSet = new LineDataSet(entries, getString(R.string.active_history)); diff --git a/app/src/main/java/com/community/pocket/ui/main/ui/info/InfoResponse.java b/app/src/main/java/com/community/pocket/ui/main/ui/info/InfoResponse.java new file mode 100644 index 0000000..5243104 --- /dev/null +++ b/app/src/main/java/com/community/pocket/ui/main/ui/info/InfoResponse.java @@ -0,0 +1,47 @@ +package com.community.pocket.ui.main.ui.info; + +import androidx.annotation.Nullable; + + +/** + * 个人信息响应结果 + * + * @param 响应实体信息 + */ +public class InfoResponse { + @Nullable + private Integer success; + @Nullable + private Integer error; + + private T body; + + @Nullable + public Integer getSuccess() { + return success; + } + + public InfoResponse setSuccess(@Nullable Integer success) { + this.success = success; + return this; + } + + @Nullable + public Integer getError() { + return error; + } + + public InfoResponse setError(@Nullable Integer error) { + this.error = error; + return this; + } + + T getBody() { + return body; + } + + public InfoResponse setBody(T body) { + this.body = body; + return this; + } +} diff --git a/app/src/main/java/com/community/pocket/ui/main/ui/info/InfoViewModel.java b/app/src/main/java/com/community/pocket/ui/main/ui/info/InfoViewModel.java index 4e7bc2b..579be6f 100644 --- a/app/src/main/java/com/community/pocket/ui/main/ui/info/InfoViewModel.java +++ b/app/src/main/java/com/community/pocket/ui/main/ui/info/InfoViewModel.java @@ -1,19 +1,68 @@ package com.community.pocket.ui.main.ui.info; -import androidx.lifecycle.LiveData; import androidx.lifecycle.MutableLiveData; import androidx.lifecycle.ViewModel; +import com.community.pocket.R; +import com.community.pocket.data.main.info.InfoRequest; +import com.community.pocket.data.model.MyInfo; +import com.community.pocket.util.ValidUtil; + +//个人信息UI数据管理 class InfoViewModel extends ViewModel { - private MutableLiveData mText; + //修改密码表单校验状态 + private MutableLiveData modifyFormState = new MutableLiveData<>(); + + //修改密码请求状态 + private MutableLiveData modifyResponse = new MutableLiveData<>(); + + //个人信息请求状态 + private MutableLiveData> infoResponse = new MutableLiveData<>(); + + //请求接口管理 + private InfoRequest infoRequest; + + InfoViewModel(InfoRequest infoRequest) { + this.infoRequest = infoRequest; + } + + MutableLiveData getModifyFormState() { + return modifyFormState; + } + + MutableLiveData getModifyResponse() { + return modifyResponse; + } + + MutableLiveData> getInfoResponse() { + return infoResponse; + } + + //修改密码表单校验状态 + void modifyPwdChanged(String oldpwd, String newpwd, String confirmNewPwd) { + if (!ValidUtil.passwordvalid(oldpwd)) { + modifyFormState.setValue(new InfoFormState(R.string.invalid_password, null, null)); + } else if (!ValidUtil.passwordvalid(newpwd)) { + modifyFormState.setValue(new InfoFormState(null, R.string.invalid_password, null)); + } else if (!ValidUtil.passwordvalid(confirmNewPwd)) { + modifyFormState.setValue(new InfoFormState(null, null, R.string.invalid_password)); + } else if (!newpwd.equals(confirmNewPwd)) { + modifyFormState.setValue(new InfoFormState(null, null, R.string.invalid_confirm_password)); + } else { + modifyFormState.setValue(new InfoFormState(true)); + } + } - public InfoViewModel() { - mText = new MutableLiveData<>(); - mText.setValue("This is info fragment"); + //修改密码 + void modifyPwd(String oldpwd, String newpwd) { + InfoResponse infoResponse = infoRequest.modifyPwd(oldpwd, newpwd); + modifyResponse.setValue(infoResponse); } - LiveData getText() { - return mText; + //获取个人信息 + void loadInfo() { + InfoResponse myInfoInfoResponse = infoRequest.loadInfo(); + infoResponse.setValue(myInfoInfoResponse); } } diff --git a/app/src/main/java/com/community/pocket/ui/main/ui/info/InfoViewModelFactory.java b/app/src/main/java/com/community/pocket/ui/main/ui/info/InfoViewModelFactory.java new file mode 100644 index 0000000..eec9885 --- /dev/null +++ b/app/src/main/java/com/community/pocket/ui/main/ui/info/InfoViewModelFactory.java @@ -0,0 +1,20 @@ +package com.community.pocket.ui.main.ui.info; + +import androidx.annotation.NonNull; +import androidx.lifecycle.ViewModel; +import androidx.lifecycle.ViewModelProvider; + +import com.community.pocket.data.main.info.InfoRequest; + +public class InfoViewModelFactory implements ViewModelProvider.Factory { + @NonNull + @Override + @SuppressWarnings("unchecked") + public T create(@NonNull Class modelClass) { + if (modelClass.isAssignableFrom(InfoViewModel.class)) { + return (T) new InfoViewModel(InfoRequest.getInstance()); + } else { + throw new IllegalArgumentException("Unknown ViewModel class"); + } + } +} diff --git a/app/src/main/res/layout/main/layout/info_fragment.xml b/app/src/main/res/layout/main/layout/info/layout/info_fragment.xml similarity index 91% rename from app/src/main/res/layout/main/layout/info_fragment.xml rename to app/src/main/res/layout/main/layout/info/layout/info_fragment.xml index fdc32d2..8070fb0 100644 --- a/app/src/main/res/layout/main/layout/info_fragment.xml +++ b/app/src/main/res/layout/main/layout/info/layout/info_fragment.xml @@ -18,7 +18,7 @@