Android에서 NumberPicker을 custom하는 법에 대해 포스팅하겠습니다
custom한 결과는 아래⬇️와 같습니다
안드로이드에는 DatePicker, TimePicker, NumberPicker 등 다양한 Picker이 존재합니다
TimePicker의 경우, spinner
와 clock
mode가 존재합니다
많이 사용되는 timePicker의 spinner모드를 이용해 cutom을 하려 했으나, 숫자만을 고르는 spinner을 만들기 위해 numberPicker
을 이용했습니다
기획의도는 다음과 같습니다
앞 선 다이얼로그에서 시간을 지정하는 버튼을 누르면, 해당 다이얼로그가 나타납니다
spinner를 통해 숫자를 골라 확인을 누르면, 해당 데이터가 이전 다이얼로그로 전달됩니다
custom dialog를 만들기 위해 xml을 만들어주었습니다
xml에서는 numberPicker
요소를 추가해주었고, picker에 대한 설정은 class 내부에서 추가할 예정입니다
custom dialog
에 대한 추가적인 설명은 https://velog.io/@dooo_it_ly/AndroidJava-Dialog-Custom
을 참고해주세요 ‼️
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingHorizontal="30dp">
<NumberPicker
android:id="@+id/makar_alarm_time_picker"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:paddingHorizontal="20dp"/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="50dp"
android:layout_gravity="center"
android:layout_marginTop="10dp"
android:layout_marginBottom="20dp">
<Button
android:id="@+id/close_makar_alarm_time_btn"
android:layout_width="110dp"
android:layout_height="wrap_content"
android:layout_marginEnd="15dp"
android:background="@drawable/custom_button_white"
android:text="@string/close_button"
android:textColor="@color/black"
android:textSize="16sp"
android:textStyle="bold" />
<Button
android:id="@+id/set_makar_alarm_time_btn"
android:layout_width="110dp"
android:layout_height="wrap_content"
android:background="@drawable/custom_button_main"
android:text="@string/register_button"
android:textColor="@color/white"
android:textSize="16sp"
android:textStyle="bold" />
</LinearLayout>
</LinearLayout>
xml에 대한 디자인은 다음과 같습니다
numberPiceker를 담을 customDialog class를 만들어줍니다
Dialog
extendpublic class SetGetOffAlarmTimeDialog extends Dialog {
private Context context;
private NumberPicker alarmTimePicker;
private Button positiveBtn, negativeBtn;
private int getOffAlarmTime = MainActivity.user.getGetOffAlarmTime();
public SetGetOffAlarmTimeDialog(@NonNull Context context) {
super(context);
this.context = context;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setBackgroundDrawableResource(R.drawable.custom_dialog_background);
setContentView(R.layout.dialog_set_getoff_alarm_time);
}
}
timeArr
라는 배열을 만들고, spinner에 담을 수들을 넣어줍니다
numberPicker의 함수들은 String type을 다루기 때문에 위의 배열 타입을 String으로 지정
하는 것이 코드 사용에 더 용이합니다 ‼️
setAlarmTimePicker()
함수를 만들어 picker에 나타날 값들을 설정한 배열로 설정해줍니다
setMinValue
는 spinner의 최소값이고, setMaxValue
는 최대값입니다
저는 배열의 0번 인덱스부터 5번 인덱스를 각각 최소, 최대 값으로 지정해주었습니다
private String[] timeArr = {"10", "20", "30", "40", "50", "60"};
private void setAlarmTimePicker(){
alarmTimePicker.setDisplayedValues(timeArr);
alarmTimePicker.setMinValue(0);
alarmTimePicker.setMaxValue(5);
}
xml에서 설정해준 positiveBtn, negativeBtn, numberPicker에 대해 listener을 설정해줍니다
‼️ numberPicker은 setOnValueChangedListener
라는 값이 변경될 때 호출할 수 있는 리스너를 제공합니다
picker
, oldVal
, newVal
이라는 3개의 인자가 들어오는데, oldVal
은 기존 spinner의 인덱스, newVal
은 바뀐 인덱스를 뜻합니다
🔎 제가 스피너의 값을 10에서 40으로 바꿨다면 oldVal은 0, newVal은 3이 들어옵니다
배열에서 인덱스에 맞는 String을 찾아 Int로 파싱해 사용할 변수에 값을 저장해주었습니다
alarmTimePicker = findViewById(R.id.getoff_alarm_time_picker);
setAlarmTimePicker(); //numberPicker custom
positiveBtn = findViewById(R.id.set_getoff_alarm_time_btn);
negativeBtn = findViewById(R.id.close_getoff_alarm_time_btn);
//alarmpicker에 대한 listener
alarmTimePicker.setOnValueChangedListener(new NumberPicker.OnValueChangeListener() {
@Override
public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
getOffAlarmTime = Integer.parseInt(timeArr[newVal]);
}
});
positiveBtn.setOnClickListener(view -> {
//분 전달 -> alarmTime 변경
sendDataToFirstDialog(getOffAlarmTime);
Toast.makeText(context, "하차 "+getOffAlarmTime+"분 전 알림이 울립니다", Toast.LENGTH_SHORT).show();
dismiss();
});
negativeBtn.setOnClickListener(view -> {
dismiss();
});
아래와 같이 설정한 숫자들을 spin할 수 있는 picker가 완성되었습니다!
40분을 설정한 후 등록 버튼을 누르면 아래와 같이 이전 다이얼로그에 세팅값이 저장되고, 의도한대로 토스트까지 띄워집니다 😊