CalendarPicker, TimePicker (Viewmodel, LiveData, Factory, EventBus)

Lee HyeongJong·2022년 12월 13일
0

안드로이드

목록 보기
24/43

직접 제작한 timePicker, CalendarPicker

1. 탭 크기 조절 연동
2. 폴드 작은화면 연동
3. 폴드 큰화면 연동
4. 폴드 접엇다 펴도 데이터 연동
5. 회전시 데이터 연동 및 크기 조절

1. CalendarPickerPopupDialog.java

public class CalendarPickerPopupDialog extends Dialog {

    private Context context;
    private CalendarPopupDialogClickListener CalendarPopupDialogClickListener;
    private CalendarView calendar_alert;

    private TextView tvTitle, tvNegative, tvPositive;
    private String text;
    private String title;

    Reserves reserves;

    //커스텀
    private int setYearValue;
    private int setMonthValue;
    private int setDayValue;

    public CalendarPickerPopupDialog(@NonNull Context context, CalendarPopupDialogClickListener CalendarPopupDialogClickListener) {
        super(context);
        this.context = context;
        this.CalendarPopupDialogClickListener = CalendarPopupDialogClickListener;
    }

    public void setText(String text) {
        this.text = text;
    }

    public void setYearValue(int setYearValue) { this.setYearValue = setYearValue; }
    public void setMonthValue(int setMonthValue) {
        this.setMonthValue = setMonthValue;
    }
    public void setDayValue(int setDayValue) { this.setDayValue = setDayValue; }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.calendar_dialog);

        calendar_alert = (CalendarView) findViewById(R.id.calendar_alert);
        calendar_alert.setMinDate(System.currentTimeMillis() - 1000); //이전 날짜 선택 막기

        int year = setYearValue;
        int month = setMonthValue-1;
        int day = setDayValue;

        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.YEAR, year);
        calendar.set(Calendar.MONTH, month);
        calendar.set(Calendar.DAY_OF_MONTH, day);

        long milliTime = calendar.getTimeInMillis();
        calendar_alert.setDate (milliTime, true, true);

        calendar_alert.setOnDateChangeListener(new CalendarView.OnDateChangeListener() {
            @Override
            public void onSelectedDayChange(@NonNull CalendarView view, int year, int month, int dayOfMonth) {
                setYearValue = year;
                setMonthValue = month + 1;
                setDayValue = dayOfMonth;

                reserves = new Reserves(year,month+1, dayOfMonth);
                EventBus.getDefault().post(new MessageEvent(reserves));
            }
        });

        tvPositive = findViewById(R.id.btn_calendar_ok);
        tvNegative = findViewById(R.id.btn_calendar_cancel);
//
        tvPositive.setOnClickListener(v -> {
            this.CalendarPopupDialogClickListener.onPositiveClick(setYearValue,setMonthValue,setDayValue);
            dismiss();
        });
//
        tvNegative.setOnClickListener(v -> {
            this.CalendarPopupDialogClickListener.onNegativeClick();
            dismiss();
        });
//
    }

}

2. CalendarPopupDialogClickListener.java

public interface CalendarPopupDialogClickListener {
    void onPositiveClick(int y, int m, int d);
    void onNegativeClick();
}

3. TimePickerPopupDialog.java

public class TimePickerPopupDialog extends Dialog {

    private Context context;
    private TimePickerPopupDialogClickListener TimePickerPopupDialogClickListener;
    private TimePicker timePicker;
    private TextView tvTitle, tvNegative, tvPositive;
    private String text;
    private String title;

    Reserves reserves;

    //커스텀
    private int setHourValue;
    private int setMinuteValue;

    public TimePickerPopupDialog(@NonNull Context context, TimePickerPopupDialogClickListener TimePickerPopupDialogClickListener) {
        super(context);
        this.context = context;
        this.TimePickerPopupDialogClickListener = TimePickerPopupDialogClickListener;
    }

    public void setText(String text) {
        this.text = text;
    }

