본문 바로가기
안드로이드 자바

[JAVA][Android] 리사이클러뷰 스크롤 감지하기

by teamnova 2024. 7. 7.
728x90

안녕하세요~

 

이번에는 RecyclerView에서 스크롤을 감지하는 방법에 대해 알아보겠습니다.

 

우선 전체 코드입니다.

 

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:app="http://schemas.android.com/apk/res-auto"
  xmlns:tools="http://schemas.android.com/tools"
  android:id="@+id/main"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  tools:context=".MainActivity"
  android:padding="30dp">

  <TextView
    android:id="@+id/scrollDirectionTextView"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="스크롤 감지중"
    android:textSize="20sp"
    app:layout_constraintTop_toTopOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    android:padding="10dp"/>

  <TextView
    android:id="@+id/lastVisibleItemTextView"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Last Visible Item"
    android:textSize="20sp"
    app:layout_constraintTop_toBottomOf="@id/scrollDirectionTextView"
    app:layout_constraintStart_toStartOf="parent"
    android:padding="10dp"/>

  <androidx.recyclerview.widget.RecyclerView
    android:id="@+id/recyclerView"
    android:layout_width="match_parent"
    android:layout_height="0dp"
    android:scrollbars="vertical"
    android:scrollbarSize="4dp"
    app:layout_constraintTop_toBottomOf="@id/lastVisibleItemTextView"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintEnd_toEndOf="parent"/>

</androidx.constraintlayout.widget.ConstraintLayout>

 

 

rv_item.xml

<?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:id="@+id/textView"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginTop="20dp"
    android:text="더미"
    android:textSize="30sp"/>
</LinearLayout>

 

 

TestAdapter.java

public class TestAdapter extends RecyclerView.Adapter<TestAdapter.ViewHolder> {
  private List<String> dummyData;

  public TestAdapter(List<String> dummyData) {
    this.dummyData = dummyData;
  }

  @NonNull
  @Override
  public TestAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
    View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.rv_item, parent, false);
    return new ViewHolder(view);
  }

  @Override
  public void onBindViewHolder(@NonNull TestAdapter.ViewHolder holder, int position) {
    holder.textView.setText(dummyData.get(position) + " / " +dummyData.size());

  }

  @Override
  public int getItemCount() {
    return dummyData != null ? dummyData.size() : 0;
  }

  public class ViewHolder extends RecyclerView.ViewHolder {
    private TextView textView;
    public ViewHolder(@NonNull View itemView) {
      super(itemView);
      textView = itemView.findViewById(R.id.textView);
    }
  }
}

 

 

MainActivity.java

public class MainActivity extends AppCompatActivity {

  private RecyclerView recyclerView;
  private TestAdapter testAdapter;
  private LinearLayoutManager layoutManager;
  private TextView scrollDirectionTextView;
  private TextView lastVisibleItemTextView;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    recyclerView = findViewById(R.id.recyclerView);
    scrollDirectionTextView = findViewById(R.id.scrollDirectionTextView);
    lastVisibleItemTextView = findViewById(R.id.lastVisibleItemTextView);

    layoutManager = new LinearLayoutManager(this);
    recyclerView.setLayoutManager(layoutManager);

    List<String> dummyList = generateDummyList();
    testAdapter = new TestAdapter(dummyList);
    recyclerView.setAdapter(testAdapter);

    setupScrollListener();
  }

  private List<String> generateDummyList() {
    List<String> dummyList = new ArrayList<>();
    for (int i = 1; i <= 50; i++) {
      dummyList.add("더미 아이템 " + i);
    }
    return dummyList;
  }

  private void setupScrollListener() {
    recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
      @Override
      public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
        super.onScrolled(recyclerView, dx, dy);

        if (dy > 0) {
          scrollDirectionTextView.setText("현재 스크롤 방향 : Down");
        } else if (dy < 0) {
          scrollDirectionTextView.setText("현재 스크롤 방향 : Up");
        }

        int lastVisibleItem = layoutManager.findLastCompletelyVisibleItemPosition() + 1;
        lastVisibleItemTextView.setText("화면에 마지막으로 보이는 아이템 : " + lastVisibleItem);
      }
    });
  }
}

 

 

위의 코드에서는 RecyclerView의 addOnScrollListener 메서드를 사용하여 스크롤 이벤트를 감지하고 있습니다.

 

스크롤 방향을 dy 파라미터를 통해 감지하며, 화면에 나타내고 있습니다.

 

또한, LinearLayoutManager의 findLastCompletelyVisibleItemPosition 메서드를 사용하여 마지막으로 보이는 아이템의 위치 또한 화면에 나타내고 있습니다.

 

이러한 방법을 통해 스크롤 이벤트를 활용하여 페이징과 같은 다양한 기능을 구현할 수 있습니다~! 

 

시연 영상 입니다.