본문 바로가기
IT/Android

Android TimePicker Dialog 커스텀 해서 만들기 (색상, 버튼)

by TechTonic 2022. 8. 26.
반응형

앱 개발 중 시간을 선택해야 하는 기능이 필요해서 Android SDK인 TimePickerDialog를 사용해 보았습니다.

TimePickerDialog의 각 컨포넌트들의 색상과 폰트 등을 커스텀 하고 싶어서 이리저리 구글링을 했는데 찾지 못했습니다.

도저히 찾을 수 없어서 TimePicker 를 활용해서 TimePickerDialog  기능을 만들기로 했습니다.

완성된 UI는 아래 이미지와 같고, 색상, 폰트 구분선 등을 커스텀할 수 있습니다.

 

  • 관련내용

2022.08.05 - [IT/Android] - Android 앱에 Font (글꼴, 폰트) 적용하기

 

Android 앱에 Font (글꼴, 폰트) 적용하기

앱을 취미 삼아 여러 개 만들어 보았는데 먼가 알 수 없는 밋밋한 느낌이 들었습니다. 생각하니 같은 템플릿으로 약간의 기능만 변경하여 만들다 보니 큰 틀이 변하지 않았습니다. 아직 개발 미

soir1984.tistory.com

Custom TimePickerDialog
안드로이드 기본 TimePickerDialog

 

 

TimePickerDialog Layout 생성

우선 TimePickerDialog를 생성할 Layout 을 만들어 줍니다.

  • timepicker_alert_dialog_two.xml
<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="@drawable/share_round_popup"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <View
        android:id="@+id/time_view"
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:background="@color/text_main"
        app:layout_constraintBottom_toTopOf="@+id/time_btn_no" />
    <TextView
        android:id="@+id/time_btn_yes"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="Yes"
        android:gravity="center"
        android:textSize="16dp"
        android:paddingVertical="16dp"
        android:textColor="@color/text_main"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toEndOf="@+id/time_btn_no" />

    <TextView
        android:id="@+id/time_btn_no"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:paddingVertical="16dp"
        android:text="No"
        android:textColor="@color/text_main"
        android:textSize="16dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toStartOf="@+id/time_btn_yes"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toStartOf="parent" />

    <TimePicker
        android:id="@+id/timepicker_alert_two"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:selectionDividerHeight="0.1dp"
        android:theme="@style/InfoNumberPickerTheme"
        app:layout_constraintBottom_toTopOf="@+id/time_view"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        />



</androidx.constraintlayout.widget.ConstraintLayout>

해당 코드로 Dialog UI 는 만들었습니다.

Dialog 디자인을 위해 모서리 각진 부분을 둥글게 만드는 코드를 추가합니다.

  • share_round_popup.xml
<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/shape_popup"
    >
    <stroke android:width="10dp"
        android:color="@color/base_500"

        />
    <padding android:left="5dp"
        android:top="5dp"
        android:right="5dp"
        android:bottom="5dp"
        />
    <corners android:radius="15dp"      />
    <solid android:color="@color/base_200" />
</shape>

팝업 안의 구성들 커스텀은 해당 파일에서 수정하면 됩니다.

 

아래는 Dialog 안의 글씨체 스타일을 변경하는 내용입니다.

  • themes.xml
<style name="InfoNumberPickerTheme">
    <item name="android:textSize">17sp</item>
    <item name="android:fontFamily">@font/nanummyeongjo</item>
    <item name="android:textColorPrimary">@color/text_main</item>
</style>

폰트는 네이버에서 무료로 제공해 주니 아래 포스팅을 참고해서 적용하도록 합시다.

2022.08.05 - [IT/Android] - Android 앱에 Font (글꼴, 폰트) 적용하기

 

Android 앱에 Font (글꼴, 폰트) 적용하기

앱을 여러개 만드는 중인데 .. 먼가 알 수 없는 밋밋한 느낌이 들었다. 곰곰히 생각하니 같은 템플릿으로 약간의 기능만 변경하여 만들다보니 큰 틀이 변하지 않았다. 아직 개발 미숙으로 큰 틀

soir1984.tistory.com

 

UI 만드는 부분은 이것으로 끝났습니다. 이제 데이터를 활용할 수 있도록 코드를 구현해 봅시다.

 