    public void setHourValue(int setHourValue) { this.setHourValue = setHourValue; }

    public void setMinuteValue(int setSetMinuteValue) {
        this.setMinuteValue = setSetMinuteValue;
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.timepicker_dialog);

        timePicker = (TimePicker) findViewById(R.id.timepicker_alert);
        timePicker.setIs24HourView(false);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            timePicker.setHour(setHourValue);
            timePicker.setMinute(setMinuteValue);
        } else{
            timePicker.setCurrentHour(setHourValue);
            timePicker.setCurrentMinute(setMinuteValue);
        }

        timePicker.setOnTimeChangedListener(new TimePicker.OnTimeChangedListener() {
            @Override
            public void onTimeChanged(TimePicker view, int hourOfDay, int minute) {
                setHourValue = hourOfDay;
                setMinuteValue = minute;

                reserves = new Reserves(hourOfDay, minute);
                EventBus.getDefault().post(new MessageEvent(reserves));
            }
        });

        tvPositive = findViewById(R.id.btn_time_ok);
        tvNegative = findViewById(R.id.btn_time_cancel);

        tvPositive.setOnClickListener(v -> {
            this.TimePickerPopupDialogClickListener.onPositiveClick(setHourValue,setMinuteValue);
            dismiss();
        });

        tvNegative.setOnClickListener(v -> {
            this.TimePickerPopupDialogClickListener.onNegativeClick();
            dismiss();
        });

    }


}

4. TimePickerPopupDialogClickListener.java

public interface TimePickerPopupDialogClickListener {
    void onPositiveClick(int h, int m);
    void onNegativeClick();
}

5. Reserves.java

public class Reserves {
    private static Integer nowYear;
    private static Integer nowMonth;
    private static Integer nowDay;
    private static Integer nowHour;
    private static Integer nowMinute;

    private static Boolean timePicker = false;
    private static Boolean calendarPicker = false;

    public Reserves(Integer nowYear,Integer nowMonth, Integer nowDay){
        this.calendarPicker = true;
        this.nowYear = nowYear;
        this.nowMonth = nowMonth;
        this.nowDay = nowDay;
    }

    public Reserves(Integer nowHour, Integer nowMinute) {
        this.timePicker = true;
        this.nowHour = nowHour;
        this.nowMinute = nowMinute;
    }

    public void setNowHour(Integer hour){nowHour = hour;}
    public Integer getNowHour(){return nowHour;}

    public void setNowMinute(Integer minute){nowMinute = minute;}
    public Integer getNowMinute(){return nowMinute;}

    public void setNowYear(Integer year){nowYear = year;}
    public Integer getNowYear(){return nowYear;}

    public void setNowMonth(Integer month){nowMonth= month;}
    public Integer getNowMonth(){return nowMonth;}

    public void setNowDay(Integer day){nowDay = day;}
    public Integer getNowDay(){return nowDay;}

    public Boolean getCalendarPicker(){return calendarPicker;}
    public Boolean getTimePicker(){return timePicker;}


}

6. MyViewModel.java

public class MyViewModel extends ViewModel {

    private MutableLiveData<Reserves> reserves;
    public MutableLiveData<Reserves> getReserves() {
        if (reserves == null) {
            reserves = new MutableLiveData<Reserves>();

        }
        return reserves;
    }

}

7. MyViewModelFactory.java

public class MyViewModelFactory implements ViewModelProvider.Factory {
    @NonNull
    @Override
    public <T extends ViewModel> T create(@NonNull Class<T> modelClass) {
        try {
            return modelClass.newInstance();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
            throw new RuntimeException("팩토리 런타임 에러");
        } catch (InstantiationException e) {
            e.printStackTrace();
            throw new RuntimeException("팩토리 런타임 에러2");
        }
    }
}

8. MessageEvent.java

public class MessageEvent {

    public final Reserves message;

    public MessageEvent(Reserves message) {
        this.message = message;
    }
}

9. MainActivity.java

public class MainActivity extends AppCompatActivity {
    private final static String TAG = MainActivity.class.getSimpleName();

