리스트 컨트롤 ListView – 기본 사용법
매우 자주 사용되는 컨트롤입니다.
화면 공간은 한정되어 있지만, 이 컨트롤을 사용하면 화면에 더 많은 데이터를 표시할 수 있습니다.
손가락으로 위아래로 스와이프하면 화면 밖의 데이터를 화면 안으로 가져올 수 있습니다.
기본 사용법
새로운 TestListView 프로젝트를 만듭니다.
레이아웃에 다음 코드를 추가하여 ListView를 넣습니다.
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:id="@+id/listview1"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>Code language: HTML, XML (xml)
데이터 소스 초기화
public class MainActivity extends AppCompatActivity {
private String[] courses = {"Java 입문", "Android 입문", "C# 입문", "C 언어", "ASP.NET MVC"};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(MainActivity.this, android.R.layout.simple_list_item_1, courses);
ListView listView = (ListView) findViewById(R.id.listview1);
listView.setAdapter(adapter);
}
}Code language: JavaScript (javascript)
이 데이터는 웹에서 다운로드(예: Web API), 데이터베이스에서 읽어오거나, 심지어 코드에서 문자열 배열로 직접 정의할 수도 있습니다.
데이터는 ListView에 직접 전달할 수 없으므로 어댑터를 통해 전달해야 합니다.
Android는 많은 어댑터를 제공하며, 여기서는 ArrayAdapter를 사용합니다.
ListView의 자식 레이아웃으로 android.R.layout.simple_list_item_1을 사용합니다.
이는 Android에 내장된 레이아웃 파일로, TextView 하나만 있어 텍스트를 표시합니다.

리스트 컨트롤 ListView – 인터페이스 사용자 정의
단순히 텍스트를 표시하는 것은 너무 단조롭습니다
리스트 항목에 더 풍부한 내용을 표시할 수 있습니다.
Book 엔티티 클래스 추가
package com.foxdevelop.www.testlistview;
public class Book {
private String name;
private int imageId;
public Book (String name, int imageId) {
this.name = name;
this.imageId = imageId;
}
public String getName() {
return name;
}
public int getImageId() {
return imageId;
}
}Code language: PHP (php)
Book 레이아웃 파일 추가
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/imageid"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginLeft="12dp"
/>
</LinearLayout>Code language: HTML, XML (xml)
사용자 정의 어댑터
package com.foxdevelop.www.testlistview;
import android.content.Context;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import java.util.List;
public class BookAdapter extends ArrayAdapter<Book> {
private int resource;
public BookAdapter(@NonNull Context context, int resource, @NonNull List<Book> objects) {
super(context, resource, objects);
this.resource = resource;
}
@NonNull
@Override
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
Book book = getItem(position);
View view = LayoutInflater.from(getContext()).inflate(resource, parent, false);
ImageView imageView = (ImageView) view.findViewById(R.id.imageid);
imageView.setImageResource(book.getImageId());
TextView name = (TextView) view.findViewById(R.id.name);
name.setText(book.getName());
return view;
}
}Code language: JavaScript (javascript)
액티비티의 onCreate에서 데이터 소스 초기화
package com.foxdevelop.www.testlistview;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
private List<Book> courses = new ArrayList<Book>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
LoadBooks();
BookAdapter adapter = new BookAdapter(MainActivity.this, R.layout.booklistview, courses);
ListView listView = (ListView) findViewById(R.id.listview1);
listView.setAdapter(adapter);
}
private void LoadBooks() {
courses.add(new Book("인류 사상사상 제1", R.drawable.access));
courses.add(new Book("착취 단계 정치", R.drawable.book));
courses.add(new Book("고대 인도 법의 귀중한 문헌", R.drawable.bookmarks));
courses.add(new Book("흠정 로마 사법 교과서", R.drawable.center));
courses.add(new Book("지식은 힘이다", R.drawable.date));
courses.add(new Book("나의 민법전은 영원히 존재한다", R.drawable.clock));
courses.add(new Book("미국 민주주의 연구의 고전", R.drawable.ftp));
courses.add(new Book("서양 국제법 권위 교재", R.drawable.notes));
courses.add(new Book("역사적 진실에 가장 가까운 역작", R.drawable.set));
courses.add(new Book("종교 개혁의 거울", R.drawable.energy));
courses.add(new Book("신학의 비밀은 인본학", R.drawable.tux));
courses.add(new Book("300여 년 전 중국에 소개된 명저", R.drawable.science));
courses.add(new Book("위선자를 묘사한 천고의 걸작", R.drawable.joystick));
courses.add(new Book("담장 없는 명문 대학", R.drawable.center));
courses.add(new Book("인류 사상사상 최초의 유토피아 방안", R.drawable.access));
}
}Code language: JavaScript (javascript)
다음 설정을 통해
android:orientation=”horizontal”
가로로 배치할 수 있습니다.


