728x90

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 에 대한 설명을 잘 해주고 있으니 사용법에 대해 잘 모르면 보면 도움될 수 있다.

블로그 이미지

Link2Me

,