    TimePickerPopupDialog TimePickerPopupDialog;
    CalendarPickerPopupDialog CalendarPickerPopupDialog;

    //@Bell 20221208 picker
    TextView txtRevDate, txtRevTime, txtRevAmPm;
    String finalDateTime = "";
    String finalDate = "";
    String finalTime = "";
    int finalYear, finalMonth, finalDay, finalHour, finalMinute;
    int nowYear, nowMonth, nowDay;
    int nowHour, nowMinute;
    int changeYear, changeMonth, changeDay;
    int changeHour, changeMinute;
    Reserves reserves;
    MyViewModel viewModel;
    Boolean changeDate = false;
    Boolean changeTime = false;
    Boolean changeFinalTime = false;
    Boolean changeFinalDate = false;

    //모션
    CheckBox cb_sendLater;
    LinearLayout linRevDateTime;
    ImageView imgRevColck;

    //@Bell 20221208 picker
    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onMessageEvent(MessageEvent event) {

        if(event.message.getCalendarPicker()){
            this.changeYear = event.message.getNowYear();
            this.changeMonth = event.message.getNowMonth();
            this.changeDay = event.message.getNowDay();
            this.changeDate = true;
        }

        if(event.message.getTimePicker()){
            this.changeHour = event.message.getNowHour();
            this.changeMinute = event.message.getNowMinute();
            this.changeTime = true;
        }
//
    }


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        EventBus.getDefault().register(this);

        //피커
        cb_sendLater = (CheckBox) findViewById(R.id.cb_sendLater);
        linRevDateTime = (LinearLayout) findViewById(R.id.linRevDateTime);
        imgRevColck = (ImageView) findViewById(R.id.imgRevClock);
        txtRevDate = (TextView)  findViewById(R.id.txtRevDate);
        txtRevTime = (TextView)  findViewById(R.id.txtRevTime);
        txtRevAmPm = (TextView)  findViewById(R.id.txtRevAmPm);