ListView 성능 최적화
현재 액티비티를 열 때마다 데이터 소스를 다시 로드하므로 실행 효율에 영향을 줍니다. View를 캐시하면 속도를 향상시킬 수 있습니다.
convertView를 확인하여 매번 뷰를 가져오지 않아도 됩니다.
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
Book book = getItem(position);
View view;
if (convertView == null) {
view = LayoutInflater.from(getContext()).inflate(resource, parent, false);
} else {
view = convertView;
}
ImageView imageView = (ImageView) view.findViewById(R.id.imageid);
imageView.setImageResource(book.getImageId());
TextView name = (TextView) view.findViewById(R.id.name);
name.setText(book.getName());
return view;
}Code language: PHP (php)
컨트롤 캐시
이미지 컨트롤과 텍스트 컨트롤을 저장하는 클래스를 정의합니다.
class ViewData {
ImageView imageUI;
TextView textViewUI;
}Code language: JavaScript (javascript)
package com.foxdevelop.www.testlistview;
import android.content.Context;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import java.util.List;
public class BookAdapter extends ArrayAdapter<Book> {
private int resource;
public BookAdapter(@NonNull Context context, int resource, @NonNull List<Book> objects) {
super(context, resource, objects);
this.resource = resource;
}
@NonNull
@Override
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
Book book = getItem(position);
View view;
ViewUI viewUI;
if (convertView == null) {
view = LayoutInflater.from(getContext()).inflate(resource, parent, false);
ImageView imageView = (ImageView) view.findViewById(R.id.imageid);
TextView textView = (TextView) view.findViewById(R.id.name);
viewUI = new ViewUI();
viewUI.imageUI = imageView;
viewUI.textViewUI = textView;
view.setTag(viewUI);
} else {
view = convertView;
viewUI = (ViewUI) view.getTag();
}
viewUI.imageUI.setImageResource(book.getImageId());
viewUI.textViewUI.setText(book.getName());
return view;
}
class ViewUI {
ImageView imageUI;
TextView textViewUI;
}
}Code language: JavaScript (javascript)
ListView 클릭 이벤트
listview 항목에 클릭 이벤트 추가하기
예를 들어, 각 항목을 클릭할 때 책 이름을 표시하도록 구현합니다.
메인 액티비티의 onCreate 내부에서:

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
LoadBooks();
BookAdapter adapter = new BookAdapter(MainActivity.this, R.layout.booklistview, courses);
final ListView listView = (ListView) findViewById(R.id.listview1);
listView.setAdapter(adapter);
// 클릭 이벤트
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
Book b = courses.get(i);
Toast.makeText(MainActivity.this, b.getName(), Toast.LENGTH_LONG).show();
}
});
}Code language: PHP (php)
gradle의 dependencies에 라이브러리 추가
Configuration ‘compile’ is obsolete and has been replaced with ‘implementation’ and ‘api’.
2018년 말에 제거될 예정입니다. 자세한 내용은 다음을 참조하세요: http://d.android.com/r/tools/update-dependency-configurations.html
다음 종속 라이브러리에 대한 지원을 추가해야 합니다:
android.support.v7.widget.RecyclerView

<?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="match_parent">
<android.support.v7.widget.RecyclerView
android:id="@+id/testrecy"
android:layout_width="match_parent"
android:layout_height="match_parent">
</android.support.v7.widget.RecyclerView>
</LinearLayout>Code language: HTML, XML (xml)
스크롤 컨트롤 RecyclerView 사용 – 1
ListView는 매우 강력하며 오늘날에도 많은 앱에서 사용되고 있습니다.
하지만 성능이 약간 떨어지고 확장성이 좋지 않습니다.
데이터의 세로 스크롤만 구현할 수 있으며 가로 스크롤은 불가능합니다.
RecyclerView는 ListView의 향상된 버전입니다.
ListView와 동일한 효과를 구현할 수 있으며 단점을 개선했습니다.
공식적으로는 RecyclerView 사용을 권장합니다.
기본 사용법
먼저 gradle에 다음을 추가하세요:
compile ‘com.android.support:recyclerview-v7:27.1.1’
이전 섹션에서 다른 RecyclerView를 추가했습니다.
<android.support.v7.widget.RecyclerView
android:id="@+id/testrecy"
android:layout_width="match_parent"
android:layout_height="match_parent"/>Code language: HTML, XML (xml)
계속해서 책 예제를 사용합니다.