nilupeng
2022-08-11 5479c528b0ce8f210ef71898a026f662f4275f08
签到
金币账户设置
10 files added
5 files modified
1204 ■■■■■ changed files
app/src/main/AndroidManifest.xml 3 ●●●●● patch | view | raw | blame | history
app/src/main/java/com/runt/open/mvvm/data/Results.java 42 ●●●●● patch | view | raw | blame | history
app/src/main/java/com/runt/open/mvvm/retrofit/api/CommonApiCenter.java 30 ●●●● patch | view | raw | blame | history
app/src/main/java/com/runt/open/mvvm/ui/adapter/CalendarAdapter.java 58 ●●●●● patch | view | raw | blame | history
app/src/main/java/com/runt/open/mvvm/ui/coin/CoinSettingActivity.java 99 ●●●●● patch | view | raw | blame | history
app/src/main/java/com/runt/open/mvvm/ui/coin/CoinSettingViewModel.java 19 ●●●●● patch | view | raw | blame | history
app/src/main/java/com/runt/open/mvvm/ui/main/mine/MineFragment.java 10 ●●●● patch | view | raw | blame | history
app/src/main/java/com/runt/open/mvvm/ui/sign/SignInActivity.java 166 ●●●●● patch | view | raw | blame | history
app/src/main/java/com/runt/open/mvvm/ui/sign/SignInViewModel.java 28 ●●●●● patch | view | raw | blame | history
app/src/main/java/com/runt/open/mvvm/util/DatesUtil.java 379 ●●●●● patch | view | raw | blame | history
app/src/main/res/drawable/bg_gold_circle.xml 11 ●●●●● patch | view | raw | blame | history
app/src/main/res/layout/activity_setting_coin.xml 92 ●●●●● patch | view | raw | blame | history
app/src/main/res/layout/activity_signs.xml 245 ●●●●● patch | view | raw | blame | history
app/src/main/res/layout/item_calendar_day.xml 19 ●●●●● patch | view | raw | blame | history
app/src/main/res/values/styles.xml 3 ●●●● patch | view | raw | blame | history
app/src/main/AndroidManifest.xml
@@ -48,6 +48,9 @@
        <activity android:name=".ui.SettingActivity" />
        <activity android:name=".ui.AboutActivity" />
        <activity android:name=".ui.msg.MsgDetailActivity" />
        <activity android:name=".ui.sign.SignInActivity" />
        <activity android:name=".ui.coin.CoinSettingActivity" />
        <activity android:name=".ui.loadpage.PageActivitys$CoinRecordActivity" tools:ignore="Instantiatable"/>
    </application>
app/src/main/java/com/runt/open/mvvm/data/Results.java
@@ -2,6 +2,7 @@
import com.runt.open.mvvm.ui.login.UserBean;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
@@ -38,4 +39,45 @@
         **/
        public Object remark;
    }
    public static class Mycalendar {
        String day;
        int style;
        long dateTime;
        public String getDay() {
            return day;
        }
        public void setDay(String day) {
            this.day = day;
        }
        public int getStyle() {
            return style;
        }
        public void setStyle(int style) {
            this.style = style;
        }
        public long getDateTime() {
            return dateTime;
        }
        public void setDateTime(long dateTime) {
            this.dateTime = dateTime;
        }
        SimpleDateFormat datesdf = new SimpleDateFormat("yyyy-MM-dd");
        @Override
        public String toString() {
            return "Mycalendar{" +
                    "day='" + day + '\'' +
                    ", style=" + style +
                    ", dateTime=" + datesdf.format(new Date(dateTime)) +
                    '}';
        }
    }
}
app/src/main/java/com/runt/open/mvvm/retrofit/api/CommonApiCenter.java
@@ -8,6 +8,7 @@
import okhttp3.MultipartBody;
import retrofit2.http.*;
import java.util.List;
import java.util.Map;
/**
@@ -63,16 +64,6 @@
    @POST("updatehead")
    Observable<Results.StringApiResult> updateHead(@Part MultipartBody.Part file);
    /**
     * 获取咨询列表
     * @param pageNum   页数
     * @param pageSize  每页数量
     * @return
     */
    @GET("getMsgList")
    Observable<HttpApiResult<PageResult<Results.Message>>> getMsgList(@Query("page") int pageNum, @Query("size") int pageSize);
    /**
     * app更新
     * @return
@@ -80,12 +71,21 @@
    @GET("getMsgDetail")
    Observable<HttpApiResult<Results.Message>> getMsgDetail(@Query("id") String id);
    @POST("updateAlipay")
    Observable<Results.StringApiResult> updateAlipay(@Field("account") String account,@Field("paypass") String paypass);
    @POST("updateRealname")
    Observable<Results.StringApiResult> updateRealname(@Field("account") String account,@Field("paypass") String paypass);
    /**
     * 获取金币记录
     * @param pageNum   页数
     * @param pageSize  每页数量
     * 获取签到列表
     * @param month
     * @return
     */
    @GET("coinRecord")
    Observable<HttpApiResult<PageResult<Results.CustomCoin>>> getCoinRecord(@Query("page") int pageNum, @Query("size") int pageSize, @Query("inOrOut") int inOrOut);
    @GET("getSignsByMonth")
    Observable<HttpApiResult<List<String>>> getSignsByMonth(@Query("month") String month);
    @POST("signIn")
    Observable<Results.StringApiResult> signIn();
}
app/src/main/java/com/runt/open/mvvm/ui/adapter/CalendarAdapter.java
New file
@@ -0,0 +1,58 @@
package com.runt.open.mvvm.ui.adapter;
import android.widget.TextView;
import com.runt.open.mvvm.R;
import com.runt.open.mvvm.base.adapter.BaseAdapter;
import com.runt.open.mvvm.data.Results;
import com.runt.open.mvvm.databinding.ItemCalendarDayBinding;
import java.util.List;
/**
 * @purpose Created by Runt (qingingrunt2010@qq.com) on 2019-3-26.
 */
