안드로이드 연도와 월만 선택하는 datepicker 만들기

프로그래밍/Android 관련2018. 2. 17. 00:40

안녕하세요. 개발자 드리머즈입니다.


이번 포스팅에서는 연도와 달만 고를 수 있도록 하는 year month picker를 보겠습니다. 스택오버플로우에서 대부분 참고한 소스인데 링크를 못찾겠네요.


안드로이드는 연도/달/일을 고를 수 있는 Date Picker를 제공하지만 날짜(day)를 제외한 연도(year)와 달(month)만을 고를 수 있도록 하는 Picker는 제공하지 않습니다. 그래서 연도와 달만 고르도록 하는 picker를 사용하려면 개발자가 직접 만들어야 합니다. 처음엔 불편하다는 생각이 들지만 의외로 만들어보면 간단하고 커스터마이징 자유도도 높아서 좋습니다.


먼저 실행화면부터 보겠습니다.


 


왼쪽 사진의 화면에 중앙에 있는 버튼을 누르면 오른쪽 화면처럼 year month picker dialog가 뜨는 간단한 예제입니다.


year month picker dialog의 핵심이 되는 소스를 보겠습니다.

레이아웃을 설정하는 xml파일입니다. 코드라서 길어보이지만 사실 엄청 간단합니다. 

핵심은 <NumberPicker>입니다.

<NumberPicker> 2개를 사용해서 각각 년도/달을 입력받습니다.


year_month_picker.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
<?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:orientation="vertical"
    android:layout_marginTop="20dp"
    >
 
    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:orientation="horizontal">
 
        <NumberPicker
            android:id="@+id/picker_year"
            android:layout_width="wrap_content"
            android:layout_height="150dp"
            android:layout_margin="10dp"
            >
        </NumberPicker>
 
        <NumberPicker
            android:id="@+id/picker_month"
            android:layout_width="wrap_content"
            android:layout_height="150dp"
            android:layout_margin="10dp"
            >
        </NumberPicker>
 
    </LinearLayout>
 
 
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom"
        android:orientation="horizontal"
        android:layout_marginTop="10dp"
        >
 
        <Button
            android:id="@+id/btn_cancel"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:text="@string/cancel"
            android:layout_weight="1"
            android:textAllCaps="false"
            />
 
        <Button
            android:id="@+id/btn_confirm"
            android:layout_width="0dp"
            android:layout_weight="1"
            android:layout_height="wrap_content"
            android:text="@string/confirm"
            android:textAllCaps="false"
            />
 
    </LinearLayout>
</LinearLayout>
cs




그 다음은 java코드입니다. 


MyYearMonthPickerDialog.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
public class MyYearMonthPickerDialog extends DialogFragment {
 
    private static final int MAX_YEAR = 2099;
    private static final int MIN_YEAR = 1980;
 
    private DatePickerDialog.OnDateSetListener listener;
    public Calendar cal = Calendar.getInstance();
 
    public void setListener(DatePickerDialog.OnDateSetListener listener) {
        this.listener = listener;
    }
 
    Button btnConfirm;
    Button btnCancel;
 
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
        LayoutInflater inflater = getActivity().getLayoutInflater();
 
        View dialog = inflater.inflate(R.layout.year_month_picker, null);
 
        btnConfirm = dialog.findViewById(R.id.btn_confirm);
        btnCancel = dialog.findViewById(R.id.btn_cancel);
 
        final NumberPicker monthPicker = (NumberPicker) dialog.findViewById(R.id.picker_month);
        final NumberPicker yearPicker = (NumberPicker) dialog.findViewById(R.id.picker_year);
 
        btnCancel.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View view) {
                MyYearMonthPickerDialog.this.getDialog().cancel();
            }
        });
 
        btnConfirm.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View view) {
                listener.onDateSet(null, yearPicker.getValue(), monthPicker.getValue(), 0);
                MyYearMonthPickerDialog.this.getDialog().cancel();
            }
        });
 
        monthPicker.setMinValue(1);
        monthPicker.setMaxValue(12);
        monthPicker.setValue(cal.get(Calendar.MONTH) + 1);
 
        int year = cal.get(Calendar.YEAR);
        yearPicker.setMinValue(MIN_YEAR);
        yearPicker.setMaxValue(MAX_YEAR);
        yearPicker.setValue(year);
 
        builder.setView(dialog)
        // Add action buttons
        /*
        .setPositiveButton(R.string.confirm, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int id) {
                listener.onDateSet(null, yearPicker.getValue(), monthPicker.getValue(), 0);
            }
        })
        .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int id) {
                MyYearMonthPickerDialog.this.getDialog().cancel();
            }
        })
        */
        ;
 
        return builder.create();
    }
}
cs


커스텀 레이아웃을 이용한 AlertDialog입니다. AlertDialog에서 제공하는 PositiveButton과 NegativeButton을 사용할 수도 있지만 원하는대로 표현하기가 어려워서 주석처리해놨습니다. 대신 xml파일에 직접 원하는 모양으로 버튼을 배치했습니다.

listener 설정하는 부분을 유의해서 보면 될 것 같습니다. btnConfirm을 클릭하면 listener.onDateSet()함수를 호출하도록 만들어놨습니다. 


다음은 MainActivity의 xml파일과 java파일입니다.


activity_main.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.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"
    tools:context="com.dreamaz.yearmonthpickertest.MainActivity">
 
    <Button
        android:id="@+id/btn_year_month_picker"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Year Month Picker Dialog"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
 
</android.support.constraint.ConstraintLayout>
 
cs

MainActivity.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public class MainActivity extends AppCompatActivity {
    Button btnYearMonthPicker;
 
    DatePickerDialog.OnDateSetListener d = new DatePickerDialog.OnDateSetListener() {
        @Override
        public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth){
        Log.d("YearMonthPickerTest""year = " + year + ", month = " + monthOfYear + ", day = " + dayOfMonth);
        }
    };
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
 
        btnYearMonthPicker = findViewById(R.id.btn_year_month_picker);
 
        btnYearMonthPicker.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View view) {
                MyYearMonthPickerDialog pd = new MyYearMonthPickerDialog();
                pd.setListener(d);
                pd.show(getSupportFragmentManager(), "YearMonthPickerTest");
            }
        });
    }
}
 
cs

코드가 간단하므로 이해가 쉬울 것입니다. year month picker dialog의 OK버튼을 누르면 MainActivity에 정의된 listener가 불립니다.(onDateSet)

이 때 year, month 등의 값이 전달되므로 이 값을 사용해 원하는 동작을 하면 됩니다.


작성자

Posted by 드리머즈

관련 글

댓글 영역