Computer >> 컴퓨터 >  >> 프로그래밍 >> Android

안드로이드 RecyclerView에서 클릭한 항목과 위치(Position) 가져오는 방법

이 튜토리얼에서는 안드로이드 RecyclerView에서 사용자가 클릭한 항목(item)과 그 위치(position)를 가져오는 방법을 단계별 예제와 함께 알아봅니다.

1단계 — 새 프로젝트 생성

Android Studio에서 File ⇒ New Project를 선택한 후, 필요한 정보를 모두 입력하여 새 프로젝트를 생성합니다.

2단계 — activity_main.xml 작성

res/layout/activity_main.xml에 다음 코드를 추가합니다.

<?xml version = "1.0" encoding = "utf-8"?>
<android.support.design.widget.CoordinatorLayout android:layout_width = "match_parent"
   android:layout_height = "match_parent"
   xmlns:android = "https://schemas.android.com/apk/res/android"
   xmlns:app = "https://schemas.android.com/apk/res-auto">
   <android.support.design.widget.AppBarLayout
      android:layout_width = "match_parent"
      android:layout_height = "wrap_content">
   <android.support.v7.widget.Toolbar
      android:id = "@+id/appbarlayout_tool_bar"
      android:background = "@color/colorPrimary"
      android:layout_width = "match_parent"
      android:layout_height = "?attr/actionBarSize"
      app:layout_scrollFlags = "scroll|snap|enterAlways"
      app:theme = "@style/ThemeOverlay.AppCompat.Dark.ActionBar"
      app:popupTheme = "@style/ThemeOverlay.AppCompat.Light" />
   </android.support.design.widget.AppBarLayout>
   <android.support.v7.widget.RecyclerView
      android:id = "@+id/recycler_view"
      android:layout_width = "match_parent"
      android:layout_height = "match_parent"
      app:layout_behavior = "@string/appbar_scrolling_view_behavior"/>
</android.support.design.widget.CoordinatorLayout>

위 레이아웃에는 Toolbar를 포함하는 AppBarLayout과, 스크롤 시 함께 동작하는 RecyclerView가 배치되어 있습니다.

3단계 — MainActivity.java 작성

src/MainActivity.java에 다음 코드를 추가합니다.

package com.example.myapplication;
import android.annotation.TargetApi;
import android.os.Build;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.DefaultItemAnimator;
import android.support.v7.widget.DividerItemDecoration;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.widget.TextView;
import android.widget.Toast;
import java.util.ArrayList;

public class MainActivity extends AppCompatActivity {
   TextView text;
   ArrayList<String> list = new ArrayList<>();
   private RecyclerView recyclerView;
   private customAdapter mAdapter;
   private onClickInterface onclickInterface;
   @TargetApi(Build.VERSION_CODES.LOLLIPOP)
   @Override
   public void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);
      Toolbar toolbar = (android.support.v7.widget.Toolbar) findViewById(R.id.appbarlayout_tool_bar);
      toolbar.setTitle("This is toolbar.");
      setSupportActionBar(toolbar);
      onclickInterface = new onClickInterface() {
         @Override
         public void setClick(int abc) {
            list.remove(abc);
            Toast.makeText(MainActivity.this,"Position is"+abc,Toast.LENGTH_LONG).show();
            mAdapter.notifyDataSetChanged();
         }
      };
      recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
      RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getApplicationContext());
      recyclerView.setLayoutManager(mLayoutManager);
      recyclerView.setItemAnimator(new DefaultItemAnimator());
      mAdapter = new customAdapter(this, list, onclickInterface);
      recyclerView.setAdapter(mAdapter);
      recyclerView.addItemDecoration(new DividerItemDecoration(recyclerView.getContext(), DividerItemDecoration.VERTICAL));
      list.add("sairamm");
      list.add("Krishna");
      list.add("prasad");
      list.add("sairamm");
      list.add("Krishna");
      list.add("prasad");
      list.add("sairamm");
      list.add("Krishna");
      list.add("prasad");
      list.add("sairamm");
      list.add("Krishna");
      list.add("prasad");
      list.add("Krishna");
      list.add("prasad");
      list.add("sairamm");
      list.add("Krishna");
      list.add("prasad");
      list.add("sairamm");
      list.add("Krishna");
      list.add("prasad");
   }
}

여기서 핵심은 onClickInterface입니다. 어댑터에서 클릭 이벤트가 발생하면 인터페이스를 통해 액티비티로 클릭된 위치 값이 전달되고, setClick() 메서드에서는 해당 위치의 항목을 리스트에서 삭제한 뒤 Toast로 위치를 표시하고 notifyDataSetChanged()로 목록을 갱신합니다.