public class CalendarAdapter extends BaseAdapter<Results.Mycalendar, ItemCalendarDayBinding> {
    public CalendarAdapter(List<Results.Mycalendar> list) {
        this.dataList = list;
    }
    @Override
    protected void onBindView(ItemCalendarDayBinding binding, int position, Results.Mycalendar mycalendar) {
        TextView txt = binding.txtDay;
        txt.setTextColor(binding.getRoot().getContext().getResources().getColor(R.color.white));
        switch (mycalendar.getStyle()){
            case 0://已签到
                txt.setBackground(binding.getRoot().getContext().getResources().getDrawable(R.drawable.bg_blue_circle));
                break;
            case 1://当月未签到
                txt.setBackground(binding.getRoot().getContext().getResources().getDrawable(R.drawable.bg_enable_circle));
                break;
            case 2://今日
                txt.setBackground(binding.getRoot().getContext().getResources().getDrawable(R.drawable.bg_red_border_circle));
                txt.setTextColor(binding.getRoot().getContext().getResources().getColor(R.color.txt_normal));
                break;
            case 3://还未到
                txt.setBackgroundColor(binding.getRoot().getContext().getResources().getColor(R.color.white));
                txt.setTextColor(binding.getRoot().getContext().getResources().getColor(R.color.txt_normal));
                break;
            case 4://不是本月
                txt.setBackgroundColor(binding.getRoot().getContext().getResources().getColor(R.color.white));
                txt.setTextColor(binding.getRoot().getContext().getResources().getColor(R.color.txt_enable));
                break;
            case 5://领取金币
                txt.setBackground(binding.getRoot().getContext().getResources().getDrawable(R.drawable.bg_gold_circle));
                break;
            case 6://今日已签到
                txt.setBackground(binding.getRoot().getContext().getResources().getDrawable(R.drawable.bg_red_circle));
                //txt.setBackground(binding.getRoot().getContext().getResources().getDrawable(R.drawable.bg_blue_circle));
                break;
        }
        txt.setText(mycalendar.getDay());
    }
}
app/src/main/java/com/runt/open/mvvm/ui/coin/CoinSettingActivity.java
New file
@@ -0,0 +1,99 @@
package com.runt.open.mvvm.ui.coin;
import android.content.Intent;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import com.runt.open.mvvm.base.activities.BaseActivity;
import com.runt.open.mvvm.data.HttpApiResult;
import com.runt.open.mvvm.databinding.ActivitySettingCoinBinding;
import com.runt.open.mvvm.listener.ResPonse;
import com.runt.open.mvvm.retrofit.observable.HttpObserver;
import com.runt.open.mvvm.ui.login.UserBean;
/**
 * My father is Object, ites purpose of 金币交易设置
 *
 * @purpose Created by Runt (qingingrunt2010@qq.com) on 2020-10-30.
 */
public class CoinSettingActivity extends BaseActivity<ActivitySettingCoinBinding,CoinSettingViewModel> {
    private int requestCode = 0;
    @Override
    public void initViews() {
        ActivityResultLauncher<Intent>  launcher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> {
            if( result.getResultCode() == RESULT_OK){
                String pass = result.getData().getStringExtra("paypass");
                HttpObserver<String> observer = new HttpObserver<String>() {
                    @Override
                    protected void onSuccess(String data) {
                        if(REQUEST_CODE_PAYPASS_FOR_ALIPAY == requestCode ){
                            showToast("支付宝修改成功");
                            UserBean.getUser().setAlipay(mBinding.txtAlipay.getText().toString());
                        }else if(REQUEST_CODE_PAYPASS_FOR_REALNAME == requestCode ){
                            showToast("修改成功");
                            UserBean.getUser().setRealname(mBinding.txtRealname.getText().toString());
                        }
                    }
                    @Override
                    protected void onFailed(HttpApiResult error) {
                        super.onFailed(error);
                        loadData();
                        if(error.code == 621){
                            showDialog("设置支付密码", "当前账号还没有设置支付密码", "设置", "取消", new ResPonse() {
                                @Override
                                public void doSuccess(Object obj) {
                                    //startActivity(new Intent(mContext, PaypassActivity.class).putExtra("type", 1));//去设置密码
                                }
                            });
                        }
                    }
                };
                if(REQUEST_CODE_PAYPASS_FOR_ALIPAY == requestCode ){
                    mViewModel.updateAlipay(mBinding.txtAlipay.getText().toString(),pass,observer);
                }else if(REQUEST_CODE_PAYPASS_FOR_REALNAME == requestCode ){
                    mViewModel.updateName(mBinding.txtRealname.getText().toString(),pass,observer);
                }
            }
        });
        mBinding.linAlipay.setOnClickListener(v->{
            showInputDialog("修改支付宝账号", UserBean.getUser().getAlipay(), "请输入支付宝账号用于提现", new ResPonse() {
                @Override
                public void doSuccess(Object obj) {
                    mBinding.txtAlipay.setText(obj.toString());
                    requestCode = REQUEST_CODE_PAYPASS_FOR_ALIPAY;
                    //launcher.launch(new Intent(mContext, PaypassActivity.class));
                }
            });
        });
        mBinding.linRealname.setOnClickListener(v->{
            showInputDialog("修改真实姓名", UserBean.getUser().getRealname(), "请输入真实姓名用于提现", new ResPonse() {
                @Override
                public void doSuccess(Object obj) {
                    requestCode = REQUEST_CODE_PAYPASS_FOR_REALNAME;
                    mBinding.txtRealname.setText(obj.toString());
                    //launcher.launch(new Intent(mContext, PaypassActivity.class));
                }
            });
        });
        mBinding.linPass.setOnClickListener(v->{
            //startActivity(new Intent(mContext,PaypassActivity.class).putExtra("type",1));
        });
    }
    @Override
    public void loadData() {
        if(UserBean.getUser().getAlipay()!=null){
            mBinding.txtAlipay.setText(UserBean.getUser().getAlipay());
        }else{
            mBinding.txtAlipay.setText("");
        }
        if(UserBean.getUser().getRealname() != null){
            mBinding.txtRealname.setText(UserBean.getUser().getRealname());
        }else{
            mBinding.txtRealname.setText("");
        }
    }
}
app/src/main/java/com/runt/open/mvvm/ui/coin/CoinSettingViewModel.java
New file
@@ -0,0 +1,19 @@
package com.runt.open.mvvm.ui.coin;
import com.runt.open.mvvm.base.model.BaseViewModel;
import com.runt.open.mvvm.retrofit.observable.HttpObserver;
/**
 * @purpose Created by Runt (qingingrunt2010@qq.com) on 2019-3-26.
 */
