GridCellAdapter 대신에 RecyclerView 기반 CalendarAdapter를 만들면 어떤 사항들이 변경되는지 알아보자.
RecyclerView 는 ListView 보다 메모리, 성능이 개선된 것으로 데이터 양이 많은 경우 스크롤을 효율적으로 수행할 수 있는 위젯이다.
앱 build.gradle 수정사항
dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation 'androidx.appcompat:appcompat:1.1.0' implementation 'androidx.constraintlayout:constraintlayout:1.1.3' implementation 'androidx.recyclerview:recyclerview:1.0.0' implementation 'androidx.cardview:cardview:1.0.0' implementation 'gun0912.ted:tedpermission:2.0.0' implementation 'androidx.multidex:multidex:2.0.0' // minSdkVersion 이 21 이하인 경우 사용 implementation files('libs/icu4j-4_8_2.jar') }
|
activity_main.xml
<GridView android:id="@+id/calendar" android:layout_width="fill_parent" android:layout_height="wrap_content" android:scrollbars="horizontal" android:numColumns="7" > </GridView>
|
<androidx.recyclerview.widget.RecyclerView android:id="@+id/calendar" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_centerVertical="true" android:adjustViewBounds="false" android:focusableInTouchMode="true" android:scrollbars="vertical" />
|
MainActivity.java
private GridView calendarView; private GridCellAdapter adapter;
calendarView = (GridView) this.findViewById(R.id.calendar);
makeCalendarList(month, year);
// Initialised adapter = new GridCellAdapter(mContext, calList); adapter.notifyDataSetChanged(); calendarView.setAdapter(adapter); }
private void setGridCellAdapterToDate(int month, int year) { makeCalendarList(month, year); adapter = new GridCellAdapter(mContext, calList); adapter.notifyDataSetChanged(); calendarView.setAdapter(adapter); // 상단 화면 날짜 출력 cal.set(year, month -1, cal.get(Calendar.DAY_OF_MONTH)); currentMonth.setText(DateFormat.format(dateTemplate, cal.getTime())); }
|
private RecyclerView calendarView; private RecyclerView.Adapter adapter;
calendarView = this.findViewById(R.id.calendar); calendarView.setHasFixedSize(true); calendarView.setLayoutManager(new GridLayoutManager(mContext,7));
makeCalendarList(month, year);
// Initialised adapter = new CalendarAdapter(mContext, calList); adapter.notifyDataSetChanged(); calendarView.setAdapter(adapter); }
private void setGridCellAdapterToDate(int month, int year) { makeCalendarList(month, year); adapter = new CalendarAdapter(mContext, calList); adapter.notifyDataSetChanged(); calendarView.setAdapter(adapter); // 상단 화면 날짜 출력 cal.set(year, month -1, cal.get(Calendar.DAY_OF_MONTH)); currentMonth.setText(DateFormat.format(dateTemplate, cal.getTime())); }
|
이제 CalendarAdapter 만드는 방법이다.
public class CalendarAdapter extends RecyclerView.Adapter<CalendarAdapter.CustomViewHolder> {
@NonNull @Override public CalendarAdapter.CustomViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { return null; }
@Override public void onBindViewHolder(@NonNull CalendarAdapter.CustomViewHolder holder, int position) {
}
@Override public int getItemCount() { return 0; }
public class CustomViewHolder extends RecyclerView.ViewHolder { public CustomViewHolder(@NonNull View itemView) { super(itemView); } } } |
아래 이미지와 같은 과정을 거치면 위와 같은 코드가 만들어진다.
이제 완성된 코드를 적는다.
package com.link2me.android.adpater;
import android.content.Context; import android.graphics.Color; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.LinearLayout; import android.widget.TextView;
import androidx.annotation.NonNull; import androidx.recyclerview.widget.RecyclerView;
import com.link2me.android.calendar.R; import com.link2me.android.item.Calendar_Item; import com.link2me.android.util.CalendarHelper;
import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.LinkedHashMap;
public class CalendarAdapter extends RecyclerView.Adapter<CalendarAdapter.CustomViewHolder> { static final String tag = CalendarAdapter.class.getSimpleName(); Context mContext;
private LinkedHashMap<String, Calendar_Item> calList; private String[] mKeys;
private final SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyyMMdd");
public CalendarAdapter(Context context, LinkedHashMap<String, Calendar_Item> list) { mContext = context; calList = list; mKeys = calList.keySet().toArray(new String[list.size()]); }
@NonNull @Override public CalendarAdapter.CustomViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.calendar_cell, parent, false); CustomViewHolder holder = new CustomViewHolder(view); return holder; }
@Override public void onBindViewHolder(@NonNull final CalendarAdapter.CustomViewHolder holder, int position) { String theday = calList.get(mKeys[position]).getDay(); String themonth = calList.get(mKeys[position]).getMonth(); String theyear = calList.get(mKeys[position]).getYear(); String holiday = calList.get(mKeys[position]).getEvent();
holder.gridcell_Day.setText(theday); holder.gridcell_LunarDay.setText(CalendarHelper.Sol2Lun(theyear, String.valueOf(Integer.parseInt(themonth)-1),theday)); //0 ~ 11월로 인식하므로 - 1 if(holiday.length()>0){ holder.gridcell_Event.setText(holiday); } else { holder.gridcell_Event.setText(""); } holder.gridcell_layout.setTag(theday + "-" + themonth + "-" + theyear);
if(calList.get(mKeys[position]).getColor().equals("GRAY")){ holder.gridcell_Day.setTextColor(Color.LTGRAY); } if(calList.get(mKeys[position]).getColor().equals("BLACK")){ holder.gridcell_Day.setTextColor(Color.BLACK); } if(calList.get(mKeys[position]).getColor().equals("RED")){ holder.gridcell_Day.setTextColor(Color.RED); holder.gridcell_Event.setTextColor(Color.RED); } if(calList.get(mKeys[position]).getColor().equals("BLUE")){ holder.gridcell_Day.setTextColor(Color.BLUE); } if(calList.get(mKeys[position]).getColor().equals("CYAN")){ holder.gridcell_layout.setBackgroundColor(Color.CYAN); }
String tagData = theyear+themonth+theday; holder.itemView.setTag(tagData); holder.itemView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { String date_month_year = (String) view.getTag(); Log.e("Selected date", date_month_year); try { Date parsedDate = dateFormatter.parse(date_month_year); Log.d(tag, "Parsed Date: " + parsedDate.toString());
} catch (ParseException e) { e.printStackTrace(); } } }); }
@Override public int getItemCount() { return calList.size(); }
public class CustomViewHolder extends RecyclerView.ViewHolder { protected LinearLayout gridcell_layout; protected TextView gridcell_Day; protected TextView gridcell_LunarDay; protected TextView gridcell_Event;
public CustomViewHolder(@NonNull View itemView) { super(itemView); gridcell_layout = (LinearLayout) itemView.findViewById(R.id.calendar_day_gridcell); gridcell_Day = itemView.findViewById(R.id.dayTV); gridcell_LunarDay = itemView.findViewById(R.id.lunardayTV); gridcell_Event = itemView.findViewById(R.id.eventTV); } } } |
커스텀 달력 만드는 방법에 대한 충분한 설명이 되었을 것이라고 본다.
https://www.youtube.com/watch?v=kNq9w1_nhL4 를 강좌를 보면 RecyclerView 에 대한 설명을 잘 해주고 있으니 사용법에 대해 잘 모르면 보면 도움될 수 있다.