        handleScheduledMessage();

    }

    //    가로 / 세로모드
    @Override
    public void onConfigurationChanged(@NonNull Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        //안해도됨 (타임피커는 연동됨)
//        if (TimePickerPopupDialog != null) {
//            TimePickerPopupDialog.dismiss();
//            changeFinalTime = false;
//            //세로
//            if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
//                getTimePickerPopupDialog();
//
//                //가로
//            } else if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
//                getTimePickerPopupDialog();
//
//            }
//            changeFinalTime = true;
//        }

        if (CalendarPickerPopupDialog != null) {
            CalendarPickerPopupDialog.dismiss();
            if(changeDate == false){ changeDate = true; }
            changeFinalDate = false;
            //세로
            if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
                getCalendarPickerPopupDialog();

                //가로
            } else if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
                getCalendarPickerPopupDialog();

            }
            changeFinalDate = true;
        }
    }

    //@Bell 20221208 피커 깨지는 현상 수정 및 예약 쪽지 테마변경 및 커스텀
    private void handleScheduledMessage() {
        cb_sendLater.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                if (isChecked) {
                    tenMinuteLater();
                    txtRevDate.setText(nowYear+". "+nowMonth+". "+nowDay);
                    txtRevTime.setText(getFormattedHour(nowHour)+":"+nowMinute);
                    txtRevAmPm.setText(getAmPmTen(nowHour));
                    finalDate = getFinalDate(nowYear, nowMonth, nowDay);
                    finalTime = getFinalTime(nowHour, nowMinute);
                    finalDateTime = finalDate + "" + finalTime;
                    Log.d(TAG+ " @@@@", "finalDateTime: "+ finalDateTime);
//                    Animation animation = AnimationUtils.loadAnimation(getActivity(),R.anim.anim_shake_clock);
                    Animation animation = AnimationUtils.loadAnimation(getApplicationContext(),R.anim.anim_shake_clock);
                    linRevDateTime.setVisibility(View.VISIBLE);
                    imgRevColck.startAnimation(animation);
                    //Picker
                    txtRevDate.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View v) { getCalendarPickerPopupDialog(); }
                    });
                    txtRevTime.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            getTimePickerPopupDialog();
                        }
                    });
                    
                    //여기서최종 정보 전송
                    
                    Log.d(TAG + "@@@@", "Last ! finalDateTime: " + finalDateTime);

                } else {
                    linRevDateTime.setVisibility(View.GONE);
                    changeFinalDate = false;
                    changeFinalTime = false;
                    changeDate = false;
                    changeTime = false;
//
                }
            }
        });
    }

    //@Bell Picker
    //데이트피커 다이얼로그
    //켈린더피커 다이얼로그
    private Date currentDate = new Date();
    
    public void getCalendarPickerPopupDialog(){
        CalendarPickerPopupDialog = new CalendarPickerPopupDialog(MainActivity.this, new CalendarPopupDialogClickListener() {
            @Override
            public void onPositiveClick(int y, int m, int d) {

                CalendarPickerPopupDialog = null;
                txtRevDate.setText(y+". "+m+". "+d);
                finalDate = getFinalDate(y,m,d);
                finalDateTime = finalDate + "" + finalTime;

                finalYear = y;
                finalMonth = m;
                finalDay = d;
                changeFinalDate = true;
                changeTime = false;

                if (stringToDate(finalDateTime).before(currentDate)) {
                    txtRevAmPm.setText(getAmPmTen(nowHour));
                    txtRevTime.setText(getFormattedHour(nowHour)+":"+nowMinute);
                    finalTime = getFinalTime(nowHour,nowMinute);
                    finalDateTime = finalDate + "" + finalTime;
                    Log.d(TAG+ "@@@@", "befor finalDateTime: "+ finalDateTime);
                    Toast.makeText(MainActivity.this, "시간을 다시 전택해 주세요", Toast.LENGTH_SHORT).show();
                    changeFinalTime = false;
                    changeFinalDate = false;
                    changeTime = false;
                    changeDate = false;
                } else {
                    Log.d(TAG+ "@@@@", "finalDateTime: "+ finalDateTime);
                    Toast.makeText(MainActivity.this, y+"년 "+m+"월 "+d+"일 선택되었습니다.", Toast.LENGTH_SHORT).show();
                }
                
                Log.d(TAG + "@@@@", "Last calendar finalDateTime: " + finalDateTime);
                //여기서 최종 데이터 전송

            }

            @Override
            public void onNegativeClick() {

                CalendarPickerPopupDialog = null;
                changeDate = false;
                changeTime = false;

                Toast.makeText(MainActivity.this, "취소되었습니다.", Toast.LENGTH_SHORT).show();


            }
        });

//        getCurrentDate();
        tenMinuteLater();

        if(changeFinalDate) {
            CalendarPickerPopupDialog.setYearValue(finalYear);
            CalendarPickerPopupDialog.setMonthValue(finalMonth);
            CalendarPickerPopupDialog.setDayValue(finalDay);
        }else if(changeDate) {
            reserves = new Reserves(changeYear, changeMonth, changeDay);

            //뷰모델 객체 생성
            viewModel = new ViewModelProvider(this, new MyViewModelFactory())
                    .get(MyViewModel.class);

            //옵저버 정의 - 데이터가 변하는 이벤트 발생시 처리할 핸들러(람다)
            Observer<Reserves> PickerObserver = PickerData -> reserves = PickerData;

            //뷰모델에 옵저버 등록
            viewModel.getReserves().observe(this, PickerObserver);
            viewModel.getReserves().setValue(reserves);

            CalendarPickerPopupDialog.setYearValue(viewModel.getReserves().getValue().getNowYear());
            CalendarPickerPopupDialog.setMonthValue(viewModel.getReserves().getValue().getNowMonth());
            CalendarPickerPopupDialog.setDayValue(viewModel.getReserves().getValue().getNowDay());
        }else {
            CalendarPickerPopupDialog.setYearValue(nowYear);
            CalendarPickerPopupDialog.setMonthValue(nowMonth);
            CalendarPickerPopupDialog.setDayValue(nowDay);
        }

        CalendarPickerPopupDialog.setCancelable(false);
        CalendarPickerPopupDialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
        CalendarPickerPopupDialog.show();

    }

    public void getTimePickerPopupDialog(){
        TimePickerPopupDialog = new TimePickerPopupDialog(MainActivity.this, new TimePickerPopupDialogClickListener() {
            @Override
            public void onPositiveClick(int h, int m) {

                TimePickerPopupDialog = null;

                finalTime = getFinalTime(h,m);
                finalDateTime = finalDate + "" + finalTime;

                finalHour = h;
                finalMinute = m;
                changeFinalTime = true;
                changeDate = false;

                if (stringToDate(finalDateTime).before(currentDate)) {
                    txtRevAmPm.setText(getAmPmTen(nowHour));
                    txtRevTime.setText(getFormattedHour(nowHour)+":"+nowMinute);
                    finalTime = getFinalTime(nowHour,nowMinute);
                    finalDateTime = finalDate + "" + finalTime;
                    Log.d(TAG+ "@@@@", "befor finalDateTime: "+ finalDateTime);
                    Toast.makeText(MainActivity.this, "시간을 다시 선택해 주세요", Toast.LENGTH_SHORT).show();
                    changeFinalTime = false;
                    changeFinalDate = false;
                    changeTime = false;
                    changeDate = false;
                } else {
                    txtRevAmPm.setText(getAmPmTen(h));
                    txtRevTime.setText(getFormattedHour(h)+":"+m);
                    finalTime = getFinalTime(h,m);
                    finalDateTime = finalDate + "" + finalTime;
                    Log.d(TAG+ "@@@@", "finalDateTime: "+ finalDateTime);
                    Toast.makeText(MainActivity.this, getAmPmTen(h)+" "+getFormattedHour(h)+"시"+m+"분 선택되었습니다.", Toast.LENGTH_SHORT).show();
                }
                
                Log.d(TAG + "@@@@", "Last time finalDateTime: " + finalDateTime);
                
                //여기서 최종 데이터 전송

            }

            @Override
            public void onNegativeClick() {

                TimePickerPopupDialog = null;

                changeDate = false;
                changeTime = false;

                Toast.makeText(MainActivity.this, "취소되었습니다.", Toast.LENGTH_SHORT).show();

            }
        });

//        getCurrentTime(); //현시간
        tenMinuteLater();

        if(changeFinalTime) {
            TimePickerPopupDialog.setHourValue(finalHour);
            TimePickerPopupDialog.setMinuteValue(finalMinute);
        }else if(changeTime) {
            reserves = new Reserves(changeHour, changeMinute);

            //뷰모델 객체 생성
            viewModel = new ViewModelProvider(this, new MyViewModelFactory())
                    .get(MyViewModel.class);

            //옵저버 정의 - 데이터가 변하는 이벤트 발생시 처리할 핸들러(람다)
            Observer<Reserves> PickerObserver = PickerData -> reserves = PickerData;

            //뷰모델에 옵저버 등록
            viewModel.getReserves().observe(this, PickerObserver);
            viewModel.getReserves().setValue(reserves);

            TimePickerPopupDialog.setHourValue(viewModel.getReserves().getValue().getNowHour());
            TimePickerPopupDialog.setMinuteValue(viewModel.getReserves().getValue().getNowMinute());
        }else {
            TimePickerPopupDialog.setHourValue(nowHour);
            TimePickerPopupDialog.setMinuteValue(nowMinute);
        }

        TimePickerPopupDialog.setCancelable(false);
        TimePickerPopupDialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
        TimePickerPopupDialog.getWindow().requestFeature(Window.FEATURE_NO_TITLE);
        TimePickerPopupDialog.show();

    }

    //현재날짜
    public void getCurrentDate() {
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
            LocalDate now = LocalDate.now();
            this.nowYear = now.getYear();
            this.nowMonth = now.getMonth().getValue();
            Log.d("@@@@", "nowMonth : "+ nowMonth);
            this.nowDay = now.getDayOfMonth();
        } else {
            Date now = new Date();
            SimpleDateFormat formatterYear = new SimpleDateFormat("yyyy");
            SimpleDateFormat formatterMonth = new SimpleDateFormat("MM");
            SimpleDateFormat formatterDay = new SimpleDateFormat("dd");
            int formatedNowYear = Integer.parseInt(formatterYear.format(now));
            int formatedNowMonth = Integer.parseInt(formatterMonth.format(now));
            int formatedNowDay = Integer.parseInt(formatterDay.format(now));
            Log.d("@@@@", formatedNowYear+" "+formatedNowMonth+" "+formatedNowDay);
            this.nowYear = formatedNowYear;
            this.nowMonth = formatedNowMonth;
            this.nowDay = formatedNowDay;
        }
    }

    //현재시간
    public void getCurrentTime() {
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
            LocalTime now = LocalTime.now();
            this.nowHour = now.getHour();
            this.nowMinute = now.getMinute();
        } else {
            Date now = new Date();
            SimpleDateFormat formatterHour = new SimpleDateFormat("HH");
            SimpleDateFormat formatterMinute = new SimpleDateFormat("mm");
            int formatedNowHour = Integer.parseInt(formatterHour.format(now));
            int formatedNowMinute = Integer.parseInt(formatterMinute.format(now));
            Log.d("@@@@", formatedNowHour + " " + formatedNowMinute);
            this.nowHour = formatedNowHour;
            this.nowMinute = formatedNowMinute;
        }
    }

    //메시지 예약 시간 Am Pm
    public String getAmPmTen(int hour) {
        String amPm;
        if(hour >= 12){
            amPm = "오후";
        } else{
            amPm = "오전";
        }
        return amPm;
    }

    //메시지 예약 시간 24시간 -> 12시간 formatter
    public int getFormattedHour (int hour) {
        if(hour >= 13){
            hour = hour - 12;
        }
        return hour;
    }

    //10분뒤 날짜 시간
    public void tenMinuteLater(){
        Calendar cal = Calendar.getInstance();
        SimpleDateFormat formatterYear = new SimpleDateFormat("yyyy");
        SimpleDateFormat formatterMonth = new SimpleDateFormat("MM");
        SimpleDateFormat formatterDay = new SimpleDateFormat("dd");
        SimpleDateFormat formatterHour = new SimpleDateFormat("HH");
        SimpleDateFormat formatterMinute = new SimpleDateFormat("mm");
        cal.add(Calendar.MINUTE, 10);

        int formatedNowYear = Integer.parseInt(formatterYear.format(cal.getTime()));
        int formatedNowMonth = Integer.parseInt(formatterMonth.format(cal.getTime()));
        int formatedNowDay = Integer.parseInt(formatterDay.format(cal.getTime()));
        int formatedNowHour = Integer.parseInt(formatterHour.format(cal.getTime()));
        int formatedNowMinute = Integer.parseInt(formatterMinute.format(cal.getTime()));

        this.nowYear = formatedNowYear;
        this.nowMonth = formatedNowMonth;
        this.nowDay = formatedNowDay;
        this.nowHour = formatedNowHour;
        this.nowMinute = formatedNowMinute;
    }

    //finalDate formatter
    public String getFinalDate(int mY, int mM, int mD){
        finalDate = String.format("%04d", mY)+"년 "+String.format("%02d", mM)+"월 "+String.format("%02d", mD)+"일 ";
        Log.d(TAG + "@@@@ getFinalDate ", "finalDate: " + finalDate);
        return finalDate;
    }

    //finalTime formatter
    public String getFinalTime(int mH, int mM){
        finalTime = String.format("%02d", mH)+"시 "+String.format("%02d", mM)+"분 ";
        Log.d(TAG + "@@@@ getFinalTime", "finalTime: " + finalTime);
        return finalTime;
    }

    public Date stringToDate(String mFinalDateTime){
        Date dateFinalDateTime = null;
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy년 MM월 dd일 HH시 mm분");

        try {
            dateFinalDateTime = dateFormat.parse(mFinalDateTime);
            Log.d(TAG + "@@@@", "dateFinalDateTime: " + dateFinalDateTime );
            Log.d(TAG + "@@@@", "mFinalDateTime: " + mFinalDateTime );
        } catch (Exception e){ e.printStackTrace(); }

        return dateFinalDateTime;
    }

    //다이얼로그 리사이즈
    public void dialogResize(Dialog mDialog, float x, float y){

        Display display = getWindowManager().getDefaultDisplay();
        Point size = new Point();
        display.getSize(size);

        Window window = mDialog.getWindow();

        int mX = (int)(size.x * x);
        int mY = (int)(size.y * y);

        window.setLayout(mX,mY);

    }

}

