앱 개발 중 시간을 선택해야 하는 기능이 필요해서 Android SDK인 TimePickerDialog를 사용해 보았습니다.
TimePickerDialog의 각 컨포넌트들의 색상과 폰트 등을 커스텀 하고 싶어서 이리저리 구글링을 했는데 찾지 못했습니다.
도저히 찾을 수 없어서 TimePicker 를 활용해서 TimePickerDialog 기능을 만들기로 했습니다.
완성된 UI는 아래 이미지와 같고, 색상, 폰트 구분선 등을 커스텀할 수 있습니다.
- 관련내용
2022.08.05 - [IT/Android] - Android 앱에 Font (글꼴, 폰트) 적용하기
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 (글꼴, 폰트) 적용하기
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를 커스텀해보았습니다.
'IT > Android' 카테고리의 다른 글
Android Fragment 전환 애니메이션 효과 적용하기 (0) | 2022.09.04 |
---|---|
Android 투명 Activity (Layout) 배경 만드는 방법. (0) | 2022.08.31 |
Android MPAndroidChart 막대 그래프 적용하기 (1) | 2022.08.10 |
Android 앱에 Font (글꼴, 폰트) 적용하기 (0) | 2022.08.05 |
Android Studio 코드 자동 정렬하기 (0) | 2022.08.02 |
댓글