public class CoinSettingViewModel extends BaseViewModel {
    public void updateName(String name,String pass, HttpObserver<String> httpObserver){
        httpObserverOnLoading(commonApi.updateRealname(name,pass),httpObserver);
    }
    public void updateAlipay(String alipay,String pass, HttpObserver<String> httpObserver){
        httpObserverOnLoading(commonApi.updateAlipay(alipay,pass),httpObserver);
    }
}
app/src/main/java/com/runt/open/mvvm/ui/main/mine/MineFragment.java
@@ -5,6 +5,8 @@
import android.content.pm.ActivityInfo;
import android.view.View;
import android.widget.TextView;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import com.bumptech.glide.Glide;
import com.bumptech.glide.request.RequestOptions;
import com.luck.picture.lib.PictureSelector;
@@ -17,8 +19,10 @@
import com.runt.open.mvvm.databinding.FragmentMineBinding;
import com.runt.open.mvvm.listener.ResPonse;
import com.runt.open.mvvm.retrofit.observable.HttpObserver;
import com.runt.open.mvvm.ui.coin.CoinSettingActivity;
import com.runt.open.mvvm.ui.loadpage.PageActivitys;
import com.runt.open.mvvm.ui.login.UserBean;
import com.runt.open.mvvm.ui.sign.SignInActivity;
import com.runt.open.mvvm.util.GlideEngine;
import com.runt.open.mvvm.util.MyLog;
import sakura.bottommenulibrary.bottompopfragmentmenu.BottomMenuFragment;
@@ -36,7 +40,9 @@
public class MineFragment extends BaseFragment<FragmentMineBinding,MineViewModel> implements View.OnClickListener {
    private final  String TAG = "MineFragment";
    ActivityResultLauncher<Intent> signLaunch = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> {
    });
    @Override
    public void initViews() {
    }
@@ -103,7 +109,7 @@
                                            }
                                        });
                                    }else{
                                        startActivityForResult(new Intent(mActivity, WithDrawActivity.class),REQUEST_CODE_WITHDRAW );
                                        //startActivityForResult(new Intent(mActivity, WithDrawActivity.class),REQUEST_CODE_WITHDRAW );
                                    }
                                }
                            }
@@ -111,7 +117,7 @@
                        .show();
                break;
            case R.id.lin_sign://签到
                startActivityForResult(new Intent(getContext(), SignInActivity.class),REQUEST_CODE_SIGN);
                signLaunch.launch(new Intent(getContext(), SignInActivity.class));
                break;
        }
    }
app/src/main/java/com/runt/open/mvvm/ui/sign/SignInActivity.java
New file
@@ -0,0 +1,166 @@
package com.runt.open.mvvm.ui.sign;
import android.util.Log;
import androidx.recyclerview.widget.GridLayoutManager;
import com.runt.open.mvvm.base.activities.BaseActivity;
import com.runt.open.mvvm.data.HttpApiResult;
import com.runt.open.mvvm.data.Results;
import com.runt.open.mvvm.databinding.ActivitySignsBinding;
import com.runt.open.mvvm.retrofit.observable.HttpObserver;
import com.runt.open.mvvm.ui.adapter.CalendarAdapter;
import com.runt.open.mvvm.ui.login.UserBean;
import com.runt.open.mvvm.util.DatesUtil;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.TimeZone;
/**
 * @purpose Created by Runt (qingingrunt2010@qq.com) on 2019-3-26.
 */