4단계 — customAdapter.java 작성

src/customAdapter.java에 다음 코드를 추가합니다.

package com.example.myapplication;
import android.content.Context;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import java.util.ArrayList;

public class customAdapter extends RecyclerView.Adapter<customAdapter.MyViewHolder> {
   Context context;
   ArrayList<String> list;
   onClickInterface onClickInterface;
   public class MyViewHolder extends RecyclerView.ViewHolder {
      public TextView title;
      public MyViewHolder(View view) {
         super(view);
         title = (TextView) view.findViewById(R.id.title);
      }
   }
   public customAdapter(Context context, ArrayList<String> list, onClickInterface onClickInterface) {
      this.context = context;
      this.list = list;
      this.onClickInterface = onClickInterface;
   }
   @NonNull
   @Override
   public MyViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
      View itemView = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.list_row, viewGroup, false);
      return new MyViewHolder(itemView);
   }
   @Override
   public void onBindViewHolder(@NonNull MyViewHolder myViewHolder, final int i) {
      myViewHolder.title.setText(list.get(i));
      myViewHolder.title.setOnClickListener(new View.OnClickListener() {
         @Override
         public void onClick(View v) {
            onClickInterface.setClick(i);
         }
      });
   }
   @Override
   public int getItemCount() {
      return list.size();
   }
}

onBindViewHolder()에서 각 항목의 TextView에 클릭 리스너를 설정하고, 클릭 시 현재 바인딩된 위치 i를 인터페이스로 전달하는 것이 이 예제의 핵심입니다.

5단계 — list_row.xml 작성

res/layout/list_row.xml에 다음 코드를 추가합니다.

<?xml version = "1.0" encoding = "utf-8"?>
<android.support.v7.widget.CardView xmlns:android = "https://schemas.android.com/apk/res/android"
   xmlns:app = "https://schemas.android.com/apk/res-auto"
   xmlns:tools = "https://schemas.android.com/tools"
   android:layout_width = "match_parent"
   android:layout_height = "wrap_content"
   app:cardElevation = "10dp"
   app:cardCornerRadius = "20dp"
   tools:context = ".MainActivity">
   <LinearLayout
      android:layout_width = "match_parent"
      android:layout_height = "wrap_content"
      android:gravity = "center"
      android:orientation = "vertical">
   <ImageView
      android:id = "@+id/imageView2"
      android:layout_width = "wrap_content"
      android:layout_height = "wrap_content"
      android:src = "@drawable/logo" />
   <TextView
      android:id = "@+id/title"
      android:layout_width = "match_parent"
      android:layout_height = "wrap_content"
      android:gravity = "center"
      android:textSize = "30sp" />
   <TextView
      android:id = "@+id/textview2"
      android:layout_width = "match_parent"
      android:layout_height = "wrap_content"
      android:gravity = "center"
      android:text = "Sairamkrishan"
      android:textSize = "30sp" />
   </LinearLayout>
</android.support.v7.widget.CardView>

각 리스트 항목은 CardView로 감싸져 있어 라운드 코너와 그림자 효과가 적용됩니다.

6단계 — onClickInterface 작성

src/onClickInterface에 다음 코드를 추가합니다.

package com.example.myapplication;
public interface onClickInterface {
   void setClick(int abc);
}

앱 실행 및 결과 확인

이제 애플리케이션을 실행해 보겠습니다. 실제 안드로이드 기기가 컴퓨터에 연결되어 있다고 가정합니다. Android Studio에서 프로젝트의 액티비티 파일 중 하나를 연 뒤 툴바의 Run 아이콘을 클릭하고, 실행할 모바일 기기를 선택하세요. 그러면 기기에 다음과 같은 기본 화면이 표시됩니다.

안드로이드 RecyclerView에서 클릭한 항목과 위치(Position) 가져오는 방법

이제 목록의 TextView를 클릭하면 해당 항목이 삭제되면서 클릭된 위치가 Toast 메시지로 표시됩니다.

안드로이드 RecyclerView에서 클릭한 항목과 위치(Position) 가져오는 방법

참고 사항

이 예제는 구버전 Support Library(android.support.*)를 기준으로 작성되었습니다. 최신 프로젝트에서는 AndroidX(androidx.*) 라이브러리로 마이그레이션하는 것이 권장되며, 패키지명만 변경하면 동일하게 동작합니다. 또한 실무에서는 notifyDataSetChanged() 대신 notifyItemRemoved(abc)를 사용하면 더 효율적으로 항목 삭제를 처리할 수 있습니다.