10. calendar_dialog.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:background="@drawable/share_round_popup">

    <View
        android:id="@+id/calendar_view"
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:background="#F0F0F0"
        app:layout_constraintBottom_toTopOf="@+id/btn_calendar_cancel" />

    <TextView
        android:id="@+id/btn_calendar_ok"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="OK"
        android:gravity="end"
        android:paddingRight="15dp"
        android:textSize="16sp"
        android:paddingVertical="8dp"
        android:textColor="@color/blue"
        android:textStyle="bold"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toEndOf="@+id/btn_calendar_cancel" />

    <TextView
        android:id="@+id/btn_calendar_cancel"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="Cancel"
        android:gravity="start"
        android:paddingLeft="15dp"
        android:textSize="16sp"
        android:paddingVertical="8dp"
        android:textColor="@color/blue"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintEnd_toStartOf="@+id/btn_calendar_ok"/>

    <CalendarView
        android:id="@+id/calendar_alert"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:theme="@style/InfoCalendarPickerTheme"
        app:layout_constraintBottom_toTopOf="@+id/calendar_view"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />


</androidx.constraintlayout.widget.ConstraintLayout>

11. timepicker_dialog.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@drawable/share_round_popup"
    xmlns:app="http://schemas.android.com/apk/res-auto">


    <View
        android:id="@+id/time_view"
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:background="#F0F0F0"
        app:layout_constraintBottom_toTopOf="@+id/btn_time_cancel" />

    <TextView
        android:id="@+id/btn_time_ok"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="OK"
        android:gravity="end"
        android:paddingRight="15dp"
        android:textSize="16sp"
        android:paddingVertical="8dp"
        android:textColor="@color/blue"
        android:textStyle="bold"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toEndOf="@+id/btn_time_cancel" />

    <TextView
        android:id="@+id/btn_time_cancel"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="Cancel"
        android:gravity="start"
        android:paddingLeft="15dp"
        android:textSize="16sp"
        android:paddingVertical="8dp"
        android:textColor="@color/blue"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintEnd_toStartOf="@+id/btn_time_ok"/>

    <TimePicker
        android:id="@+id/timepicker_alert"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:theme="@style/InfoTimePickerTheme"
        app:layout_constraintBottom_toTopOf="@+id/time_view"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        android:timePickerMode="spinner"/>

