接下来完成AccountInfoActivity(账号信息详情页)
一. TimePickerView——用于设置生日
1. 初始化控件
(1)实例化layout_time_picker.xml
private void initView(Context context) {
LayoutInflater.from(getContext()).inflate(R.layout.layout_time_picker, this);
mWvYear = (WheelView) findViewById(R.id.year);
mWvMonth = (WheelView) findViewById(R.id.month);
mWvDay = (WheelView) findViewById(R.id.day);
mTvConfirm = (TextView) findViewById(R.id.tv_btn_confirm);
}
(2)加载分别设置年、月、日的滚轮控件(WheelView)
(3)加载“确认”TextView
private void initView(Context context) {
LayoutInflater.from(getContext()).inflate(R.layout.layout_time_picker, this);
mWvYear = (WheelView) findViewById(R.id.year);
mWvMonth = (WheelView) findViewById(R.id.month);
mWvDay = (WheelView) findViewById(R.id.day);
mTvConfirm = (TextView) findViewById(R.id.tv_btn_confirm);
}
2. 初始化数据
设置格式为“年-月-日”
获取当前时间,当用户想要设置生日时,默认显示为当前年月日
private void initDate(){
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault());
String[] split = sdf.format(new Date()).split("-");
int currentYear = Integer.parseInt(split[0]);
int currentMonth = Integer.parseInt(split[1]);
int currentDay = Integer.parseInt(split[2]);
mWvYear.setData(getYearData(currentYear));
mWvYear.setDefault(1);
mWvMonth.setData(getMonthData());
mWvMonth.setDefault(currentMonth - 1);
mWvDay.setData(getDayData(getMaxDay(currentYear, currentMonth)));
mWvDay.setDefault(currentDay - 1);
}
3. 初始化监听器
private void initListener(){
mTvConfirm.setOnClickListener(this);
mWvYear.setOnSelectListener(new WheelView.OnSelectListener() {
@Override
public void endSelect(int id, String text) {
changeDayData();
}
@Override
public void selecting(int id, String text) {
}
});
mWvMonth.setOnSelectListener(new WheelView.OnSelectListener() {
@Override
public void endSelect(int id, String text) {
changeDayData();
}
@Override
public void selecting(int id, String text) {
}
});
}
4. 列表加载可供用户选择的年月日
年份选择为(1900-2019)
月份选择为(1-12)
计算为闰年或平年,据此以及大月小月设置每年每月可选择的日期(28,29,30)
private ArrayList<String> getYearData(int currentYear) {
ArrayList<String> list = new ArrayList<>();
for (int i = currentYear + 1; i >= 1900; i--) {
list.add(String.valueOf(i));
}
return list;
}
private ArrayList<String> getMonthData() {
ArrayList<String> list = new ArrayList<>();
for (int i = 1; i <= 12; i++) {
list.add(String.valueOf(i));
}
return list;
}
private ArrayList<String> getDayData(int maxDay){
ArrayList<String> list = new ArrayList<>();
for (int i=1;i <= maxDay;i++){
list.add(String.valueOf(i));
}
return list;
}
private int getMaxDay(int year,int month){
if (month == 2){
if (isLeapYear(year)){
return 29;
}else {
return 28;
}
}else if (month == 1 || month == 3 || month == 5 || month == 7
|| month == 8 || month ==10 || month == 12){
return 31;
}else {
return 30;
}
}
private boolean isLeapYear(int year){
return (year % 100 == 0 && year % 400 == 0)
|| (year % 100 != 0 && year % 4 == 0);
}
5. 点击“确认”后,设为当前选择年月日
@Override
public void onClick(View v) {
if (v.getId() == R.id.tv_btn_confirm){
if (mSelectedListener != null){
mSelectedListener.selectedDate(getYear(), getMonth(),getDay());
}
}
}
附上完整TimePicker.java
package com.ezreal.ezchat.timeselectview;
import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.ezreal.ezchat.R;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Locale;
/**
* Created by 张静
*/
public class TimePickerView extends LinearLayout implements View.OnClickListener{
private WheelView mWvYear;
private WheelView mWvMonth;
private WheelView mWvDay;
private OnDateSelectedListener mSelectedListener;
private TextView mTvConfirm;
public TimePickerView(Context context) {
this(context, null);
}
public TimePickerView(Context context, AttributeSet attrs) {
super(context, attrs);
initView(context);
initDate();
initListener();
}
private void initView(Context context) {
LayoutInflater.from(getContext()).inflate(R.layout.layout_time_picker, this);
mWvYear = (WheelView) findViewById(R.id.year);
mWvMonth = (WheelView) findViewById(R.id.month);
mWvDay = (WheelView) findViewById(R.id.day);
mTvConfirm = (TextView) findViewById(R.id.tv_btn_confirm);
}
private void initDate(){
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault());
String[] split = sdf.format(new Date()).split("-");
int currentYear = Integer.parseInt(split[0]);
int currentMonth = Integer.parseInt(split[1]);
int currentDay = Integer.parseInt(split[2]);
mWvYear.setData(getYearData(currentYear));
mWvYear.setDefault(1);
mWvMonth.setData(getMonthData());
mWvMonth.setDefault(currentMonth - 1);
mWvDay.setData(getDayData(getMaxDay(currentYear, currentMonth)));
mWvDay.setDefault(currentDay - 1);
}
private void initListener(){
mTvConfirm.setOnClickListener(this);
mWvYear.setOnSelectListener(new WheelView.OnSelectListener() {
@Override
public void endSelect(int id, String text) {
changeDayData();
}
@Override
public void selecting(int id, String text) {
}
});
mWvMonth.setOnSelectListener(new WheelView.OnSelectListener() {
@Override
public void endSelect(int id, String text) {
changeDayData();
}
@Override
public void selecting(int id, String text) {
}
});
}
private ArrayList<String> getYearData(int currentYear) {
ArrayList<String> list = new ArrayList<>();
for (int i = currentYear + 1; i >= 1900; i--) {
list.add(String.valueOf(i));
}
return list;
}
private ArrayList<String> getMonthData() {
ArrayList<String> list = new ArrayList<>();
for (int i = 1; i <= 12; i++) {
list.add(String.valueOf(i));
}
return list;
}
private ArrayList<String> getDayData(int maxDay){
ArrayList<String> list = new ArrayList<>();
for (int i=1;i <= maxDay;i++){
list.add(String.valueOf(i));
}
return list;
}
private int getMaxDay(int year,int month){
if (month == 2){
if (isLeapYear(year)){
return 29;
}else {
return 28;
}
}else if (month == 1 || month == 3 || month == 5 || month == 7
|| month == 8 || month ==10 || month == 12){
return 31;
}else {
return 30;
}
}
private boolean isLeapYear(int year){
return (year % 100 == 0 && year % 400 == 0)
|| (year % 100 != 0 && year % 4 == 0);
}
private void changeDayData(){
int selectDay = getDay();
int currentYear = getYear();
int currentMonth = getMonth();
int maxDay = getMaxDay(currentYear,currentMonth);
mWvDay.setData(getDayData(maxDay));
if (selectDay > maxDay){
mWvDay.setDefault(maxDay - 1);
}else {
mWvDay.setDefault(selectDay - 1);
}
}
public int getYear(){
return Integer.parseInt(mWvYear.getSelectedText());
}
public int getMonth(){
return Integer.parseInt(mWvMonth.getSelectedText());
}
public int getDay(){
return Integer.parseInt(mWvDay.getSelectedText());
}
public void setSelectedListener(OnDateSelectedListener listener){
this.mSelectedListener = listener;
}
@Override
public void onClick(View v) {
if (v.getId() == R.id.tv_btn_confirm){
if (mSelectedListener != null){
mSelectedListener.selectedDate(getYear(), getMonth(),getDay());
}
}
}
public interface OnDateSelectedListener{
void selectedDate(int year, int month, int day);
}
}
写完TimePicker可以开始写AccountInfoActivity中设置生日
(1)实例化dialog_select_birthday.xml,利用AlertDialog创建
(2)在timePickerView上添加选择监听器
根据一定格式显示(若年份或月份是1-9之间的,显示时前面加0)
若与设置前发生变化,个人账户信息设置为现在新设置的,并设置为已发生改变
<?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="vertical">
<com.ezreal.ezchat.timeselectview.TimePickerView
android:id="@+id/date_picker"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
(2)
private void setBirthday() {
View view = LayoutInflater.from(this).inflate(R.layout.dialog_select_birthday, null);
final AlertDialog dialog = new AlertDialog.Builder(this).setView(view).create();
TimePickerView timePickerView = (TimePickerView) view.findViewById(R.id.date_picker);
timePickerView.setSelectedListener(new TimePickerView.OnDateSelectedListener() {
@Override
public void selectedDate(int year, int month, int day) {
String yearString = String.valueOf(year);
String monthString = String.valueOf(month);
String dayString = String.valueOf(day);
if (monthString.length() == 1){
monthString = "0" + monthString;
}
if (dayString.length() == 1){
dayString = "0" + dayString;
}
String birthday = String.format("%s-%s-%s", yearString, monthString, dayString);
if (!birthday.equals(mTvBirthDay.getText().toString())) {
mAccountBean.setBirthDay(birthday);
mTvBirthDay.setText(birthday);
haveAccountChange = true;
}
dialog.dismiss();
}
});
dialog.show();
}
二. CityPickerView——用于设置地区
1. layout_city_picker.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:orientation="horizontal"
android:padding="10dp">
<com.ezreal.ezchat.timeselectview.WheelView
android:id="@+id/province_wv"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
app:itemNumber="3"
app:lineColor="@color/default_line_color"
app:lineHeight="2dp"
app:maskHeight="32dp"
app:noEmpty="true"
app:normalTextColor="@color/default_unSelect_text_color"
app:normalTextSize="14sp"
app:selectedTextColor="@color/default_selected_text_color"
app:selectedTextSize="18sp"
app:unitHeight="50dp"/>
<View
android:layout_width="2dp"
android:layout_height="40dp"/>
<com.ezreal.ezchat.timeselectview.WheelView
android:id="@+id/city_wv"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
app:itemNumber="3"
app:lineColor="@color/default_line_color"
app:lineHeight="2dp"
app:maskHeight="32dp"
app:noEmpty="true"
app:normalTextColor="@color/default_unSelect_text_color"
app:normalTextSize="14sp"
app:selectedTextColor="@color/default_selected_text_color"
app:selectedTextSize="18sp"
app:unitHeight="50dp"/>
</LinearLayout>
<TextView
android:id="@+id/tv_btn_confirm"
android:layout_marginTop="10dp"
android:gravity="center"
android:layout_width="match_parent"
android:layout_height="30dp"
android:textSize="18sp"
android:textColor="@color/white_color"
android:background="@color/default_selected_text_color"
android:text="@string/confirm"/>
</LinearLayout>
2. 当View中所有子控件均被映射成xml后触发
(1)为“确定”TextView添加OnClickListener,初始化滚轮控件省份选择和城市选择并为其设置初始显示(即用户进行地区设置时所看到的,北京 西城区)
(2)为mProvincePick添加选择监听器
根据指定id从mAreaDataUtil(全国省份城市操作类)中取出所选择的省
此时,城市还没选择,默认显示为a. 若该省份城市数大于1,默认显示城市为第二个
b. 若该省份城市数为1,默认显示城市为第一个
(3)为mCityPicker添加选择监听器
根据指定id设置
protected void onFinishInflate() {
super.onFinishInflate();
LayoutInflater.from(getContext()).inflate(R.layout.layout_city_picker, this);
mTvConfirm = (TextView) findViewById(R.id.tv_btn_confirm);
mTvConfirm.setOnClickListener(this);
mProvincePicker = (WheelView) findViewById(R.id.province_wv);
mCityPicker = (WheelView) findViewById(R.id.city_wv);
mProvincePicker.setData(mProvinceList);
mProvincePicker.setDefault(0);
String defaultProvince = mProvinceList.get(0);
mCityPicker.setData(mAreaDataUtil.getCityByProvince(defaultProvince));
mCityPicker.setDefault(1);
mProvincePicker.setOnSelectListener(new WheelView.OnSelectListener() {
@Override
public void endSelect(int id, String text) {
if (text.equals("") || text == null)
return;
if (mCurrProvinceIndex != id) {
mCurrProvinceIndex = id;
String selectProvince = mProvincePicker.getSelectedText();
if (selectProvince == null || selectProvince.equals(""))
return;
// get city names by province
ArrayList<String> city = mAreaDataUtil.getCityByProvince(mProvinceList.get(id));
if (city.size() == 0) {
return;
}
mCityPicker.setData(city);
if (city.size() > 1) {
//if city is more than one,show start index == 1
mCityPicker.setDefault(1);
} else {
mCityPicker.setDefault(0);
}
}
}
@Override
public void selecting(int id, String text) {
}
});
mCityPicker.setOnSelectListener(new WheelView.OnSelectListener() {
@Override
public void endSelect(int id, String text) {
if (text.equals("") || text == null)
return;
if (mCurrCityIndex != id) {
mCurrCityIndex = id;
String selectCity = mCityPicker.getSelectedText();
if (selectCity == null || selectCity.equals(""))
return;
int lastIndex = Integer.valueOf(mCityPicker.getListSize());
if (id > lastIndex) {
mCityPicker.setDefault(lastIndex - 1);
}
}
}
@Override
public void selecting(int id, String text) {
}
});
}
附上完整CityPickerView.java
package com.ezreal.ezchat.timeselectview;
import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.ezreal.ezchat.R;
import java.util.ArrayList;
/**
* Created by 张静
*/
public class CityPickerView extends LinearLayout implements View.OnClickListener{
private WheelView mProvincePicker;
private WheelView mCityPicker;
private int mCurrProvinceIndex = -1;
private int mCurrCityIndex = -1;
private AreaDataUtil mAreaDataUtil;
private ArrayList<String> mProvinceList = new ArrayList<>();
private TextView mTvConfirm;
private OnCitySelectedListener mSelectedListener;
public CityPickerView(Context context, AttributeSet attrs) {
super(context, attrs);
getAreaInfo();
}
public CityPickerView(Context context) {
this(context, null);
}
private void getAreaInfo() {
mAreaDataUtil = new AreaDataUtil(getContext());
mProvinceList = mAreaDataUtil.getProvinces();
}
@Override
public void onClick(View v) {
if (v.getId() == R.id.tv_btn_confirm){
if (mSelectedListener != null){
mSelectedListener.citySelected(getProvince(),getCity());
}
}
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
LayoutInflater.from(getContext()).inflate(R.layout.layout_city_picker, this);
mTvConfirm = (TextView) findViewById(R.id.tv_btn_confirm);
mTvConfirm.setOnClickListener(this);
mProvincePicker = (WheelView) findViewById(R.id.province_wv);
mCityPicker = (WheelView) findViewById(R.id.city_wv);
mProvincePicker.setData(mProvinceList);
mProvincePicker.setDefault(0);
String defaultProvince = mProvinceList.get(0);
mCityPicker.setData(mAreaDataUtil.getCityByProvince(defaultProvince));
mCityPicker.setDefault(1);
mProvincePicker.setOnSelectListener(new WheelView.OnSelectListener() {
@Override
public void endSelect(int id, String text) {
if (text.equals("") || text == null)
return;
if (mCurrProvinceIndex != id) {
mCurrProvinceIndex = id;
String selectProvince = mProvincePicker.getSelectedText();
if (selectProvince == null || selectProvince.equals(""))
return;
// get city names by province
ArrayList<String> city = mAreaDataUtil.getCityByProvince(mProvinceList.get(id));
if (city.size() == 0) {
return;
}
mCityPicker.setData(city);
if (city.size() > 1) {
//if city is more than one,show start index == 1
mCityPicker.setDefault(1);
} else {
mCityPicker.setDefault(0);
}
}
}
@Override
public void selecting(int id, String text) {
}
});
mCityPicker.setOnSelectListener(new WheelView.OnSelectListener() {
@Override
public void endSelect(int id, String text) {
if (text.equals("") || text == null)
return;
if (mCurrCityIndex != id) {
mCurrCityIndex = id;
String selectCity = mCityPicker.getSelectedText();
if (selectCity == null || selectCity.equals(""))
return;
int lastIndex = Integer.valueOf(mCityPicker.getListSize());
if (id > lastIndex) {
mCityPicker.setDefault(lastIndex - 1);
}
}
}
@Override
public void selecting(int id, String text) {
}
});
}
public String getProvince() {
if (mProvincePicker == null) {
return null;
}
return mProvincePicker.getSelectedText();
}
public String getCity() {
if (mCityPicker == null) {
return null;
}
return mCityPicker.getSelectedText();
}
public void setCitySelectedListener(OnCitySelectedListener listener){
this.mSelectedListener = listener;
}
public interface OnCitySelectedListener{
void citySelected(String province, String city);
}
}
其中,AreaDataUtil——全国省份城市操作类
package com.ezreal.ezchat.timeselectview;
import android.content.Context;
import com.ezreal.ezchat.R;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
/**
* 全国省份城市操作类
*
* @author 张静
*/
public class AreaDataUtil {
/**
* 所有的省市String
*/
public String AREAS_DATA;
/**
* 一个省份对应多个城市
*/
private String[] single_province_city;
/**
* 全国省市Map key:省份 |Value:城市集合
*/
private HashMap<String, List<String>> mCityMap = new HashMap<>();
public AreaDataUtil(Context context) {
AREAS_DATA = context.getResources().getString(R.string.province_and_city);
splitProvince();
getAllCityMap();
}
/**
* 将省份和对应城市分割出来
* <p/>
* 得到:宁夏!!银川!石嘴山!吴忠!固原
*/
private void splitProvince() {
single_province_city = AREAS_DATA.split("!!!");
}
/**
* 获得全国省份的列表
*
* @return
*/
public ArrayList<String> getProvinces() {
ArrayList<String> provinceList = new ArrayList<>();
for (String str : single_province_city) {
String province = str.split("!!")[0];
provinceList.add(province);
}
return provinceList;
}
/**
* 根据省份获取城市列表
*
* @return
*/
private void getAllCityMap() {
for (String str : single_province_city) {
// 得到省份
String province = str.split("!!")[0];
// 得到当前省份对应的城市
String city = str.split("!!")[1];
// 分离城市放入集合
List<String> cityList = Arrays.asList(city.split("!"));
// 省份和城市放入Map中
mCityMap.put(province, cityList);
}
}
/**
* 根据省份查找对应的城市列表
*
* @return 城市集合
*/
public ArrayList<String> getCityByProvince(String provinceStr) {
List<String> list = mCityMap.get(provinceStr);
ArrayList<String> arrList = new ArrayList<>();
for (String city : list) {
arrList.add(city);
}
return arrList;
}
}
写完CityPickerView可以开始写AccountInfoActivity中的设置地区方法
(1)实例化dialog_select_location.xml,并利用AlertDialog创建
<?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="vertical">
<com.ezreal.ezchat.timeselectview.CityPickerView
android:id="@+id/city_picker"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
(2)将设置完后的地区信息与原信息比对,若发生变化,则在个人账户信息中保存新设置,并设置已发生变化
private void setLocation(){
View view = LayoutInflater.from(this).inflate(R.layout.dialog_select_location, null);
final AlertDialog dialog = new AlertDialog.Builder(this).setView(view).create();
CityPickerView cityPickerView = (CityPickerView) view.findViewById(R.id.city_picker);
cityPickerView.setCitySelectedListener(new CityPickerView.OnCitySelectedListener() {
@Override
public void citySelected(String province, String city) {
String location = province + "/" + city;
if (!location.equals(mTvLocation.getText().toString())) {
mAccountBean.setLocation(location);
mTvLocation.setText(location);
haveAccountChange = true;
}
dialog.dismiss();
}
});
dialog.show();
}
三. 完整AccountInfoActivity.java
package com.ezreal.ezchat.activity;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.support.annotation.Nullable;
import android.support.v7.app.AlertDialog;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.RelativeLayout;
import android.widget.TextView;
import com.ezreal.ezchat.R;
import com.ezreal.ezchat.bean.LocalAccountBean;
import com.ezreal.ezchat.handler.NimUserHandler;
import com.ezreal.ezchat.utils.Constant;
import com.ezreal.ezchat.timeselectview.CityPickerView;
import com.ezreal.ezchat.timeselectview.TimePickerView;
import com.joooonho.SelectableRoundedImageView;
import com.netease.nimlib.sdk.AbortableFuture;
import com.netease.nimlib.sdk.NIMClient;
import com.netease.nimlib.sdk.RequestCallback;
import com.netease.nimlib.sdk.nos.NosService;
import com.netease.nimlib.sdk.uinfo.constant.GenderEnum;
import com.ezreal.ezchat.commonlibrary.utils.ImageUtils;
import com.ezreal.ezchat.commonlibrary.utils.TextUtils;
import com.ezreal.ezchat.commonlibrary.utils.ToastUtils;
import java.io.File;
import butterknife.BindView;
import butterknife.ButterKnife;
import io.reactivex.Flowable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.functions.Consumer;
import io.reactivex.functions.Function;
import io.reactivex.schedulers.Schedulers;
/**
* 账号信息详情页
* Created by 张静.
*/
public class AccountInfoActivity extends BaseActivity implements View.OnClickListener, View.OnTouchListener {
private static final String TAG = AccountInfoActivity.class.getSimpleName();
@BindView(R.id.layout_head)
RelativeLayout mLayoutHead;
@BindView(R.id.iv_head_picture)
SelectableRoundedImageView mIvHead;
@BindView(R.id.tv_account)
TextView mTvAccount;
@BindView(R.id.et_account_nick)
EditText mEtNick;
@BindView(R.id.tv_account_sex)
TextView mTvSex;
@BindView(R.id.tv_account_birth)
TextView mTvBirthDay;
@BindView(R.id.tv_account_location)
TextView mTvLocation;
@BindView(R.id.et_account_signature)
EditText mEtSignature;
// 个人信息
private LocalAccountBean mAccountBean;
// 头像本地路径
private String mHeadImgPath = "";
// 获取图像请求码
private static final int SELECT_PHOTO = 30000;
private static final int TAKE_PHOTO = 30001;
// 信息是否有被更新
private boolean haveAccountChange = false;
// 是否处于编辑状态
private boolean isEditor;
// 输入服务,用于显示键盘
private InputMethodManager mInputMethodManager;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setStatusBarColor(R.color.app_blue_color);
setContentView(R.layout.activity_account_info);
setTitleBar("个人信息", true, true);
ButterKnife.bind(this);
showData();
init();
}
// 显示数据
private void showData() {
mAccountBean = NimUserHandler.getInstance().getLocalAccount();
if (mAccountBean != null) {
ImageUtils.setImageByFile(this, mIvHead,
mAccountBean.getHeadImgUrl(), R.mipmap.bg_img_defalut);
mTvAccount.setText(mAccountBean.getAccount());
mEtNick.setText(mAccountBean.getNick());
if (mAccountBean.getGenderEnum() == GenderEnum.FEMALE) {
mTvSex.setText("女");
} else if (mAccountBean.getGenderEnum() == GenderEnum.MALE) {
mTvSex.setText("男");
} else {
mTvSex.setText("保密");
}
mEtSignature.setText(mAccountBean.getSignature());
String birthday = mAccountBean.getBirthDay();
if (TextUtils.isEmpty(birthday)) {
mTvBirthDay.setText("未设置");
} else {
mTvBirthDay.setText(birthday);
}
String location = mAccountBean.getLocation();
if (TextUtils.isEmpty(location)) {
mTvLocation.setText("未设置");
} else {
mTvLocation.setText(location);
}
}
}
private void init() {
mInputMethodManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
// 文字
mLayoutHead.setOnClickListener(this);
mTvSex.setOnClickListener(this);
mTvBirthDay.setOnClickListener(this);
mTvLocation.setOnClickListener(this);
// 标题栏
mIvBack.setOnClickListener(this);
mIvMenu.setOnClickListener(this);
// 输入框
mEtNick.setOnTouchListener(this);
mEtSignature.setOnTouchListener(this);
// 结束编辑,相当于初始化为非编辑状态
finishEdit();
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.layout_head:
setHeadImg();
break;
case R.id.tv_account_sex:
setSex();
break;
case R.id.tv_account_location:
setLocation();
break;
case R.id.tv_account_birth:
setBirthday();
break;
case R.id.iv_back_btn:
this.finish();
break;
case R.id.iv_menu_btn:
if (isEditor) {
finishEdit();
} else {
startEdit();
}
break;
}
}
// EditText 获取焦点并将光标移动到末尾
@Override
public boolean onTouch(View v, MotionEvent event) {
if (isEditor) {
if (v.getId() == R.id.et_account_nick) {
mEtNick.requestFocus();
mEtNick.setSelection(mEtNick.getText().length());
mInputMethodManager.showSoftInput(mEtNick, 0);
} else if (v.getId() == R.id.et_account_signature) {
mEtSignature.requestFocus();
mEtSignature.setSelection(mEtSignature.getText().length());
mInputMethodManager.showSoftInput(mEtSignature, 0);
}
return true;
}
return false;
}
/**
* 启动编辑
*/
private void startEdit() {
mIvMenu.setImageResource(R.mipmap.done);
// 可点击
mLayoutHead.setClickable(true);
mTvSex.setClickable(true);
mTvLocation.setClickable(true);
mTvBirthDay.setClickable(true);
// 可编辑
mEtNick.setFocusable(true);
mEtNick.setFocusableInTouchMode(true);
mEtSignature.setFocusable(true);
mEtSignature.setFocusableInTouchMode(true);
isEditor = true;
}
/**
* 结束编辑,判断是否有修改,决定是否同步缓存数据
*/
private void finishEdit() {
if (!mEtNick.getText().toString()
.equals(mAccountBean.getNick())) {
mAccountBean.setNick(mEtNick.getText().toString());
haveAccountChange = true;
}
if (!mEtSignature.getText().toString()
.equals(mAccountBean.getSignature())) {
mAccountBean.setSignature(mEtSignature.getText().toString());
haveAccountChange = true;
}
if (haveAccountChange) {
// 将数据更新到缓存
NimUserHandler.getInstance().setLocalAccount(mAccountBean);
// 通知handler将数据更新到服务器
NimUserHandler.getInstance().syncChange2Service();
haveAccountChange = false;
}
mIvMenu.setImageResource(R.mipmap.editor);
// 不可点击
mLayoutHead.setClickable(false);
mTvSex.setClickable(false);
mTvLocation.setClickable(false);
mTvBirthDay.setClickable(false);
// 不可编辑
mEtNick.setFocusable(false);
mEtNick.setFocusableInTouchMode(false);
mEtSignature.setFocusable(false);
mEtSignature.setFocusableInTouchMode(false);
isEditor = false;
}
/**
* 设置性别
*/
private void setSex(){
final int[] selected = new int[1];
if (mAccountBean.getGenderEnum() == GenderEnum.MALE) {
selected[0] = 0;
} else if (mAccountBean.getGenderEnum() == GenderEnum.FEMALE) {
selected[0] = 1;
} else {
selected[0] = 2;
}
final String[] items = new String[]{"男", "女", "保密"};
new AlertDialog.Builder(this)
.setTitle("性别")
.setSingleChoiceItems(items, selected[0], new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (which != selected[0]) {
if (which == 0) {
mAccountBean.setGenderEnum(GenderEnum.MALE);
mTvSex.setText("男");
} else if (which == 1) {
mAccountBean.setGenderEnum(GenderEnum.FEMALE);
mTvSex.setText("女");
} else {
mAccountBean.setGenderEnum(GenderEnum.UNKNOWN);
mTvSex.setText("保密");
}
haveAccountChange = true;
}
dialog.dismiss();
}
}).create().show();
}
/**
* 设置生日
*/
private void setBirthday() {
View view = LayoutInflater.from(this).inflate(R.layout.dialog_select_birthday, null);
final AlertDialog dialog = new AlertDialog.Builder(this).setView(view).create();
TimePickerView timePickerView = (TimePickerView) view.findViewById(R.id.date_picker);
timePickerView.setSelectedListener(new TimePickerView.OnDateSelectedListener() {
@Override
public void selectedDate(int year, int month, int day) {
String yearString = String.valueOf(year);
String monthString = String.valueOf(month);
String dayString = String.valueOf(day);
if (monthString.length() == 1){
monthString = "0" + monthString;
}
if (dayString.length() == 1){
dayString = "0" + dayString;
}
String birthday = String.format("%s-%s-%s", yearString, monthString, dayString);
if (!birthday.equals(mTvBirthDay.getText().toString())) {
mAccountBean.setBirthDay(birthday);
mTvBirthDay.setText(birthday);
haveAccountChange = true;
}
dialog.dismiss();
}
});
dialog.show();
}
/**
* 设置地区
*/
private void setLocation(){
View view = LayoutInflater.from(this).inflate(R.layout.dialog_select_location, null);
final AlertDialog dialog = new AlertDialog.Builder(this).setView(view).create();
CityPickerView cityPickerView = (CityPickerView) view.findViewById(R.id.city_picker);
cityPickerView.setCitySelectedListener(new CityPickerView.OnCitySelectedListener() {
@Override
public void citySelected(String province, String city) {
String location = province + "/" + city;
if (!location.equals(mTvLocation.getText().toString())) {
mAccountBean.setLocation(location);
mTvLocation.setText(location);
haveAccountChange = true;
}
dialog.dismiss();
}
});
dialog.show();
}
/**
* 设置头像,拍照或选择照片
*/
private void setHeadImg() {
View view = LayoutInflater.from(this).inflate(R.layout.dialog_set_head_img, null);
final AlertDialog alertDialog = new AlertDialog.Builder(this).setView(view).create();
TextView take = (TextView) view.findViewById(R.id.tv_take_photo);
TextView select = (TextView) view.findViewById(R.id.tv_select_img);
take.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
alertDialog.dismiss();
try {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
mHeadImgPath = Constant.APP_CACHE_PATH + File.separator + "image"
+ File.separator + mAccountBean.getAccount() + ".jpg";
Uri uri = Uri.fromFile(new File(mHeadImgPath));
intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);//设置图像文件名
startActivityForResult(intent, TAKE_PHOTO);
} catch (Exception e) {
ToastUtils.showMessage(AccountInfoActivity.this, "启动相机出错!请重试");
e.printStackTrace();
}
}
});
select.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
alertDialog.dismiss();
Intent intent = new Intent(Intent.ACTION_PICK,
MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
intent.setType("image/*");
startActivityForResult(Intent.createChooser(intent, "选择头像图片"), SELECT_PHOTO);
}
});
alertDialog.show();
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
if (requestCode == TAKE_PHOTO) {
dealTakePhotoResult();
} else if (requestCode == SELECT_PHOTO) {
mHeadImgPath = ImageUtils.getFilePathFromUri(AccountInfoActivity.this, data.getData());
dealTakePhotoResult();
}
}
}
/**
* 处理拍照回传数据
*/
private void dealTakePhotoResult() {
Flowable.just(mHeadImgPath)
.map(new Function<String, Bitmap>() {
@Override
public Bitmap apply(String path) throws Exception {
// 调整旋转角度,压缩
int bitmapDegree = ImageUtils.getBitmapDegree(mHeadImgPath);
Bitmap bitmap = ImageUtils.getBitmapFromFile(mHeadImgPath, 600, 400);
bitmap = ImageUtils.rotateBitmapByDegree(bitmap, bitmapDegree);
ImageUtils.saveBitmap2Jpg(bitmap, path);
return bitmap;
}
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer<Bitmap>() {
@Override
public void accept(Bitmap bitmap) throws Exception {
// 显示,记录更新,同步至网易云服务器
if (bitmap != null) {
// 上传至服务器
uploadHeadImg(bitmap);
}
}
});
}
/**
* 将头像数据上传至网易云服务器存储,获取服务器返回URL
*/
private void uploadHeadImg(final Bitmap bitmap) {
AbortableFuture<String> upload = NIMClient.getService(NosService.class)
.upload(new File(mHeadImgPath), "image/ipeg");
upload.setCallback(new RequestCallback() {
@Override
public void onSuccess(Object param) {
Log.e(TAG,"uploadHeadImg onSuccess url = " + param.toString());
mIvHead.setImageBitmap(bitmap);
// 保存图片本地路径和服务器路径
mAccountBean.setHeadImgUrl(param.toString());
haveAccountChange = true;
}
@Override
public void onFailed(int code) {
Log.e(TAG,"uploadHeadImg onFailed code " + code);
ToastUtils.showMessage(AccountInfoActivity.this,
"修改失败,头像上传失败,code:" + code);
}
@Override
public void onException(Throwable exception) {
Log.e(TAG,"uploadHeadImg onException message " + exception.getMessage());
ToastUtils.showMessage(AccountInfoActivity.this,
"修改失败,图像上传出错:" + exception.getMessage());
}
});
}
}