프로젝트 [코테 복습] - activity_main과 RecyclerView

유의선·2024년 5월 9일

activity_main

RecyclerView와 FloatingButton으로 이루어진 화면이다.

Recyclerview의 Item들로 복습할 내용을 보여주고
Item들을 좌우로 슬라이드하는것으로 Item 삭제, Item 수정 화면으로 넘어가고,
FloatingButton을 누르면 RecyclerView에 새 Item을 추가하는 화면으로 넘어가도록 만들 생각이다.


RecyclerView

RecyclerView 안에 들어갈 Item의 layout은 다음처럼 생겼다.
FrameLayout으로 만들어 Item을 좌우로 슬라이드시키면 itemLayout이 좌우로 슬라이드되어 backgroundLayout이 보이도록 만들었다.

RecyclerView에 저장할 Item의 데이터 타입이 될 Task 클래스를 만들었다.
데이터의 id와 내용인 task, 만든 날짜인 time을 저장한다.

public class Task implements Parcelable {
    int id;
    String task;
    String time;

    public Task(int id, String task, String time){
        this.id = id;
        this.task = task;
        this.time = time;
    }
    protected Task(Parcel in) {
        id = in.readInt();
        task = in.readString();
        time = in.readString();
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeInt(id);
        dest.writeString(task);
        dest.writeString(time);
    }

    @Override
    public int describeContents() {
        return 0;
    }

    public static final Creator<Task> CREATOR = new Creator<Task>() {
        @Override
        public Task createFromParcel(Parcel in) {
            return new Task(in);
        }

        @Override
        public Task[] newArray(int size) {
            return new Task[size];
        }
    };

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getTask() {
        return task;
    }

    public void setTask(String task) {
        this.task = task;
    }

    public String getTime() {
        return time;
    }

    public void setTime(String time) {
        this.time = time;
    }
}

다음은 RecyclerView에 사용할 adapter와
터치 이벤트를 만들기 위한 interface 클래스이다.

public class TaskAdapter extends RecyclerView.Adapter<TaskAdapter.ViewHolder> implements onTaskClickListener {

    ArrayList<Task> items = new ArrayList<>();
    onTaskClickListener listener = null;

    public void setOnItemClickListener(onTaskClickListener listener){
        this.listener = listener;
    }

    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_task, parent, false);

        return new ViewHolder(itemView, this);
    }

    @Override
    public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
        Task item = items.get(position);
        holder.setItem(item);
    }

    @Override
    public int getItemCount() {
        return items.size();
    }

    public void addItem(Task item){
        items.add(item);
    }

    public Task getItem(int position){
        return items.get(position);
    }

    public void deleteAllItem() {
        items.clear();
    }

    @Override
    public void onItemClick(ViewHolder holder, View view, int position) {
        if(listener != null){
            listener.onItemClick(holder, view, position);
        }
    }

    static class ViewHolder extends RecyclerView.ViewHolder{
        TextView textTask;
        TextView textTime;

        public ViewHolder(@NonNull View itemView, final onTaskClickListener listener) {
            super(itemView);

            textTask = itemView.findViewById(R.id.textTask);
            textTime = itemView.findViewById(R.id.textTime);

            itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    int position = getAdapterPosition();

                    if(listener != null){
                        listener.onItemClick(ViewHolder.this, view, position);
                    }
                }
            });
        }

        public void setItem(Task item){
            textTask.setText(item.getTask());

            textTime.setText(item.getTime());
        }
    }
}
public interface onTaskClickListener {
    public void onItemClick(TaskAdapter.ViewHolder holder, View view, int position);
}

다음은 RecyclerView의 item의 좌우 swipe 기능 구현을 위해 ItemTouchHelper.Callback을 상속해 만든 TaskItemTouchHelperCallback 클래스와
좌우 swipe 시 구현될 기능을 작성할 interface 클래스이다.

public class TaskItemTouchHelperCallback extends ItemTouchHelper.Callback {
    private onItemSwipeListener listener;
    public TaskItemTouchHelperCallback(onItemSwipeListener listener){
        this.listener = listener;
    }


    @Override
    public int getMovementFlags(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder) {
        int dragFlags = 0;
        int swipeFlags = ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT;
        return makeMovementFlags(dragFlags, swipeFlags);
    }

    @Override
    public boolean onMove(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, @NonNull RecyclerView.ViewHolder target) {
        return false;
    }

    @Override
    public float getSwipeThreshold(@NonNull RecyclerView.ViewHolder viewHolder) {
        return super.getSwipeThreshold(viewHolder);
    }

    @Override
    public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int direction) {
        if(direction == ItemTouchHelper.LEFT){
            //EDIT
            listener.editItem(viewHolder.getAdapterPosition());
        }else if(direction == ItemTouchHelper.RIGHT){
            //DELETE
            listener.removeItem(viewHolder.getAdapterPosition());
        }
    }

    // clearView after Swiped Event
    @Override
    public void clearView(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder) {
        //super.clearView(recyclerView, viewHolder);
        getDefaultUIUtil().clearView(viewHolder.itemView.findViewById(R.id.itemLayout));
    }

    @Override
    public float getSwipeEscapeVelocity(float defaultValue) {
        return defaultValue * 3;
    }


    // Swipe Item without background
    // when swiped, set background imageviews' Visibility
    @Override
    public void onChildDraw(@NonNull Canvas c, @NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {

        if (actionState == ItemTouchHelper.ACTION_STATE_SWIPE) {
            View deleteImage = viewHolder.itemView.findViewById(R.id.imageDelete);
            View editImage = viewHolder.itemView.findViewById(R.id.imageEdit);
            View itemView = viewHolder.itemView.findViewById(R.id.itemLayout);
            if(dX > 0){
                deleteImage.setVisibility(View.VISIBLE);
                editImage.setVisibility(View.INVISIBLE);
                getDefaultUIUtil().onDraw(c, recyclerView, itemView, dX, dY, actionState, isCurrentlyActive);
            }else if(dX < 0){
                deleteImage.setVisibility(View.INVISIBLE);
                editImage.setVisibility(View.VISIBLE);
                getDefaultUIUtil().onDraw(c, recyclerView, itemView, dX, dY, actionState, isCurrentlyActive);
            }
        }


    }

}
public interface onItemSwipeListener {
    void editItem(int position);
    void removeItem(int position);
}

onChildDraw 클래스를 사용하여 좌우 swipe 할 때 Task 레이아웃의 itemLayout 만이 swipe 되도록 만들었다.

0개의 댓글