
RecyclerView와 FloatingButton으로 이루어진 화면이다.
Recyclerview의 Item들로 복습할 내용을 보여주고
Item들을 좌우로 슬라이드하는것으로 Item 삭제, Item 수정 화면으로 넘어가고,
FloatingButton을 누르면 RecyclerView에 새 Item을 추가하는 화면으로 넘어가도록 만들 생각이다.
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 되도록 만들었다.