반응형
안녕하세요.
첫번째 Project "WGPG"의 ver1.0.0 개발을 끝내고 새로운 프로젝트를 진행중인데,
프로젝트의 내용중에 Custom Calendar의 내용이 있어, 개발하던중에 막히게 되어 글을 작성하게 되었습니다.
1. 구현하고자 하는 것
ViewPager와 RecyclerView를 이용한 Custom Calendar를 구현하고자 합니다.
아래의 그림을 보시면 이해가 편합니다.
ViewPager의 View들은 각 월의 달력을 보여주고 View 안의 RecyclerView가 각 일을 보여주는 역할을 합니다.
2. 소스코드
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
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
|
package com.example.customcalenderexample;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.RecyclerView;
import androidx.viewpager.widget.ViewPager;
import android.os.Bundle;
import android.widget.TextView;
import java.util.Calendar;
import java.util.GregorianCalendar;
public class MainActivity extends AppCompatActivity {
private TextView tv_month;
private RecyclerView rv;
private MainAdapter adapter;
private GregorianCalendar today = new GregorianCalendar();
private ViewPager vp;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//ViewPager Calendar
vp = (ViewPager) findViewById(R.id.vp);
vp.setAdapter(new ViewPagerAdapter(this, today.get(Calendar.YEAR), today.get(Calendar.MONTH)));
//RecyclerView Calendar
//Need to
/*
tv_month = (TextView)findViewById(R.id.tv_month);
rv = (RecyclerView)findViewById(R.id.rv);
adapter = new MainAdapter();
rv.setLayoutManager(new StaggeredGridLayoutManager(7,StaggeredGridLayoutManager.VERTICAL));
rv.setAdapter(adapter);
setCalender();
*/
}
/*
private void setCalender(){
try{
GregorianCalendar calendar = new GregorianCalendar(today.get(Calendar.YEAR), today.get(Calendar.MONTH), 1);
int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK) -1 ;
int max = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
tv_month.setText(Integer.toString(calendar.get(Calendar.YEAR)) + "/" + Integer.toString(calendar.get(Calendar.MONTH)+1) + "/" + Integer.toString(calendar.get(Calendar.DATE)));
for(int i = 0; i < dayOfWeek; i++){
adapter.addItem(0,0);
}
for(int i = 1; i <= max; i++){
adapter.addItem(1,i);
}
}catch (Exception e){
e.printStackTrace();
}
}
*/
}
|
cs |
ViewPagerAdapter.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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
|
package com.example.customcalenderexample;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.StaggeredGridLayoutManager;
import androidx.viewpager.widget.PagerAdapter;
import java.util.Calendar;
import java.util.GregorianCalendar;
public class ViewPagerAdapter extends PagerAdapter {
private Context context;
private TextView tv_month;
private RecyclerView rv;
private MainAdapter adapter;
private GregorianCalendar today = new GregorianCalendar();
private int year, month, num = 0;
public ViewPagerAdapter(Context context, int year, int month){
this.context = context;
this.year = year;
this.month = month;
}
@NonNull
@Override
public Object instantiateItem(@NonNull ViewGroup container, int position) {
View view = null;
if(this.context != null){
LayoutInflater inflater = (LayoutInflater)this.context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.content_viewpager, container, false);
tv_month = (TextView)view.findViewById(R.id.tv_month);
rv = (RecyclerView)view.findViewById(R.id.rv);
adapter = new MainAdapter();
rv.setLayoutManager(new StaggeredGridLayoutManager(7,StaggeredGridLayoutManager.VERTICAL));
rv.setAdapter(adapter);
setCalender(year,month+num);
num++;
}
container.addView(view);
return view;
}
@Override
public int getCount() {
return 3;
}
@Override
public boolean isViewFromObject(@NonNull View view, @NonNull Object object) {
return (view == (View)object);
}
private void setCalender(int year, int month){
try{
GregorianCalendar calendar = new GregorianCalendar(year, month, 1);
int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK) -1 ;
int max = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
tv_month.setText(Integer.toString(calendar.get(Calendar.YEAR)) + "/" + Integer.toString(calendar.get(Calendar.MONTH)+1));
for(int i = 0; i < dayOfWeek; i++){
adapter.addItem(0,0);
}
for(int i = 1; i <= max; i++){
adapter.addItem(1,i);
}
}catch (Exception e){
e.printStackTrace();
}
}
}
|
cs |
MainAdapter.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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
|
package com.example.customcalenderexample;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList;
public class MainAdapter extends RecyclerView.Adapter<MainAdapter.ViewHolder> {
private ArrayList<MainItem> lists = new ArrayList<>();
private int key;
public class ViewHolder extends RecyclerView.ViewHolder {
private TextView tv_day;
private TextView tv_header;
public ViewHolder(@NonNull View itemView) {
super(itemView);
tv_day = itemView.findViewById(R.id.tv_day);
tv_header = itemView.findViewById(R.id.tv_header);
}
}
@Override
public int getItemViewType(int position) {
key = lists.get(position).getKey();
switch (key){
case 0 : return 0;
case 1 : return 1;
case 2 : return 2;
}
return -1;
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
LayoutInflater inflater;
View view;
ViewHolder vh;
switch (viewType){
case 0 :
inflater = (LayoutInflater)parent.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.item_empty, parent, false);
vh = new ViewHolder(view);
return vh;
case 1 :
inflater = (LayoutInflater)parent.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.item_day, parent, false);
vh = new ViewHolder(view);
return vh;
case 2 :
inflater = (LayoutInflater)parent.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.item_header, parent, false);
vh = new ViewHolder(view);
return vh;
}
return null;
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
int viewType = getItemViewType(position);
MainItem item = lists.get(position);
switch(viewType){
case 0 :
break;
case 1 :
holder.tv_day.setText(Integer.toString(item.getDay()));
break;
case 2 :
holder.tv_header.setText(Integer.toString(item.getDay()));
break;
}
}
@Override
public int getItemCount() {
return lists.size();
}
public void addItem(int key, int day){
MainItem item = new MainItem();
item.setKey(key);
item.setDay(day);
lists.add(item);
}
}
|
cs |
MainItem.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
package com.example.customcalenderexample;
public class MainItem {
private int key;
private int day;
public int getKey() {
return key;
}
public void setKey(int key) {
this.key = key;
}
public int getDay() {
return day;
}
public void setDay(int day) {
this.day = day;
}
}
|
cs |
3. 지금까지 해본 것
ViewPager의 Page수를 조정해본 결과 2개의 페이지까지는 강제종료되지 않고 잘 동작하지만,
3개 이상의 페이지에서 Swipe를 2회 이상 하면 꺼지는 현상을 확인했습니다.
4. 내가 생각하는 문제점
1) 많은 양의 view를 넣어서 과부하 상태가 되었다.
2) ViewPager의 기존의 문제점을 보완한 것이 ViewPager2라는데 ViewPager2가 해결책이 될 수도 있을 것 같다.
3) ViewPager의 Adapter에서 RecyclerView의 요소들을 추가하지 말고, View를 ViewPager의 list item으로 주는 방법도 될 수도 있을 것 같다.
반응형
'Legacy' 카테고리의 다른 글
[C++#2-1] 회전 알고리즘 (0) | 2021.05.27 |
---|---|
[C++#2] 구현 (0) | 2021.05.26 |
[안드로이드 스튜디오 독학#35] WGPG_Home (0) | 2021.03.11 |
[안드로이드 스튜디오 독학#34] WGPG_Diary (0) | 2021.03.11 |
[안드로이드 스튜디오 독학#33] WGPG_Resume (0) | 2021.03.11 |