public class SignInActivity extends BaseActivity<ActivitySignsBinding,SignInViewModel> {
    List<Results.Mycalendar> list = new ArrayList<>();
    CalendarAdapter adapter = new CalendarAdapter(list);
    SimpleDateFormat datesdf = new SimpleDateFormat("yyyy-MM-dd");
    SimpleDateFormat monthdf = new SimpleDateFormat("yyyy/MM");
    SimpleDateFormat secondsdf = new SimpleDateFormat("dd");
    int last = 0 ;
    HttpObserver<List<String>> observer = new HttpObserver<List<String>>() {
        @Override
        protected void onSuccess(List<String> data) {
            last = (int) mBinding.txtCalendarTitle.getTag();
            String today = datesdf.format(new Date());
            if(data.contains(today)){
                mBinding.btnSign.setText("已签到");
                mBinding.btnSign.setEnabled(false);
            }
            initCalendar(data);
            loadMothBtn(getStartDate());
        }
        @Override
        protected void onFailed(HttpApiResult error) {
            super.onFailed(error);
            loadMothBtn(getStartDate());
        }
    };
    @Override
    public void initViews() {
        mBinding.lastMonth.setOnClickListener(v->{
            v.setEnabled(false);
            mBinding.txtCalendarTitle.setTag(last - 1);
            mViewModel.getSigns(last-1,observer);
        });
        mBinding.nextMonth.setOnClickListener(v->{
            v.setEnabled(false);
            mBinding.txtCalendarTitle.setTag(last+ 1);
            mViewModel.getSigns(last+1,observer);;});
        mBinding.btnSign.setOnClickListener(v->{mViewModel.signIn(new HttpObserver<String>(this) {
            @Override
            protected void onSuccess(String data) {
                showToast("赠送金币"+data+"个");
                UserBean.getUser().setCoin(UserBean.getUser().getCoin()+Integer.parseInt(data.toString()));
                UserBean.getUser().setSign(UserBean.getUser().getSign()+1);
                mBinding.txtSigns.setText(UserBean.getUser().getSign()+"天");
                mBinding.btnSign.setEnabled(false);
                mBinding.btnSign.setText("已签到");
                setResult(RESULT_OK);
                mViewModel.getSigns(last,observer);
            }
            @Override
            protected void onFailed(HttpApiResult error) {
                super.onFailed(error);
                if(error.code == 610){
                    mBinding.btnSign.setEnabled(false);
                    mBinding.btnSign.setText("已签到");
                }
            }
        });});
        mBinding.recycler.setLayoutManager(new GridLayoutManager(mContext,7));
        mBinding.recycler.setAdapter(adapter);
    }
    @Override
    public void loadData() {
        initCalendar(new ArrayList<>());
        mBinding.txtCalendarTitle.setTag(last);
        mViewModel.getSigns(last,observer);
    }
    /**
     * 加载🗓
     * @param signList
     */
    private  void initCalendar(List<String> signList ){
        list.clear();
        Date startDate = getStartDate();
        Date endDate = DatesUtil.getEndDayOfMonth(DatesUtil.getNowMonth()+last);
        int days = (int) ((endDate.getTime() - startDate.getTime())/(60000*60*24));
        int week = DatesUtil.getWeekOfDate(startDate);
        long starttime = startDate.getTime()-((60000*60*24*week-1));
        int lastWeek = DatesUtil.getWeekOfDate(endDate);
        long endtime = endDate.getTime()+((60000*60*24*(6-lastWeek)));
        days+=week+1;
        days+=(6-lastWeek);
        int newDays = (int) ((endtime- starttime)/(60000*60*24));
        //Log.e(TAG,"days:"+days +" newDays:"+newDays+" month:"+(DatesUtil.getNowMonth()+last)+" endDate:"+datesdf.format(endDate));
        for(int i  = 0 ; i < days ; i ++ ){
            Results.Mycalendar calendar = new Results.Mycalendar();
            long dateTime = starttime+(i*(60000l*60*24));
            calendar.setDateTime(dateTime);
            calendar.setDay(secondsdf.format(new Date(dateTime)));
            /*if(coinList.contains(datesdf.format(new Date(dateTime)))){//是否赠送了金币
                calendar.setStyle(5);
            }else */if(dateTime < startDate.getTime() || dateTime > endDate.getTime()){//不是本月的日期
                calendar.setStyle(4);
            }else if(datesdf.format(new Date()).equals(datesdf.format(new Date(dateTime)))&& !signList.contains(datesdf.format(new Date(dateTime)))){//今天
                Log.e(TAG,"今天"+datesdf.format(new Date()));
                calendar.setStyle(2);
            }else if(datesdf.format(new Date()).equals(datesdf.format(new Date(dateTime)))&& signList.contains(datesdf.format(new Date(dateTime)))){//今天
                calendar.setStyle(6);
            }else if(new Date().getTime()<dateTime){//还没到的日期
                calendar.setStyle(3);
            }else if(signList.contains(datesdf.format(new Date(dateTime)))){//是否签到
                calendar.setStyle(0);
            }else{
                calendar.setStyle(1);
            }
            //Log.e(TAG,"day:"+datesdf.format(new Date(dateTime)) + " sign:"+signs.contains(datesdf.format(new Date(dateTime))));
            list.add(calendar);
        }
        adapter.notifyDataSetChanged();
        mBinding.txtCalendarTitle.setText(monthdf.format(startDate));
        loadMothBtn(startDate);
    }
    private Date getStartDate(){
        secondsdf.setTimeZone(TimeZone.getTimeZone("GMT+08:00"));
        datesdf.setTimeZone(TimeZone.getTimeZone("GMT+08:00"));
        return DatesUtil.getBeginDayOfMonth(DatesUtil.getNowMonth()+last);
    }
    private void loadMothBtn(Date startDate){
        try {
            if(monthdf.format(startDate).equals(monthdf.format(new Date()))|| new Date().getTime()<startDate.getTime()) {//超过指定日期禁止点击
                mBinding.nextMonth.setEnabled(false);
            }else{
                mBinding.nextMonth.setEnabled(true);
            }
            if(monthdf.format(startDate).equals("2021/09") || monthdf.parse("2021/09").getTime()>startDate.getTime()){//超过指定日期禁止点击
                mBinding.lastMonth.setEnabled(false);
            }else{
                mBinding.lastMonth.setEnabled(true);
            }
        } catch (ParseException e) {
            e.printStackTrace();
        }
    }
}
app/src/main/java/com/runt/open/mvvm/ui/sign/SignInViewModel.java
New file
@@ -0,0 +1,28 @@
package com.runt.open.mvvm.ui.sign;
import com.runt.open.mvvm.base.model.BaseViewModel;
import com.runt.open.mvvm.retrofit.observable.HttpObserver;
import com.runt.open.mvvm.util.DatesUtil;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
/**
 * @purpose Created by Runt (qingingrunt2010@qq.com) on 2019-3-26.
 */
