안드로이드 ToDoList - andeuloideu ToDoList

[안드로이드] RecyclerView로 TodoList 만들기

안드로이드 ToDoList - andeuloideu ToDoList
악마핫홍2020. 6. 8. 23:40

RecyclerView는 이해가 조금 안되기 때문에 저번 주 '모바일 프로그래밍' 수업 때 실습한 내용을 정리하였습니다. 순전히 저의 학업을 위해 복습하는 용도입니다!! (RecyclerView는 진짜 어렵다...)

build.gradle(Module:app)에 우선 recyclerview를 import해줘야 한다.

(아래 한 줄을 추가한다.)

dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation 'androidx.appcompat:appcompat:1.1.0' implementation 'androidx.constraintlayout:constraintlayout:1.1.3' testImplementation 'junit:junit:4.12' androidTestImplementation 'androidx.test.ext:junit:1.1.1' androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' implementation "androidx.recyclerview:recyclerview:1.1.0" }

Activity_main.xml(메인 화면 구성은 아래와 같다)

안드로이드 ToDoList - andeuloideu ToDoList

<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Todo List" android:textSize="10pt" android:layout_margin="20dp"/> <androidx.recyclerview.widget.RecyclerView android:id="@+id/recycler1" android:scrollbars="vertical" android:layout_width="match_parent" android:layout_height="350dp" android:layout_margin="20dp"/> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content"> <EditText android:id="@+id/edit_todo_main" android:layout_width="250dp" android:layout_height="wrap_content" android:hint="할 일" android:layout_margin="20dp"/> <Button android:id="@+id/button_insert_main" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="BUTTON" android:layout_margin="20dp"/> </LinearLayout> </LinearLayout>

Recyclerview_item.xml(리사이클 뷰에 추가될 하나의 목록에 대한 XML 레이아웃을 만든다)

하나의 목록이 전체 화면을 구성하면 안되기 때문에 높이는 wrap_content로 해야 한다.

안드로이드 ToDoList - andeuloideu ToDoList

<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="-" android:textSize="10pt" android:layout_margin="10dp" android:layout_gravity="center_vertical"/> <TextView android:id="@+id/textview_todo_item" android:layout_width="280dp" android:layout_height="wrap_content" android:text="밥먹기" android:textSize="10pt" android:layout_gravity="center_vertical"/> <ImageButton android:id="@+id/button_todo_item" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:src="@drawable/ic_delete_black_24dp" android:layout_marginLeft="10dp"/> </LinearLayout>

Todo.java

객체를 하나 생성한다. 기본적으로 생성자와 Getter를 만든다.

ArrayList에서 리스트 하나에 들어갈 데이터를 갖고 있는 Todo 클래스이다.

ArrayList<Todo(객체)> todoArrayList(이름) 의 형태로 선언 되어 RecyclerView의 데이터셋으로 사용된다.

public class Todo { private String todoName; //생성자 public Todo(String todoName) { this.todoName = todoName; } //getter public String getTodoName() { return todoName; } }

TodoAdapter.java

MainActivity.java와 같은 폴더 안에 새로운 class를 생성한다. TodoAdapter이다.

내가 궁금한 점: Adapter가 하는 일은 무엇인가? MainActivity.java와 RecyclerView 사이를 연결해준다.

package com.example.assignmentweek11; import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.Button; import android.widget.ImageButton; import android.widget.TextView; import androidx.recyclerview.widget.RecyclerView; import java.util.ArrayList; /* * Adapter 는 main 사이 중간자 역할을 한다. * item(Todo 객체) 과 연결해주는 하나의 포맷이다. * */ public class TodoAdapter extends RecyclerView.Adapter<TodoAdapter.ViewHolder> { //alt+enter > 새로운 대안 도구 private ArrayList<Todo> mData = null; //Todo라는 객체를 가진 ArrayList 생성 // item View 를 저장하는 뷰홀더 클래스. public class ViewHolder extends RecyclerView.ViewHolder { protected TextView textview_todo_item; protected ImageButton deleteBt; public ViewHolder(View itemView) { //itemView와 연결했기 때문에 findViewById 앞에 itemView를 명시한다. super(itemView); this.textview_todo_item = itemView.findViewById(R.id.textview_todo_item); this.deleteBt = itemView.findViewById(R.id.button_todo_item); //ArrayList 삭제 버튼 deleteBt.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { int position = getAdapterPosition(); //현재 어뎁터가 다루고 있는 리스트의 포지션을 가져온다. if(position != RecyclerView.NO_POSITION){ //삭제된 포지션이 아닌 경우 mData.remove(position); //ArrayList<Todo> 타입의 리스트에서 해당 포지션의 item을 제거한다. notifyDataSetChanged(); //어뎁터에게 데이터 셋이 변경되었음을 알린다. } } }); } } // 생성자에서 데이터 리스트 객체를 전달받음. TodoAdapter(ArrayList<Todo> list){ mData = list; } // onCreateViewHolder() - 아이템 뷰를 위한 뷰홀더 객체 생성하여 리턴. 이해하기 제일 어려운 부분!!!!!!!!!!!! @Override public TodoAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { Context context = parent.getContext() ; LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) ; View view = inflater.inflate(R.layout.recyclerview_item, parent, false) ; TodoAdapter.ViewHolder vh = new TodoAdapter.ViewHolder(view) ; return vh ; } // onBindViewHolder() - position에 해당하는 데이터를 뷰홀더의 아이템뷰에 표시. @Override public void onBindViewHolder(TodoAdapter.ViewHolder holder, int position) { holder.textview_todo_item.setText(mData.get(position).getTodoName()); //직접적으로 binding 해주는 것 //textview_todo_item.setText("할 일"); 동일 } // getItemCount() - 전체 데이터 갯수 리턴. @Override public int getItemCount() { return mData.size(); } }

MainActivity.java

RecyclerView에 사용될 어뎁터 뷰를 지정한다.

생성한 Todo 객체를 ArrayList인 TodoArrayList에 추가한다.

package com.example.assignmentweek11; import androidx.appcompat.app.AppCompatActivity; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.EditText; import java.util.ArrayList; public class MainActivity extends AppCompatActivity { Button insertButton; EditText todoEdit; private ArrayList<Todo> todoArrayList; private TodoAdapter todoAdapter; //어뎁터를 사용하기 위해 정의 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recycler1); // 리사이클러뷰에 LinearLayoutManager 객체 지정. recyclerView.setLayoutManager(new LinearLayoutManager(this)); //상하로 움직이는 리사이클러뷰, 반드시 지정해야 함 // 리사이클러뷰에 TodoAdapter 객체 지정. todoArrayList = new ArrayList<>(); todoAdapter = new TodoAdapter(todoArrayList); //어뎁터 안에 ArrayList 넣기 recyclerView.setAdapter(todoAdapter); //어뎁터를 셋팅 insertButton = (Button) findViewById(R.id.button_insert_main); todoEdit = (EditText) findViewById(R.id.edit_todo_main); insertButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Todo newTodo = new Todo(todoEdit.getText().toString()); //입력한 문자열로 Todo 객체 생성 todoArrayList.add(newTodo); //생성한 객체를 ArrayList<Todo> 타입의 TodoArrayList에 추가 todoAdapter.notifyDataSetChanged(); //어뎁터에게 데이터 셋이 변경되었음을 알린다. todoEdit.setText(null); } }); } }

안드로이드 ToDoList - andeuloideu ToDoList

삽입과 삭제가 자유로운 Todo List 앱 만들기 과정이다.