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

LinearLayoutManager로 RecyclerView 맨 위로 스크롤하는 방법 – 안드로이드 예제 가이드

본격적인 예제에 들어가기 전에, 안드로이드에서 RecyclerView가 무엇인지 먼저 이해할 필요가 있습니다. RecyclerView는 ListView의 발전된 형태로, ViewHolder 디자인 패턴을 기반으로 동작합니다. RecyclerView를 활용하면 그리드 형태나 리스트 형태의 아이템을 효율적으로 화면에 표시할 수 있습니다.

이번 예제에서는 학생 이름과 나이를 보여주는 학생 기록 앱을 만들어 보면서, LinearLayoutManager를 사용한 RecyclerView에서 맨 위로 스크롤하는 방법을 단계별로 알아보겠습니다.

1단계 – 새 프로젝트 생성

Android Studio에서 새 프로젝트를 생성합니다. 메뉴에서 File ⇒ New Project로 이동한 후, 프로젝트 생성에 필요한 모든 정보를 입력하세요.

2단계 – 라이브러리 의존성 추가

build.gradle 파일을 열고 RecyclerView와 CardView 라이브러리 의존성을 추가합니다.

apply plugin: 'com.android.application'

android {
    compileSdkVersion 28
    defaultConfig {
        applicationId "com.example.andy.tutorialspoint"
        minSdkVersion 19
        targetSdkVersion 28
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}
dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.android.support:appcompat-v7:28.0.0'
    implementation 'com.android.support:design:28.0.0'
    implementation 'com.android.support.constraint:constraint-layout:1.1.3'
    implementation 'com.android.support:cardview-v7:28.0.0'
    implementation 'com.android.support:recyclerview-v7:28.0.0'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}

3단계 – activity_main.xml 레이아웃 작성

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

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
    xmlns:android="https://schemas.android.com/apk/res/android"
    xmlns:tools="https://schemas.android.com/tools"
    xmlns:app="https://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    tools:showIn="@layout/activity_main"
    android:fitsSystemWindows="true"
    tools:context=".MainActivity">
    <android.support.v7.widget.RecyclerView
        android:id="@+id/recycler_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:scrollbars="horizontal" />
    <android.support.design.widget.FloatingActionButton
        android:id="@+id/top"
        app:backgroundTint="#FFFF00"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom|end"
        android:src="@android:drawable/arrow_up_float" />
</android.support.design.widget.CoordinatorLayout>

위 코드에서는 부모 레이아웃으로 CoordinatorLayout을 사용하고, 그 안에 RecyclerView와 FloatingActionButton을 배치했습니다. FloatingActionButton은 CoordinatorLayout을 지원하기 때문에 부모 레이아웃을 CoordinatorLayout으로 지정한 것입니다. 사용자가 FloatingActionButton을 클릭하면 RecyclerView가 맨 위 위치로 스크롤됩니다.

4단계 – MainActivity.java 작성

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

package com.example.andy.tutorialspoint;

import android.annotation.TargetApi;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.RequiresApi;
import android.support.design.widget.FloatingActionButton;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class MainActivity extends AppCompatActivity {
    private RecyclerView recyclerView;
    private StudentAdapter studentAdapter;
    private List<studentData> studentDataList = new ArrayList<>();

    @TargetApi(Build.VERSION_CODES.O)
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        FloatingActionButton moveTop = findViewById(R.id.top);
        recyclerView = findViewById(R.id.recycler_view);
        studentAdapter = new StudentAdapter(studentDataList, MainActivity.this);
        RecyclerView.LayoutManager manager = new LinearLayoutManager(this);
        recyclerView.setLayoutManager(manager);
        recyclerView.setAdapter(studentAdapter);
        StudentDataPrepare();
        moveTop.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                recyclerView.smoothScrollToPosition(0);
            }
        });
    }

    @RequiresApi(api = Build.VERSION_CODES.N)
    private void StudentDataPrepare() {
        studentData data = new studentData("sai", 25);
        studentDataList.add(data);
        data = new studentData("sai raj", 25);
        studentDataList.add(data);
        data = new studentData("raghu", 20);
        studentDataList.add(data);
        data = new studentData("raj", 28);
        studentDataList.add(data);
        data = new studentData("amar", 15);
        studentDataList.add(data);
        data = new studentData("bapu", 19);
        studentDataList.add(data);
        data = new studentData("chandra", 52);
        studentDataList.add(data);
        data = new studentData("deraj", 30);
        studentDataList.add(data);
        data = new studentData("eshanth", 28);
        studentDataList.add(data);
        Collections.sort(studentDataList, new Comparator<studentData>() {
            @Override
            public int compare(studentData o1, studentData o2) {
                return o1.name.compareTo(o2.name);
            }
        });
    }
}

위 코드에서는 RecyclerView에 StudentAdapter를 연결하고, 어댑터에 학생 데이터 리스트(ArrayList)를 전달했습니다. 이 리스트에는 학생의 이름(name)나이(age)가 포함되어 있으며, 이름 순으로 정렬됩니다.