public class SignInViewModel extends BaseViewModel {
    public void signIn(HttpObserver<String> observer){
        httpObserverOn(commonApi.signIn(),observer);
    }
    public void getSigns(int month,HttpObserver<List<String>> observer){
        SimpleDateFormat monthdf = new SimpleDateFormat("yyyy-MM");
        Date startDate = DatesUtil.getBeginDayOfMonth(DatesUtil.getNowMonth()+month);
        httpObserverOn(commonApi.getSignsByMonth(monthdf.format(startDate)),observer);
    }
}
app/src/main/java/com/runt/open/mvvm/util/DatesUtil.java
New file
@@ -0,0 +1,379 @@
package com.runt.open.mvvm.util;
import android.annotation.SuppressLint;
import java.sql.Timestamp;
import java.util.*;
/**
 * My father is Object, ites purpose of
 *
 * @purpose Created by Runt (qingingrunt2010@qq.com) on 2019-3-26.
 */
public class DatesUtil {
    /**
     * 获取当前日期是星期几<br>
     *
     * @param date
     * @return 当前日期是星期几    首日为星期日
     */
    public static int getWeekOfDate(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        int w = cal.get(Calendar.DAY_OF_WEEK) - 1;
        if (w < 0)
            w = 0;
        return w;
    }
    // 获取当天的开始时间
    public static Date getDayBegin() {
        Calendar cal = new GregorianCalendar();
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);
        return cal.getTime();
    }
    // 获取当天的结束时间
    public static Date getDayEnd() {
        Calendar cal = new GregorianCalendar();
        cal.set(Calendar.HOUR_OF_DAY, 23);
        cal.set(Calendar.MINUTE, 59);
        cal.set(Calendar.SECOND, 59);
        return cal.getTime();
    }
    // 获取昨天的开始时间
    public static Date getBeginDayOfYesterday() {
        Calendar cal = new GregorianCalendar();
        cal.setTime(getDayBegin());
        cal.add(Calendar.DAY_OF_MONTH, -1);
        return cal.getTime();
    }
    // 获取昨天的结束时间
    public static Date getEndDayOfYesterDay() {
        Calendar cal = new GregorianCalendar();
        cal.setTime(getDayEnd());
        cal.add(Calendar.DAY_OF_MONTH, -1);
        return cal.getTime();
    }
    // 获取明天的开始时间
    public static Date getBeginDayOfTomorrow() {
        Calendar cal = new GregorianCalendar();
        cal.setTime(getDayBegin());
        cal.add(Calendar.DAY_OF_MONTH, 1);
        return cal.getTime();
    }
    // 获取明天的结束时间
    public static Date getEndDayOfTomorrow() {
        Calendar cal = new GregorianCalendar();
        cal.setTime(getDayEnd());
        cal.add(Calendar.DAY_OF_MONTH, 1);
        return cal.getTime();
    }
    // 获取本周的开始时间
    @SuppressWarnings("unused")
    public static Date getBeginDayOfWeek() {
        Date date = new Date();
        if (date == null) {
            return null;
        }
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        int dayofweek = cal.get(Calendar.DAY_OF_WEEK);
        if (dayofweek == 1) {
            dayofweek += 7;
        }
        cal.add(Calendar.DATE, 2 - dayofweek);
        return getDayStartTime(cal.getTime());
    }
    // 获取本周的结束时间
    public static Date getEndDayOfWeek() {
        Calendar cal = Calendar.getInstance();
        cal.setTime(getBeginDayOfWeek());
        cal.add(Calendar.DAY_OF_WEEK, 6);
        Date weekEndSta = cal.getTime();
        return getDayEndTime(weekEndSta);
    }
    // 获取上周的开始时间
    @SuppressWarnings("unused")
    public static Date getBeginDayOfLastWeek() {
        Date date = new Date();
        if (date == null) {
            return null;
        }
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        int dayofweek = cal.get(Calendar.DAY_OF_WEEK);
        if (dayofweek == 1) {
            dayofweek += 7;
        }
        cal.add(Calendar.DATE, 2 - dayofweek - 7);
        return getDayStartTime(cal.getTime());
    }
    // 获取上周的结束时间
    public static Date getEndDayOfLastWeek() {
        Calendar cal = Calendar.getInstance();
        cal.setTime(getBeginDayOfLastWeek());
        cal.add(Calendar.DAY_OF_WEEK, 6);
        Date weekEndSta = cal.getTime();
        return getDayEndTime(weekEndSta);
    }
    // 获取本月的结束时间
    @SuppressLint("WrongConstant")
    public static Date getEndDayOfMonth() {
        Calendar calendar = Calendar.getInstance();
        calendar.set(getNowYear(), getNowMonth() - 1, 1);
        int day = calendar.getActualMaximum(5);
        calendar.set(getNowYear(), getNowMonth() - 1, day);
        return getDayEndTime(calendar.getTime());
    }
    // 获取当年某月的结束时间
    @SuppressLint("WrongConstant")
    public static Date getEndDayOfMonth(int month) {
        return getEndDayOfMonth(getNowYear(),month);
    }
    // 获取某年某月的结束时间
    @SuppressLint("WrongConstant")
    public static Date getEndDayOfMonth(int year,int month) {
        Calendar calendar = Calendar.getInstance();
        if(month <= 0){
            year-=(1+((Math.abs(month))/12));
            month = 12-(Math.abs(month)%12);
        }else if( month > 12){
            year +=(1+((Math.abs(month))/12));
            month = (Math.abs(month)%12);
        }
        calendar.set(year, month - 1, 1);
        int day = calendar.getActualMaximum(5);
        calendar.set(year, month - 1, day);
        return getDayEndTime(calendar.getTime());
    }
    // 获取某月的开始时间
    public static Date getBeginDayOfMonth(int month) {
        return getBeginDayOfMonth(getNowYear(),month);
    }
    // 获取某年某月的开始时间
    public static Date getBeginDayOfMonth(int year, int month) {
        Calendar calendar = Calendar.getInstance();
        if(month <= 0){
            year-=(1+((Math.abs(month))/12));
            month = 12-(Math.abs(month)%12);
        }else if( month > 12){
            year +=(1+((Math.abs(month))/12));
            month = (Math.abs(month)%12);
        }
        calendar.set(year, month-1, 1);
        return getDayStartTime(calendar.getTime());
    }
    // 获取上月的结束时间
    @SuppressLint("WrongConstant")
    public static Date getEndDayOfLastMonth() {
        Calendar calendar = Calendar.getInstance();
        calendar.set(getNowYear(), getNowMonth() - 2, 1);
        int day = calendar.getActualMaximum(5);
        calendar.set(getNowYear(), getNowMonth() - 2, day);
        return getDayEndTime(calendar.getTime());
    }
    /**
     * 获取当月多少天
     * @param year
     * @param month
     * @return
     */
    public static int getDaysOfMonth(int year,int month){
        Calendar c = Calendar.getInstance();
        c.set(year, month, 0); //输入类型为int类型
        return c.get(Calendar.DAY_OF_MONTH);
    }
    // 获取本年的开始时间
    public static Date getBeginDayOfYear() {
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.YEAR, getNowYear());
        cal.set(Calendar.MONTH, Calendar.JANUARY);
        cal.set(Calendar.DATE, 1);
        return getDayStartTime(cal.getTime());
    }
    // 获取本年的结束时间
    public static Date getEndDayOfYear() {
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.YEAR, getNowYear());
        cal.set(Calendar.MONTH, Calendar.DECEMBER);
        cal.set(Calendar.DATE, 31);
        return getDayEndTime(cal.getTime());
    }
    // 获取某个日期的开始时间
    public static Timestamp getDayStartTime(Date d) {
        Calendar calendar = Calendar.getInstance();
        if (null != d)
            calendar.setTime(d);
        calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH),
                calendar.get(Calendar.DAY_OF_MONTH), 0, 0, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return new Timestamp(calendar.getTimeInMillis());
    }
    // 获取某个日期的结束时间
    public static Timestamp getDayEndTime(Date d) {
        Calendar calendar = Calendar.getInstance();
        if (null != d)
            calendar.setTime(d);
        calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH),
                calendar.get(Calendar.DAY_OF_MONTH), 23, 59, 59);
        calendar.set(Calendar.MILLISECOND, 999);
        return new Timestamp(calendar.getTimeInMillis());
    }
    // 获取今年是哪一年
    @SuppressLint("WrongConstant")
    public static Integer getNowYear() {
        Date date = new Date();
        GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
        gc.setTime(date);
        return Integer.valueOf(gc.get(1));
    }
    // 获取本月是哪一月
    @SuppressLint("WrongConstant")
    public static int getNowMonth() {
        Date date = new Date();
        GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
        gc.setTime(date);
        return gc.get(2) + 1;
    }
    // 两个日期相减得到的天数
    public static int getDiffDays(Date beginDate, Date endDate) {
        if (beginDate == null || endDate == null) {
            throw new IllegalArgumentException("getDiffDays param is null!");
        }
        long diff = (endDate.getTime() - beginDate.getTime())
                / (1000 * 60 * 60 * 24);
        int days = new Long(diff).intValue();
        return days;
    }
    // 两个日期相减得到的毫秒数
    public static long dateDiff(Date beginDate, Date endDate) {
        long date1ms = beginDate.getTime();
        long date2ms = endDate.getTime();
        return date2ms - date1ms;
    }
    // 获取两个日期中的最大日期
    public static Date max(Date beginDate, Date endDate) {
        if (beginDate == null) {
            return endDate;
        }
        if (endDate == null) {
            return beginDate;
        }
        if (beginDate.after(endDate)) {
            return beginDate;
        }
        return endDate;
    }
    // 获取两个日期中的最小日期
    public static Date min(Date beginDate, Date endDate) {
        if (beginDate == null) {
            return endDate;
        }
        if (endDate == null) {
            return beginDate;
        }
        if (beginDate.after(endDate)) {
            return endDate;
        }
        return beginDate;
    }
    // 返回某月该季度的第一个月
    public static Date getFirstSeasonDate(Date date) {
        final int[] SEASON = { 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4 };
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        int sean = SEASON[cal.get(Calendar.MONTH)];
        cal.set(Calendar.MONTH, sean * 3 - 3);
        return cal.getTime();
    }
    // 返回某个日期下几天的日期
    public static Date getNextDay(Date date, int i) {
        Calendar cal = new GregorianCalendar();
        cal.setTime(date);
        cal.set(Calendar.DATE, cal.get(Calendar.DATE) + i);
        return cal.getTime();
    }
    // 返回某个日期前几天的日期
    public static Date getFrontDay(Date date, int i) {
        Calendar cal = new GregorianCalendar();
        cal.setTime(date);
        cal.set(Calendar.DATE, cal.get(Calendar.DATE) - i);
        return cal.getTime();
    }
    // 获取某年某月到某年某月按天的切片日期集合(间隔天数的集合)
    @SuppressWarnings({ "rawtypes", "unchecked" })
    public static List getTimeList(int beginYear, int beginMonth, int endYear,
                                   int endMonth, int k) {
        List list = new ArrayList();
        if (beginYear == endYear) {
            for (int j = beginMonth; j <= endMonth; j++) {
                list.add(getTimeList(beginYear, j, k));
            }
        } else {
            {
                for (int j = beginMonth; j < 12; j++) {
                    list.add(getTimeList(beginYear, j, k));
                }
                for (int i = beginYear + 1; i < endYear; i++) {
                    for (int j = 0; j < 12; j++) {
                        list.add(getTimeList(i, j, k));
                    }
                }
                for (int j = 0; j <= endMonth; j++) {
                    list.add(getTimeList(endYear, j, k));
                }
            }
        }
        return list;
    }
    // 获取某年某月按天切片日期集合(某个月间隔多少天的日期集合)
    @SuppressWarnings({ "unchecked", "rawtypes" })
    public static List getTimeList(int beginYear, int beginMonth, int k) {
        List list = new ArrayList();
        Calendar begincal = new GregorianCalendar(beginYear, beginMonth, 1);
        int max = begincal.getActualMaximum(Calendar.DATE);
        for (int i = 1; i < max; i = i + k) {
            list.add(begincal.getTime());
            begincal.add(Calendar.DATE, k);
        }
        begincal = new GregorianCalendar(beginYear, beginMonth, max);
        list.add(begincal.getTime());
        return list;
    }
}
app/src/main/res/drawable/bg_gold_circle.xml
New file
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <shape android:shape="rectangle">
            <corners android:radius="@dimen/circle" />
            <solid android:color="@color/gold" />
        </shape>
    </item>
