안드로이드 Custom ListView를 만들어보자

개발/안드로이드 2017. 9. 28. 09:54
반응형

1. 안드로이드 Custom ListView를 만들어보자

2. 안드로이드 Custom Listview 이벤트 적용

3. 안드로이드 ListView 동작방식 이해하기


ListView는 전화 앱의 연락처 나 메시지(SMS) 앱의 목록 처럼 표현해주는 위젯입니다.

스크롤뷰에 라벨을 붙여서 해도 표현해도 되는데 왜 전화 앱이나 메시지 앱의 경우 ListView를 이용하여야 할까요?


그건 반복된 데이터를 표시 할 때 ScrollView에 TextView, ImageView 위젯등을 올려 놓고 컨트롤 하는거 보다 효율적이고 간단합니다.

데이터가 100개, 1000개든 동일하게 처리가 가능하죠.

그리고 데이터 수치만큼 UI를 생성하는 방식이 아니므로 메모리면에서도 훨씬 절약 할 수 있습니다.


이번에는 ListView의 구조나 구현방법에 대한 설명을 하고 다음 강좌에 이벤트, 데이터가 많을 경우 어떻게 메모리 관리를 하는지에 대해 알아보려고 합니다.

불필요하거나 복잡한 구조는 배제하고 최대한 이해하기 쉽도록 심플하게 코드를 만들었습니다. (나만 그렇게 생각할지도..)

하단에 샘플프로젝트도 올렸으니 테스트해보시면 쉽게 이해하실 수 있지 않을까합니다.



0. ListView 위젯 구조

ListView는 데이터 목록을 아이템 단위로 구성하여 각 행을 표현 하고 있습니다.

ListView는 각 아이템을 직접 표현하지 않습니다. Adapter를 통해 UI(위젯)를 표현해 주고 있습니다.

Adapter에서는 각 아이템마다 getView 메소드를 호출해서 View를 구성 할 수 있는 방식을 사용하고 있습니다. 


이번 예제에서는 아래 이미지와 같이 제목, 날짜, 버튼을 포함하고 있는 ListView를 만들어 볼 예정입니다.



아래 이미지를 통해 신규/수정 해야할 파일을 미리 알고 시작하면 이해하는데 도움이 되지 않을까 합니다.


이제 시작해볼까요? 

1. Layout 작성

Layout은 ListView 위젯, 각 아이템을 표시 할 Item Layout 두개를 작성합니다. 

  

  1-1) ListView 위젯

  MainActivity Layout 인 "activity_main.xml"에 ListView 위젯을 만듭니다.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="twomix.co.kr.listviewsample.MainActivity"
tools:layout_editor_absoluteY="81dp"
tools:layout_editor_absoluteX="0dp">

<ListView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/listView"
/>

</LinearLayout>


  1-2) Item Layout

"listview_item.xml"을 만들어 아래 이미지와 같이 만듭니다.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="80dp">

<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="75"
android:orientation="vertical">

<TextView
android:id="@+id/textTitle"
android:layout_width="match_parent"
android:layout_height="0dp"
android:text="제목"
android:layout_weight="60"
android:gravity="center_vertical"
android:paddingLeft="10dp"
android:textStyle="bold"
android:textColor="#33aabb"
/>
<TextView
android:id="@+id/textDate"
android:layout_width="match_parent"
android:layout_height="0dp"
android:text="날짜"
android:layout_weight="40"
android:gravity="center_vertical"
android:paddingLeft="10dp"
/>
</LinearLayout>

<Button
android:layout_width="0dp"
android:layout_height="match_parent"
android:text="선택"
android:layout_weight="20"
/>
<View
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="5"
/>
</LinearLayout>




2. Item Data Class 생성

public class ItemData
{
public String strTitle;
public String strDate;
}

각 아이템에 들어갈 데이터 Class 입니다.


3. Adapter Class 생성 및 동작 방법

Custom ListView를 만들기 위해서는 Adapter 를 확장해야 합니다. 

일반적으로 ArrayAdapter와 BaseAdapter를 많이 사용하는데 예제에서는 BaseAdapter를 사용하도록 하겠습니다. 

개인적으로 BaseAdapter를 많이 사용합니다.

public class ListAdapter extends BaseAdapter
{
LayoutInflater inflater = null;
private ArrayList<ItemData> m_oData = null;
private int nListCnt = 0;

public ListAdapter(ArrayList<ItemData> _oData)
{
m_oData = _oData;
nListCnt = m_oData.size();
}

@Override
public int getCount()
{
Log.i("TAG", "getCount");
return nListCnt;
}

@Override
public Object getItem(int position)
{
return null;
}

@Override
public long getItemId(int position)
{
return 0;
}

@Override
public View getView(int position, View convertView, ViewGroup parent)
{
if (convertView == null)
{
final Context context = parent.getContext();
if (inflater == null)
{
inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
convertView = inflater.inflate(R.layout.listview_item, parent, false);
}

TextView oTextTitle = (TextView) convertView.findViewById(R.id.textTitle);
TextView oTextDate = (TextView) convertView.findViewById(R.id.textDate);

oTextTitle.setText(m_oData.get(position).strTitle);
oTextDate.setText(m_oData.get(position).strDate);
return convertView;
}
}

위 코드에서 ListAdapter (생성자), getCount, getView 메소드 유심히 봐야할 곳이며, 필수로 구현해야하는 메소드 입니다. 


 생성자

 Data를 셋팅합니다.

 getCount

 화면이 갱신되기전에 호출됩니다. 처음 생성 될때도 getCount가 호출되어 아이템이 몇개 그려질지 결정 하게 됩니다. 

 getView

 return 할때 각 Item Layout을 넘겨주면 화면에 표시해 줍니다.

 positon 으로 현재 몇번째 아이템이 표시해야되는지 알 수 있습니다. 


4. ItemData 생성, ListView, Adapter 생성 및 연결

이제 모든 준비 작업은 끝나고 화면에 연결 작업을 하면됩니다.

MainActivity의 onCreate에서 연결 작업을 해보도록 하겠습니다. 

public class MainActivity extends AppCompatActivity
{
private ListView m_oListView = null;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

// 데이터 1000개 생성--------------------------------.
String[] strDate = {"2017-01-03", "1965-02-23", "2016-04-13", "2010-01-01", "2017-06-20",
"2012-07-08", "1980-04-14", "2016-09-26", "2014-10-11", "2010-12-24"};
int nDatCnt=0;
ArrayList<ItemData> oData = new ArrayList<>();
for (int i=0; i<1000; ++i)
{
ItemData oItem = new ItemData();
oItem.strTitle = "데이터 " + (i+1);
oItem.strDate = strDate[nDatCnt++];
oData.add(oItem);
if (nDatCnt >= strDate.length) nDatCnt = 0;
}

// ListView, Adapter 생성 및 연결 ------------------------
m_oListView = (ListView)findViewById(R.id.listView);
ListAdapter oAdapter = new ListAdapter(oData);
m_oListView.setAdapter(oAdapter);
}
}


데이터는 1000개를 생성하였습니다. 이제 실행 후 결과 화면을 확인해 보도록 합시다. 


아래 예제 소스를 통해 직접 돌려보고 익혀 봅시다.

ListViewSample.zip



다음에는 이벤트 및 동작 방식에 대해 설명하도록 하겠습니다. 



반응형
admin