핵심은 smoothScrollToPosition() 메서드입니다. 이 메서드를 사용하면 지정한 위치로 부드럽게 스크롤할 수 있으며, 여기서는 0번째(맨 위) 위치로 이동하도록 설정했습니다. 필요에 따라 임의의 위치 값도 지정할 수 있습니다.

moveTop.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        recyclerView.smoothScrollToPosition(0);
    }
});

5단계 – StudentAdapter.java 작성

다음은 수정된 src/StudentAdapter.java 파일의 내용입니다.

package com.example.andy.tutorialspoint;

import android.graphics.Color;
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.LinearLayout;
import android.widget.TextView;
import java.util.List;
import java.util.Random;

class StudentAdapter extends RecyclerView.Adapter<StudentAdapter.MyViewHolder> {
    List<studentData> studentDataList;

    public StudentAdapter(List<studentData> studentDataList) {
        this.studentDataList = studentDataList;
    }

    @NonNull
    @Override
    public MyViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
        View itemView = LayoutInflater.from(viewGroup.getContext())
                .inflate(R.layout.student_list_row, viewGroup, false);
        return new MyViewHolder(itemView);
    }

    @Override
    public void onBindViewHolder(MyViewHolder viewHolder, int i) {
        studentData data = studentDataList.get(i);
        Random rnd = new Random();
        int currentColor = Color.argb(255, rnd.nextInt(256), rnd.nextInt(256), rnd.nextInt(256));
        viewHolder.parent.setBackgroundColor(currentColor);
        viewHolder.name.setText(data.name);
        viewHolder.age.setText(String.valueOf(data.age));
    }

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

    class MyViewHolder extends RecyclerView.ViewHolder {
        TextView name, age;
        LinearLayout parent;

        public MyViewHolder(View itemView) {
            super(itemView);
            parent = itemView.findViewById(R.id.parent);
            name = itemView.findViewById(R.id.name);
            age = itemView.findViewById(R.id.age);
        }
    }
}

어댑터 클래스는 다음과 같은 네 가지 핵심 요소로 구성됩니다.

  • onCreateViewHolder(): 뷰 홀더(ViewHolder)를 생성하고 해당 뷰를 반환합니다.

  • onBindViewHolder(): 생성된 뷰 홀더에 데이터를 바인딩합니다.

  • getItemCount(): 리스트의 전체 크기를 반환합니다.

  • MyViewHolder 클래스: RecyclerView.ViewHolder를 상속받는 내부 뷰 홀더 클래스입니다.

RecyclerView 아이템에 랜덤한 배경색을 적용하기 위해, 안드로이드에서 기본 제공되는 Random 클래스로 무작위 색상을 생성한 뒤 뷰 아이템의 부모 레이아웃에 색상을 지정했습니다.

Random rnd = new Random();
int currentColor = Color.argb(255, rnd.nextInt(256), rnd.nextInt(256), rnd.nextInt(256));
viewHolder.parent.setBackgroundColor(currentColor);

6단계 – student_list_row.xml 작성

다음은 수정된 res/layout/student_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:card_view="https://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    card_view:cardCornerRadius="4dp"
    android:id="@+id/card_view"
    android:layout_margin="10dp"
    android:layout_height="200dp">
    <LinearLayout
        android:id="@+id/parent"
        android:layout_gravity="center"
        android:layout_width="match_parent"
        android:orientation="vertical"
        android:gravity="center"
        android:layout_height="match_parent">
        <TextView
            android:id="@+id/name"
            android:layout_width="wrap_content"
            android:gravity="center"
            android:textSize="25sp"
            android:textColor="#FFF"
            android:layout_height="wrap_content" />
        <TextView
            android:id="@+id/age"
            android:layout_width="wrap_content"
            android:gravity="center"
            android:textSize="25sp"
            android:textColor="#FFF"
            android:layout_height="wrap_content" />
    </LinearLayout>
</android.support.v7.widget.CardView>

위 리스트 아이템 뷰에서는 CardView 안에 학생의 이름과 나이를 표시하는 두 개의 TextView를 배치했습니다. CardView는 미리 정의된 코너 반경(corner radius)그림자(shadow) 속성을 제공하므로, 이를 활용해 카드에 둥근 모서리 효과를 적용했습니다.

7단계 – studentData.java 작성

다음은 수정된 src/studentData.java 파일의 내용입니다.

package com.example.andy.tutorialspoint;

class studentData {
    String name;
    int age;

    public studentData(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

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

LinearLayoutManager로 RecyclerView 맨 위로 스크롤하는 방법 – 안드로이드 예제 가이드

이제 노란색 버튼(FloatingActionButton)을 클릭하면 RecyclerView가 맨 위로 부드럽게 스크롤되며, 결과는 다음과 같습니다.

LinearLayoutManager로 RecyclerView 맨 위로 스크롤하는 방법 – 안드로이드 예제 가이드