</selector>
app/src/main/res/layout/activity_setting_coin.xml
New file
@@ -0,0 +1,92 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:background="@color/white"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
    <com.runt.open.mvvm.widgets.TitleBarView
        android:id="@+id/title_bar"
        style="@style/titlebar"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:leftDrawable="@mipmap/icon_white_back"
        app:leftTint="@color/black"
        app:titleText="财务设置"
        />
    <TextView
        android:id="@+id/lin_realname"
        style="@style/lin_txt"
        app:layout_constraintTop_toBottomOf="@id/title_bar"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        android:text="真实姓名" />
    <TextView
        android:id="@+id/txt_realname"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginRight="@dimen/default_margin_lr"
        android:textSize="14sp"
        android:textColor="@color/txt_enable"
        app:layout_constraintTop_toTopOf="@id/lin_realname"
        app:layout_constraintBottom_toBottomOf="@id/lin_realname"
        app:layout_constraintRight_toRightOf="parent"  />
    <TextView
        android:id="@+id/lin_pass"
        style="@style/lin_txt"
        app:layout_constraintTop_toBottomOf="@id/lin_realname"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        android:drawableRight="@mipmap/arrow_right"
        android:text="支付密码" />
    <TextView
        android:id="@+id/lin_alipay"
        style="@style/lin_txt"
        app:layout_constraintTop_toBottomOf="@id/lin_pass"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        android:text="支付宝账号" />
    <TextView
        android:id="@+id/txt_alipay"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginRight="@dimen/default_margin_lr"
        android:textSize="14sp"
        android:textColor="@color/txt_enable"
        app:layout_constraintTop_toTopOf="@id/lin_alipay"
        app:layout_constraintBottom_toBottomOf="@id/lin_alipay"
        app:layout_constraintRight_toRightOf="parent"  />
    <View
        app:layout_constraintTop_toBottomOf="@id/title_bar"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        android:layout_width="match_parent"
        android:layout_height="0.5dp"
        android:background="@color/color_gray8" />
    <View
        app:layout_constraintTop_toBottomOf="@id/lin_realname"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        android:layout_width="match_parent"
        android:layout_height="0.5dp"
        android:background="@color/color_gray8" />
    <View
        app:layout_constraintTop_toBottomOf="@id/lin_pass"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        android:layout_width="match_parent"
        android:layout_height="0.5dp"
        android:background="@color/color_gray8" />
    <View
        app:layout_constraintTop_toBottomOf="@id/lin_alipay"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        android:layout_width="match_parent"
        android:layout_height="0.5dp"
        android:background="@color/color_gray8" />