TimePickerDialog 코드 구현

만들어 놓은 Dialog의 데이터를 활용하기 위한 class를 생성합니다.

  • TimePickerPopupDialogTwoButton.java
public class TimePickerPopupDialogTwoButton extends Dialog {

    private Context context;
    private TimePickerPopupDialogClickListener TimePickerPopupDialogClickListener;
    private TimePicker timePicker;
    private TextView tvTitle, tvNegative, tvPositive;
    private String text;
    private String title;
    private static String TAG = MainActivity.TAG;
    //커스텀
    private int setHourValue;
    private int setMinuteValue;


    public TimePickerPopupDialogTwoButton(@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 setMinuteValue) {
        this.setMinuteValue = setMinuteValue;
    }




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

        timePicker = (TimePicker) findViewById(R.id.timepicker_alert_two);

        timePicker.setIs24HourView(true);
        timePicker.setHour(setHourValue);
        timePicker.setMinute(setMinuteValue);

        timePicker.setOnTimeChangedListener(new TimePicker.OnTimeChangedListener() {
            @Override
            public void onTimeChanged(TimePicker view, int hourOfDay, int minute) {
                setHourValue = hourOfDay;
                setMinuteValue = minute;
                Log.d(TAG, setHourValue + "시" + setMinuteValue + "분");

            }
        });

        // popup dialog 버튼 이벤트
        tvPositive = findViewById(R.id.time_btn_yes);
        tvPositive.setOnClickListener(v -> {
            // YES 버튼 클릭
            this.TimePickerPopupDialogClickListener.onPositiveClick(setHourValue, setMinuteValue);
            dismiss();
        });


        tvNegative = findViewById(R.id.time_btn_no);
        tvNegative.setOnClickListener(v -> {
            // NO 버튼 클릭
            this.TimePickerPopupDialogClickListener.onNegativeClick();
            dismiss();
        });
    }


}

timePicker.setOnTimeChangedListener를 통해 TimePicker의 선택 값을 받을 수 있습니다.

이후 '확인' 버튼을 눌렀을 때 TimePicker 값들을 리스너(tvPositive.setOnClickListener)를 통해 호출부로 다시 값을 전달합니다.

아래는 리스너 파일입니다. 호출부에 값을 리턴해주기 위해 필요합니다.

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

onPositiveClick : 확인버튼 눌렀을 경우의 이벤트

onNegativeClick: 취소 버튼 눌렀을 경우의 이벤트

 

아래는 실제 팝업을 생성할 호출부 코드입니다.

 

  • Main_Fragment.java
TextView tv_setting_alram_end = (TextView)v.findViewById(R.id.setting_alram_end);
tv_setting_alram_end.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {

        TimePickerPopupDialogTwoButton octDialog = new TimePickerPopupDialogTwoButton(getContext(), new TimePickerPopupDialogClickListener() {

            @Override
            public void onPositiveClick(int setHourValue, int setMinuteValue) {
                Log.d(TAG, "onPositiveClick : " + setHourValue + "시 " + setMinuteValue + "분");
                
            }

            @Override
            public void onNegativeClick() {
                Log.d(TAG, "NO click");

            }
        });

        octDialog.setHourValue(end_alarm_h);
        octDialog.setMinuteValue(end_alarm_m);
        octDialog.setCanceledOnTouchOutside(false);  //다이알로그 밖에 터치했을 때 다이알로그가 꺼짐.(true) 안꺼짐 (false)
        octDialog.setCancelable(true);  //다이알로그 취소 가능. ( back버튼 )
        //octDialog.getWindow().setLayout(WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.MATCH_PARENT);
        //아래 2개를 해야 모서리 라운딩 백그라운드 컬러가 없어짐. (중요)
        octDialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
        octDialog.getWindow().requestFeature(Window.FEATURE_NO_TITLE);
        octDialog.show();

    }
});

여기서 중요한 부분은 아래 두 가지 옵션을 추가해야 Dialog UI 모서리 부분이 둥글게 되니 참고하세요.

 

octDialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
octDialog.getWindow().requestFeature(Window.FEATURE_NO_TITLE);

 

이렇게 TimePicker Dialog를 커스텀해보았습니다.

 

반응형

댓글