</androidx.constraintlayout.widget.ConstraintLayout>

12. activity_main.xml

<?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:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/main"
    tools:context=".MainActivity">

    <CheckBox
        android:id="@+id/cb_sendLater"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
        android:buttonTint="@color/black"
        android:gravity="center"
        android:scaleX="0.9"
        android:scaleY="0.9"
        android:text="check"
        android:textColor="@color/black"
        android:textSize="13dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.953"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.023" />

    <androidx.constraintlayout.widget.ConstraintLayout
        android:id="@+id/cvRevDataTime"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginHorizontal="15dp"
        android:background="@color/white"
        app:cardBackgroundColor="@color/white"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <LinearLayout
            android:id="@+id/linRevDateTime"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="horizontal"
            android:visibility="gone">

            <ImageView
                android:id="@+id/imgRevClock"
                android:layout_width="24dp"
                android:layout_height="24dp"
                android:layout_gravity="center_vertical"
                android:layout_marginVertical="8dp"
                android:layout_marginStart="10dp"
                android:src="@drawable/alarm" />

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_gravity="center_vertical"
                android:orientation="horizontal">

                <TextView
                    android:id="@+id/txtRevDate"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:ellipsize="end"
                    android:paddingHorizontal="10dp"
                    android:paddingVertical="8dp"
                    android:text="0000. 00. 00"
                    android:textColor="@color/black"
                    android:textSize="13dp" />

                <TextView
                    android:id="@+id/txtRevAmPm"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:ellipsize="end"
                    android:paddingVertical="8dp"
                    android:text="오후"
                    android:textColor="@color/black"
                    android:textSize="13dp" />

                <TextView
                    android:id="@+id/txtRevTime"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:ellipsize="end"
                    android:paddingVertical="8dp"
                    android:paddingLeft="3dp"
                    android:paddingEnd="13dp"
                    android:text="00:00"
                    android:textColor="@color/black"
                    android:textSize="13dp" />


            </LinearLayout>

        </LinearLayout>

    </androidx.constraintlayout.widget.ConstraintLayout>