</androidx.constraintlayout.widget.ConstraintLayout>
app/src/main/res/layout/activity_signs.xml
New file
@@ -0,0 +1,245 @@
<?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"
    xmlns:tools="http://schemas.android.com/tools"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@android:color/white">
    <com.runt.open.mvvm.widgets.TitleBarView
        android:id="@+id/title_bar"
        style="@style/titlebar"
        android:background="@color/transparent"
        app:leftDrawable="@mipmap/icon_white_back"
        app:leftTint="@color/black"
        app:titleText="签到"
        />
    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scrollbars="vertical">
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">
            <LinearLayout
                android:layout_width="match_parent"
                android:background="@color/theme"
                android:gravity="center_horizontal"
                android:orientation="vertical"
                android:paddingTop="30dp"
                android:layout_height="210dp">
                <TextView
                    android:id="@+id/txt_signs"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="天数"
                    android:textColor="@color/white"
                    android:textStyle="bold"
                    android:textSize="26sp"/>
                <TextView
                    android:id="@+id/txt_tip"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="连续签到赠送金币丰厚"
                    android:layout_marginTop="10dp"
                    android:textColor="@color/cut_off_line"
                    android:textSize="16sp"/>
            </LinearLayout>
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginTop="-80dp"
                android:layout_marginLeft="15dp"
                android:layout_marginRight="15dp"
                android:background="@drawable/bg_white_corner"
                android:orientation="vertical"
                android:elevation="5dp">
                <LinearLayout
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:padding="10dp"
                    android:layout_gravity="center"
                    android:layout_marginTop="10dp"
                    android:gravity="center_vertical"
                    android:orientation="horizontal">
                    <ImageView
                        android:id="@+id/last_month"
                        android:layout_width="wrap_content"
                        android:layout_height="16dp"
                        android:adjustViewBounds="true"
                        android:src="@drawable/calender_last"/>
                    <TextView
                        android:id="@+id/txt_calendar_title"
                        android:layout_width="130dp"
                        android:layout_height="wrap_content"
                        android:text="2017年7月"
                        android:textColor="@color/txt_normal"
                        android:textSize="20sp"
                        android:gravity="center" />
                    <ImageView
                        android:id="@+id/next_month"
                        android:layout_width="wrap_content"
                        android:layout_height="16dp"
                        android:adjustViewBounds="true"
                        android:src="@drawable/calender_next"/>
                </LinearLayout>
                <LinearLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginTop="10dp"
                    android:layout_marginBottom="10dp"
                    android:orientation="horizontal">
                    <TextView
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:gravity="center"
                        android:layout_weight="1"
                        android:textSize="@dimen/sign_text_size"
                        android:text="日"/>
                    <TextView
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:gravity="center"
                        android:layout_weight="1"
                        android:textSize="@dimen/sign_text_size"
                        android:text="一"/>
                    <TextView
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:gravity="center"
                        android:layout_weight="1"
                        android:textSize="@dimen/sign_text_size"
                        android:text="二"/>
                    <TextView
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:gravity="center"
                        android:layout_weight="1"
                        android:textSize="@dimen/sign_text_size"
                        android:text="三"/>
                    <TextView
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:gravity="center"
                        android:layout_weight="1"
                        android:textSize="@dimen/sign_text_size"
                        android:text="四"/>
                    <TextView
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:gravity="center"
                        android:layout_weight="1"
                        android:textSize="@dimen/sign_text_size"
                        android:text="五"/>
                    <TextView
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:gravity="center"
                        android:layout_weight="1"
                        android:textSize="@dimen/sign_text_size"
                        android:text="六"/>
                </LinearLayout>
                <androidx.recyclerview.widget.RecyclerView
                    android:id="@+id/recycler"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    tools:listitem="@layout/item_calendar_day"
                    app:layoutManager="androidx.recyclerview.widget.GridLayoutManager"
                    app:spanCount="7"
                    tools:itemCount="24">
                </androidx.recyclerview.widget.RecyclerView>
                <LinearLayout
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:gravity="center_vertical"
                    android:padding="15dp"
                    android:orientation="horizontal">
                    <View
                        android:layout_width="7dp"
                        android:layout_height="7dp"
                        android:background="@drawable/bg_blue_circle" />
                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_marginLeft="5dp"
                        android:textSize="@dimen/sign_text_size"
                        android:text="已签到"
                        android:gravity="center" />
                    <View
                        android:layout_width="7dp"
                        android:layout_height="7dp"
                        android:layout_marginLeft="@dimen/sign_text_margin"
                        android:background="@drawable/bg_enable_circle" />
                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_marginLeft="5dp"
                        android:textSize="@dimen/sign_text_size"
                        android:text="未签到"
                        android:gravity="center" />
                    <View
                        android:layout_width="7dp"
                        android:layout_height="7dp"
                        android:layout_marginLeft="@dimen/sign_text_margin"
                        android:background="@drawable/bg_red_border_circle" />
                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_marginLeft="5dp"
                        android:textSize="@dimen/sign_text_size"
                        android:text="今日"
                        android:gravity="center" />
                    <View
                        android:layout_width="7dp"
                        android:layout_height="7dp"
                        android:layout_marginLeft="@dimen/sign_text_margin"
                        android:background="@drawable/bg_red_circle" />
                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_marginLeft="5dp"
                        android:textSize="@dimen/sign_text_size"
                        android:text="今日已签"
                        android:gravity="center" />
                </LinearLayout>
            </LinearLayout>
            <Button
                android:id="@+id/btn_sign"
                style="@style/btn_normal"
                android:layout_marginTop="50dp"
                android:layout_marginBottom="50dp"
                android:layout_marginLeft="@dimen/default_margin_lr"
                android:layout_marginRight="@dimen/default_margin_lr"
                android:text="签到"/>
        </LinearLayout>
    </ScrollView>
</LinearLayout>
app/src/main/res/layout/item_calendar_day.xml
New file
@@ -0,0 +1,19 @@
<?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="wrap_content"
    android:layout_marginTop="10dp"
    android:gravity="center">
    <TextView
        android:id="@+id/txt_day"
        android:background="@drawable/bg_red_border_circle"
        android:layout_width="30dp"
        android:layout_height="30dp"
        android:textColor="@color/black"
        android:gravity="center"
        android:textSize="@dimen/sign_text_size"
        android:text="11"/>
</LinearLayout>
app/src/main/res/values/styles.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<resources xmlns:tools="http://schemas.android.com/tools">
    <declare-styleable name="TitleBarView">
        <attr name="leftDrawable" format="reference"/>
@@ -67,6 +67,7 @@
    </style>
    <style name="titlebar">
        <item name="android:id" tools:ignore="AaptCrash">@+id/title_bar</item>
        <item name="android:layout_width">match_parent</item>
        <item name="android:layout_height">?attr/actionBarSize</item>
        <item name="android:background">@color/white</item>