1. Adapter
ListView에 사용자가 정의한 데이터를 표시하기 위해서는 Adapter를 사용해야 합니다. 어댑터(Adapter)는 사용자의 데이터를 받아 뷰(View)를 생성해주는 객체로 ListView와는 독립적으로 동작하는 객체입니다. ListView는 Adpater로부터 생성된 뷰(View)를 받아 ListView의 한 항목으로 배치합니다. 어댑터(Adapter)는 관리되는 데이터와 제공하는 뷰(View) 형태에 따라 종류가 다양합니다.
![](./files/attach/images/525/469/307/9477b921c9c296fe529a8b379fc6502b.png)
2. 리스트뷰(ListView) 구현
2.1 구현 순서
![](./files/attach/images/525/469/307/522630995dd4e9fff4ef051521bfbf61.png)
▼ ListView를 사용하기 위해서는 당연히 ListView를 화면에 올려야 합니다. 그러기 위해 먼저 XML 레이아웃 리소스에 ListView를 정의해줍니다.
▼ ListView에 표현할 데이터 객체를 생성하기 위한 Movie Class를 생성합니다. 해당 클래스의 객체를 생성하여 ArrayList에 담아 Adapter에서 관리하도록 구현할 것입니다.
▼ Adapter에서 각 데이터 항목에 대하여 뷰(View)를 생성하기 위해서는 미리 정의된 XML 레이아웃 리소스를 사용합니다. 해당 XML 레이아웃 리소스를 전개자(Inflater)를 통해 각 뷰(View)가 참조를 얻어 현재 아이템 항목에 해당하는 데이터를 바인딩하여 뷰(View)를 생성한 뒤 해당 뷰(View)를 반환해주는 함수를 구현해야 합니다.
▼ Adapter 구현이 끝나면 구현한 Adapter와 ListView를 연결해주는 작업을 진행합니다. 그다음으로 ListView에 Click 이벤트를 연결하면 예제 구현이 끝납니다.
2.2 MainActivity의 레이아웃 리소스와 ListView의 레이아웃 리소스
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<ListView
android:id="@+id/listView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</android.support.constraint.ConstraintLayout>
▼ 앱이 메인 화면이 되는 레이아웃 리소스 형태는 ConstraintLayout 아래에 ListView를 배치한 형태입니다.
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.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:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="@+id/linearLayout3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<ImageView
android:id="@+id/poster"
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_weight="1"
android:scaleType="fitXY"
tools:srcCompat="@tools:sample/backgrounds/scenic[2]" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/movieName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="TextView" />
<TextView
android:id="@+id/grade"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:text="TextView" />
</LinearLayout>
</LinearLayout>
</android.support.constraint.ConstraintLayout>
▼ 위 XML 레이아웃 리소소는 ListView에 각각의 데이터 항목을 표현하기 위한 레이아웃 리소스입니다.
수평 LinearLayout 아래에 ImageView와 수직 LinearLayout을 배치였고 수직 LinearLayout 아래는 TextView 2개를 배치한 형태입니다.
![](./files/attach/images/525/469/307/241050d84b8a5db0b5fb33da38392388.png)
2.3 데이터 클래스 생성
public class SampleData {
private int poster;
private String movieName;
private String grade;
public SampleData(int poster, String movieName, String grade){
this.poster = poster;
this.movieName = movieName;
this.grade = grade;
}
public int getPoster()
{
return this.poster;
}
public String getMovieName()
{
return this.movieName;
}
public String getGrade()
{
return this.grade;
}
}
▼ SampleData 클래스는 영화 정보를 담기 위해 생성한 클래스입니다. 해당 클래스는 영화 Poster Image가 있는 리소스 ID를 담는 int형 멤버 변수와 영화제목을 담기위한 String 형 멤버변수 그리고 등급을 표시하기 위한 String 형 멤버 변수를 포함하고 있습니다. 생성자 함수를 통해 각 멤버 변수의 데이터 값들을 Setting하고 getter 함수를 구현하여 각 멤버변수의 값들을 return 하도록 구현하였습니다.
2.3 어댑터(Adapter) 구현
public class MyAdapter extends BaseAdapter {
Context mContext = null;
LayoutInflater mLayoutInflater = null;
ArrayList<SampleData> sample;
public MyAdapter(Context context, ArrayList<SampleData> data) {
mContext = context;
sample = data;
mLayoutInflater = LayoutInflater.from(mContext);
}
@Override
public int getCount() {
return sample.size();
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public SampleData getItem(int position) {
return sample.get(position);
}
@Override
public View getView(int position, View converView, ViewGroup parent) {
View view = mLayoutInflater.inflate(R.layout.listview_custom, null);
ImageView imageView = (ImageView)view.findViewById(R.id.poster);
TextView movieName = (TextView)view.findViewById(R.id.movieName);
TextView grade = (TextView)view.findViewById(R.id.grade);
imageView.setImageResource(sample.get(position).getPoster());
movieName.setText(sample.get(position).getMovieName());
grade.setText(sample.get(position).getGrade());
return view;
}
}
▼ BaseAdapter를 상속받아 MyAdapter를 구현합니다. 생성자 함수를 통해 ListView를 통해 표현하기 위한 사용자 정의 데이터인 ArrayList형 변수를 넘겨받아 sample이라는 참조 변수가 참조하도록 합니다.
▼ 주목해야 할 재정의 함수는 getView() 함수입니다. getView() 함수는 각 데이터 항목에 대하여 ListView에 표현하기 위한 뷰(View)를 생성하는 함수입니다. 전개자(Inflater)를 통해 listview_custom의 내용을 파싱 하여 뷰(View)들을 객체화합니다. 그리고 각 Widget의 참조를 얻어와 현재 표현하고자 하는 데이터 값들을 지정해줍니다.
2.4 어댑터(Adapter)와 리스트뷰(ListView) 연결하기 / Click Event 연결
public class MainActivity extends AppCompatActivity {
ArrayList<SampleData> movieDataList;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
this.InitializeMovieData();
ListView listView = (ListView)findViewById(R.id.listView);
final MyAdapter myAdapter = new MyAdapter(this,movieDataList);
listView.setAdapter(myAdapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener(){
@Override
public void onItemClick(AdapterView parent, View v, int position, long id){
Toast.makeText(getApplicationContext(),
myAdapter.getItem(position).getMovieName(),
Toast.LENGTH_LONG).show();
}
});
}
public void InitializeMovieData()
{
movieDataList = new ArrayList<SampleData>();
movieDataList.add(new SampleData(R.drawable.movieposter1, "미션임파서블","15세 이상관람가"));
movieDataList.add(new SampleData(R.drawable.movieposter2, "아저씨","19세 이상관람가"));
movieDataList.add(new SampleData(R.drawable.movieposter3, "어벤져스","12세 이상관람가"));
}
}
▼ 이제 어댑터(Adapter)와 리스튜뷰(ListView)를 연결해야 합니다. 그전에 먼저 Adapter에 넘겨줄 데이터를 초기화해야 합니다. 위 코드에서 InitializeMovieData() 함수를 통해 Type이 SampleData인 ArrayList에 데이터를 추가하고 있습니다.
▼ 앞서 구현했던 MyAdapter 객체를 생성합니다. 생성자 함수로 앞서 초기화했던 movieDataList를 넘겨주어 해당 Adapter 데이터를 관리하도록 합니다. 그런 다음 ListView의 setAdapter() 함수를 통해 어댑터와 리스트뷰를 연결합니다.
▼Click Event는 AdapterView.onItemClickListener 구현체를 익명 클래스 형태로 구현합니다. 특정 아이템 항목이 클릭되었을 때 재정의한 onItemClick() 함수가 호출되고 해당 함수 내에서 ListView Click에 대한 처리를 진행하시면 됩니다. 위 예제에서는 클릭된 영화의 제목을 Toast 메시지를 통해 띄우고 있습니다.
![](./files/attach/images/525/469/307/04043d19e058885bffb7b75bf1ab22ca.png)