이 튜토리얼에서는 안드로이드에서 가로 방향으로 스크롤되는 수평(Horizontal) ListView를 만드는 방법을 단계별로 알아봅니다. 안드로이드에서는 일반적으로 RecyclerView의 LayoutManager를 LinearLayoutManager.HORIZONTAL로 지정하여 가로 스크롤 리스트를 손쉽게 구현할 수 있습니다.
Step 1 — 새 프로젝트 생성 및 의존성 추가
Android Studio에서 새 프로젝트를 생성합니다. 메뉴에서 File ⇒ New Project를 선택하고, 프로젝트 생성에 필요한 모든 세부 정보를 입력합니다.
그다음 아래 의존성을 Gradle 파일(app/build.gradle)에 추가합니다.
implementation 'com.android.support:recyclerview-v7:28.0.0' implementation 'com.android.support:cardview-v7:28.0.0'
RecyclerView로 리스트를 구성하고, 각 항목을 카드 형태로 보여주기 위해 CardView 라이브러리도 함께 추가했습니다.
Step 2 — 메인 레이아웃 작성 (activity_main.xml)
res/layout/activity_main.xml 파일에 다음 코드를 추가합니다.
<RelativeLayout xmlns:android="https://schemas.android.com/apk/res/android"
xmlns:tools="https://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="6dp"
tools:context=".MainActivity">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_centerInParent="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</RelativeLayout>Step 3 — MainActivity 작성
src/MainActivity.java 파일에 다음 코드를 추가합니다. 핵심은 LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false) 부분으로, 이 설정을 통해 리스트가 가로 방향으로 배치됩니다.
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.os.Bundle;
import java.util.ArrayList;
import java.util.Arrays;
public class MainActivity extends AppCompatActivity {
RecyclerView recyclerView;
RecyclerView.LayoutManager layoutManager;
RecyclerView.Adapter adapter;
ArrayList<String> numberName;
ArrayList<Integer> numberImage;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
numberName = new ArrayList<>(Arrays.asList("Four...", "Nine... ", "Seven...", "Six...", "Ten...", "Three...", "Two..."));
numberImage = new ArrayList<>(Arrays.asList(R.drawable.four, R.drawable.nine, R.drawable.seven,
R.drawable.six, R.drawable.ten, R.drawable.three, R.drawable.two));
// RecyclerView 호출
recyclerView = findViewById(R.id.recyclerView);
recyclerView.setHasFixedSize(true);
// 가로 방향 LayoutManager 설정
layoutManager = new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false);
recyclerView.setLayoutManager(layoutManager);
adapter = new MyAdapter(MainActivity.this, numberName, numberImage);
recyclerView.setAdapter(adapter);
}
}Step 4 — 어댑터 클래스 작성 (MyAdapter.java)
새 자바 클래스 MyAdapter.java를 생성하고 다음 코드를 추가합니다. 이 어댑터는 각 항목에 데이터를 바인딩하고, 클릭 및 롱클릭 이벤트도 처리합니다.
import android.content.Context;
import android.content.Intent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import java.util.ArrayList;
import androidx.recyclerview.widget.RecyclerView;
class MyAdapter extends RecyclerView.Adapter <MyAdapter.ViewHolder>{
private ArrayList<String>numberName;
private ArrayList<Integer> numberImage;
private Context context;
MyAdapter(Context context, ArrayList<String> numberName, ArrayList<Integer> numberImage) {
super();
this.context = context;
this.numberName = numberName;
this.numberImage = numberImage;
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
View v = LayoutInflater.from(viewGroup.getContext())
.inflate(R.layout.gridlayout, viewGroup, false);
return new ViewHolder(v);
}
@Override
public void onBindViewHolder(ViewHolder viewHolder, int i) {
viewHolder.textView.setText(numberName.get(i));
viewHolder.imgThumbnail.setImageResource(numberImage.get(i));
viewHolder.setClickListener(new ItemClickListener() {
@Override
public void onClick(View view, int position, boolean isLongClick) {
if (isLongClick) {
Toast.makeText(context, "#" + position + " - " + numberName.get(position) + " (Long click)", Toast.LENGTH_SHORT).show();
context.startActivity(new Intent(context, MainActivity.class));
} else {
Toast.makeText(context, "#" + position + " - " + numberName.get(position),
Toast.LENGTH_SHORT).show();
}
}
});
}
@Override
public int getItemCount() {
return numberName.size();
}
public static class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener,
View.OnLongClickListener {
ImageView imgThumbnail;
TextView textView;
private ItemClickListener clickListener;
ViewHolder(View itemView) {
super(itemView);
imgThumbnail = itemView.findViewById(R.id.imgThumbnail);
textView = itemView.findViewById(R.id.textView);
itemView.setOnClickListener(this);
itemView.setOnLongClickListener(this);
}
void setClickListener(ItemClickListener itemClickListener) {
this.clickListener = itemClickListener;
}
@Override
public void onClick(View view) {
clickListener.onClick(view, getPosition(), false);
}
@Override
public boolean onLongClick(View view) {
clickListener.onClick(view, getPosition(), true);
return true;
}
}
}
Step 5 — 리스트 항목 레이아웃 작성 (listitem.xml)
새 레이아웃 리소스 파일을 생성하고, 각 리스트 항목이 카드 형태로 보이도록 다음 코드를 작성합니다.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="https://schemas.android.com/apk/res/android"
xmlns:card_view="https://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="0dp"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:layout_marginTop="9dp"
card_view:cardCornerRadius="3dp"
card_view:cardElevation="0.01dp">
<RelativeLayout
android:id="@+id/topLayout"
android:layout_width="match_parent"
android:layout_height="160dp">
<ImageView
android:id="@+id/imgThumbnail"
android:layout_width="match_parent"
android:layout_height="150dp"
android:layout_above="@+id/textView"
android:layout_centerHorizontal="true"
android:scaleType="fitXY" />
<TextView
android:id="@+id/textView"
android:layout_width="fill_parent"
android:layout_height="40dp"
android:layout_alignParentBottom="true"
android:layout_alignParentStart="true"
android:layout_gravity="bottom"
android:background="#ff444444"
android:gravity="center_vertical"
android:paddingStart="5dp"
android:paddingEnd="2dp"
android:text="Test"
android:textColor="#fff"
android:textSize="20sp" />
</RelativeLayout>
</androidx.cardview.widget.CardView>
</LinearLayout>참고: 원본 코드의 TextView에는 anroid:background라는 오타가 있었지만, 빌드 오류를 방지하기 위해 위 코드에서는 올바른 android:background로 수정했습니다.
Step 6 — 클릭 리스너 인터페이스 작성 (ItemClickListener.java)
인터페이스 파일 ItemClickListener.java를 생성하고 다음 코드를 추가합니다.
import android.view.View;
interface ItemClickListener {
void onClick(View view, int position, boolean isLongClick);
}Step 7 — AndroidManifest.xml 설정
androidManifest.xml에 다음 코드를 추가합니다.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="https://schemas.android.com/apk/res/android"
package="app.com.sample">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>앱 실행하기
이제 애플리케이션을 실행해 보겠습니다. 실제 안드로이드 모바일 기기가 컴퓨터에 연결되어 있다고 가정합니다. Android Studio에서 프로젝트의 액티비티 파일 중 하나를 연 뒤, 툴바의
Run 아이콘을 클릭하세요. 실행 옵션에서 자신의 모바일 기기를 선택하면, 기기 화면에 가로 방향으로 스크롤되는 이미지 리스트가 표시되는 것을 확인할 수 있습니다.