</androidx.constraintlayout.widget.ConstraintLayout>

13. alarm.xml (drawable)

<vector android:height="24dp" android:tint="#000000"
    android:viewportHeight="24" android:viewportWidth="24"
    android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
    <path android:fillColor="@android:color/white" android:pathData="M22,5.72l-4.6,-3.86 -1.29,1.53 4.6,3.86L22,5.72zM7.88,3.39L6.6,1.86 2,5.71l1.29,1.53 4.59,-3.85zM12.5,8L11,8v6l4.75,2.85 0.75,-1.23 -4,-2.37L12.5,8zM12,4c-4.97,0 -9,4.03 -9,9s4.02,9 9,9c4.97,0 9,-4.03 9,-9s-4.03,-9 -9,-9zM12,20c-3.87,0 -7,-3.13 -7,-7s3.13,-7 7,-7 7,3.13 7,7 -3.13,7 -7,7z"/>
</vector>

14. back.xml (drawable)

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/back">


    <solid android:color="@color/blue" />

</shape>

15. share_round_popup.xml (drawable)

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/shape_popup">

    <corners android:radius="15dp" />
    <solid android:color="@color/white" />

</shape>

16. anim_shake_clock.xml (anim 패키지안)

<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromXDelta="0"
    android:fromYDelta="0"
    android:toXDelta="10"
    android:toYDelta="10"
    android:duration="500"
    android:interpolator="@anim/cycle_4_pf" />

17. cycle_4_pf.xml (anim 패키지안)

<?xml version="1.0" encoding="utf-8"?>
<cycleInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
    android:cycles="4" />

18. AndroidManiffest.xml

android:configChanges="keyboard|keyboardHidden|orientation|screenSize|smallestScreenSize|screenLayout"

탭연동, 가로 세로 회전연동

19. colors.xml

<color name="blue">#0078FF</color>

20. themes.xml

    <style name="InfoTimePickerTheme">
        <item name="android:textSize">17sp</item>
        <item name="android:textColorPrimary">@color/black</item>
        <item name="colorControlNormal">#F0F0F0</item>
    </style>

    <style name="InfoCalendarPickerTheme">
        <item name="colorControlActivated">@color/blue</item>
        <item name="android:textStyle">bold</item>
    </style>

21.build.gradle

implementation 'org.greenrobot:eventbus:3.3.1'

참고
https://www.tutorialsbuzz.com/2019/09/android-datepicker-dialog-styling-kotlin.html
https://dodokwon.tistory.com/6
https://chc3484.tistory.com/101
https://soir1984.tistory.com/31
https://colalove5562.tistory.com/2
https://developer.android.com/develop/ui/views/components/pickers

profile
코딩을 시작해보자

0개의 댓글