ListView와 ArrayAdapter, ArrayList를 이용하기 + 커스텀 리스트화면 만들기
ListView 사용 까닭
리스트 뷰는 단순하게 수직 리스트 화면을 구성하는 뷰다. View –> AdapterVIew –> ListView 의 상속관계를 갖고 있다.
리스트 뷰를 이용하는 까닭은? 우리가 뮤직 앱이나 트위터 같이 한정을 을수 없이 길게 늘어진 리스트를 구성할 떄 단순히 linear layout으로 구성한다면 어떻게 될까? 각각의 child를 한 번에 생성해야 하기 때문에 엄청난 메모리 소모가 있을 것이다. 이 때 ListView를 사용하면, 화면 밖에 안 보이는 부분의 child는 만들지 않고 스크롤 함에 따라 재사용 하여 메모리 소모를 최소화한다. (최근에는 더 발전한 RecyclerView)라는 게 나온 듯 싶다.)
링크 참조
https://developer.android.com/reference/android/widget/ListView
사용방법
ListView 는 혼자서는 작동할 수 없고, 그 안에 들어갈 resource 가 필요한데 ArrayList 오브젝트를 이용한다. 단 이 때 Arraylist가 바로 들어가는 게 아니고 ArrayAdapter가 중간에서 매개자 역할을 한다. 관계를 나타내면 다음과 같다.
ListView <–> ArrayAdapter(ArrayList)
즉 ListView가 화면을 구성하기 위해, 그 내용을 ArrayAdapter에게 요청하는 식이다. 리스트뷰는 껍데기라고 생각하자.
아래와 같이 출력을 원하는 xml에 리스트뷰를 하나 생성한다.
<ListView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/list"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"/>
해당 activity 의 oncreat method에 ArrayAdapter와 Arraylist를 구성해 보자.
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.example_activity);
// 먼저 리소스 파일인 Arraylist를 만든다.
ArrayList<String> words = new ArrayList<String>();
words.add("one");
words.add("two");
words.add("three");
words.add("four");
words.add("five");
//ArrayAdapter를 만들어준다.
//android.R.layout에서 제공하는 custom layout을 이용하자. 단순히 TextView가 하나 있는 xml이다.
//ArrayList words 를 마지막 인수로 넣어준다.
ArrayAdapter<String> itemsAdapter =
new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, words);
//아까 만든 xml파일에 있는 listView를 불러온다.
ListView listView = (ListView) findViewById(R.id.list);
//SetAdapter를 이용해 ListView와 ArrayAdapter를 연결한다.
listView.setAdapter(itemsAdapter);
}
custom list화면 만들기
ArrayAdapter는 각 행에 텍스트요소 하나씩만 들어갈 때만 사용 가능하다. 하지만 각 열에 텍스트가 두개라면? 이미지가 있다면? 이 때 custom object 와 custom Adapter가 필요할 때다.
custom class
텍스트가 두 개 들어가는 CustomWord
class를 구성해 보자.
public class CustomWord {
private String mS1;
private String mS2;
public String getS1(){
return mS1;
}
public String getS2(){
return mS2;
}
public CustomWord(String s1, String s2){
mS1 = s1;
mS2 = s2;
}
}
다음으로 android에서 기존 제공해줬던 android.R.layout.simple_list_item_1
대신에 사용할 textView를 두 개 갖는 layout xml파일을 하나 만들자. 이름은 customLayout.xml
로 하자.
리니어 레이아웃에 TextView 두 개를 넣으면 됨.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/text_view_1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceListItemSmall"
android:gravity="center_vertical"
android:padding="16dp"
android:minHeight="?android:attr/listPreferredItemHeightSmall" />
<TextView
android:id="@+id/text_view_2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceListItemSmall"
android:gravity="center_vertical"
android:padding="16dp"
android:minHeight="?android:attr/listPreferredItemHeightSmall" />
</LinearLayout>
이후 아까 구성해놨던 onCreat을 이렇게 바꾸자.
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.example_activity);
ArrayList<CustomWord> customWords = new ArrayList<CustomWord>();
words.add(new CustomWords("one","1"));
words.add(new CustomWords("two","2"));
words.add(new CustomWords("three","3"));
words.add(new CustomWords("four","4"));
words.add(new CustomWords("five","5"));
CustomArrayAdapter<CustomWord> itemsAdapter =
new CustomArrayAdapter<CustomWord>(this, customLayout.xml, words);
//아까 만든 xml파일에 있는 listView를 불러온다.
ListView listView = (ListView) findViewById(R.id.list);
//SetAdapter를 이용해 ListView와 ArrayAdapter를 연결한다.
listView.setAdapter(itemsAdapter);
}
ArrayAdapter 의 subclass만들기
다음으로는 AdapterAdapter의 subclass로서 텍스트 두개짜리 오브젝트를 가진 ArrayList
public class CustomArrayAdapter extends ArrayAdapter<CustomWord> {
private static final String LOG_TAG = WordAdapter.class.getSimpleName();
public CustomArrayAdapter(Activity context, ArrayList<CustomWord> CustomWords){
//컨스트럭터는 ArrayAdapter것을 갖다 썼다.
//두 번쨰 인수는 하나의 TextView를 사용할 떄만 들어가는 값이므로 여기서는 그냥 0을 넣었다.
super(context,0,words);
}
//아래와 같이 getView를 override하자.
@NonNull
@Override
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
// listItemView 에 convertView를 설정한다. convertView는 스크롤이 넘어가서 안 보이게 될 때
// 재활용되는 view다. 그래서 빈 값일 떄는 새로 만들어야 한다.
View listItemView = convertView;
if (listItemView ==null){
listItemView = LayoutInflater.from(getContext()).inflate(R.layout.list_item,parent,false);
}
// 아까 만든 클래스의 인스턴스를 만들고 getItem method를 이용 위치에 따른 내용물을 넣어준다.
CustomWord currentWord = getItem(position);
// 이후 각 TextView값을 get 메소드를 이용해 설정한다.
TextView textView1 = (TextView) listItemView.findViewById(R.id.text_view_1);
textView1.setText(currentWord.getS1());
TextView textView2 = (TextView) listItemView.findViewById(R.id.text_view_2);
textView2.setText(currentWord.getS2());
return listItemView;
}
}
댓글남기기