实训第七周(2)

接下来完成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());
            }
        });
    }

}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值