본문 바로가기
dev/android

안드로이드 커스텀 리스트뷰 구현

by NCJ 2018. 12. 7.
728x90
반응형
SMALL

안드로이드 커스텀 리스트뷰 구현



안드로이드 개발을 하다보면 리스트뷰를 사용하는경우 많이 있다.

다양한 형태로 리스트뷰를 커스텀하여 사용한다. 


이번엔 리스트뷰를 커스텀할때 사용하는 방법을 알아보도록 한다. 


리스트뷰는 어뎁터(Adapter) ,데이터(Data), 뷰(View) 로 구성한다.



보통 레이아웃에서 리스트뷰 위젯을 만들고 어뎁터클래스를 구성하여 그 어뎁터에 데이터랑 뷰을 넣고 아이템을 만들어 리스트뷰를 통해 보여지도록 한다. 



이제 소스를 통해 하나씩 확인해보자 


우선 레이아웃에 리스트뷰를 만들어 줍니다. 

Scrollbars='none' 는 리스트뷰에 스크롤바 표시를 안 보이도록 하기위해 넣은 것 입니다.


<ListView
android:id="@+id/lv_news"
android:scrollbars="none"
android:layout_width="match_parent"
android:layout_height="match_parent"/>



이제 뷰를 구성할텐데요. 제가 만들려고 하는 뷰는 아래와 같은 형태에 뷰입니다. 




위 화면에 소스코드는 아래와 같습니다. 

layout 포더에  item_news 라고 저는 만들었습니다.


<?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:orientation="vertical">


<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="8dp">

<ImageView
android:layout_width="80dp"
android:layout_height="80dp"
android:src="@mipmap/ic_launcher" />

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:orientation="vertical">

<TextView
android:id="@+id/tv_news_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="제목입니다."
android:textColor="#000000"
android:textSize="20dp"
android:textStyle="bold" />

<TextView
android:id="@+id/tv_news_contents"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:text="간단한 내용들이 표시될 TextView 입니다."
android:textColor="#666666"
android:textSize="13dp" />


<TextView
android:id="@+id/tv_news_date"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:text="2018-12-07"
android:textColor="#666666"
android:textSize="13dp" />


</LinearLayout>


</LinearLayout>

</LinearLayout>


이제 리스트에 표현되는 뷰도 만들었으니 Data클래스를 만들어 데이터를 사용하도록 해보겠습니다.  

위 뷰에서 사용된 위젯은 이미지뷰, 텍스트뷰 3개입니다. 

그럼 우선 이미지에 대한 데이터랑 텍스트뷰에 들어갈 데이터를 구성하는 Data클래스 만들겠습니다. 


처음에 NewsItem 클래스에 데이터 변수를 넣고  ALT + INS 키를 누른 다은 Getter/Setter 항목을 클릭하고 변수들을 지정하여 만드시면 쉽게 만들 수 있습니다. 



public class NewsItem {

int ImageRes;
String Title, Contens, Data;


public int getImageRes() {
return ImageRes;
}

public void setImageRes(int imageRes) {
ImageRes = imageRes;
}

public String getTitle() {
return Title;
}

public void setTitle(String title) {
Title = title;
}

public String getContens() {
return Contens;
}

public void setContens(String contens) {
Contens = contens;
}

public String getData() {
return Data;
}

public void setData(String data) {
Data = data;
}
}

이렇게 데이터클래스를 만들어 나중에 객체형태로 데이터를 넣고 

객체를 다시 어뎁터로 넘겨서 사용하도록 하겠습니다. 

다음은 어뎁터를 만들어보 겠습니다.


리스트뷰에 보여질 아이템 수가 많으므로 ArrayList에 데이터 클래스를 객체화하여 넣고 사용합니다.

LayoutInflater는 XML파일을 뷰 객체로 만들기 위해서 사용됩니다. 


setItem은 데이터르 변경하기 위해 만든 메소드 입니다. 

notifyDataSetChanged()는 변경된 데이터 리스트를 리스트뷰에 갱신하기 위하여 사용됩니다.


Holder는 보통 ViewHolder 라고 칭하는데 리스트뷰는 스크롤이 가능한 위젯입니다. 

화면에 보여지는 뷰들이 스크롤시 사라지는 경우 그 뷰를 다시 재활용할 수 있도록 뷰홀드를 사용하여

리스트뷰 사용시 메모리 및 성능적으로 개선 할 수 있습니다.


import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;

import java.util.ArrayList;

public class NewsAdapter extends BaseAdapter {

ArrayList<NewsItem> mItems;
Context mContext;
LayoutInflater inflater;

public NewsAdapter( Context context, ArrayList<NewsItem> items) {
this.mItems = new ArrayList<>();
this.mItems.addAll(items);
this.mContext = context;
this.inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}

public void setItem(ArrayList<NewsItem> items) {
if (mItems != null) {
mItems.clear();
mItems.addAll(items);
notifyDataSetChanged();
}
}

@Override
public int getCount() {
return mItems.size();
}

@Override
public Object getItem(int position) {
return mItems.get(position);
}

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

class Holder {
ImageView iv_Img;
TextView tv_Title, tv_Contens, tv_Data;

}

@Override
public View getView(int position, View convertView, ViewGroup parent) {

final Holder holder;

if (convertView == null) {
convertView = inflater.inflate(R.layout.item_news, parent, false);
holder = new Holder();

holder.iv_Img = convertView.findViewById(R.id.iv_news_img);
holder.tv_Title = convertView.findViewById(R.id.tv_news_title);
holder.tv_Contens = convertView.findViewById(R.id.tv_news_contents);
holder.tv_Data = convertView.findViewById(R.id.tv_news_date);

convertView.setTag(holder);

} else {
holder = (Holder) convertView.getTag();
}

NewsItem item = mItems.get(position);

if (item != null) {
holder.iv_Img.setImageResource(item.getImageRes());
holder.tv_Title.setText(item.getTitle());
holder.tv_Contens.setText(item.getContens());
holder.tv_Data.setText(item.getData());
}

return convertView;
}
}

어댑터을 만들었으니 어뎁터에 데이터를 넣어서 리스트뷰로 출력해보겠습니다. 

MainActivity에서 리스트뷰에 어뎁터를 설정하고 데이터를 넣겠습니다. 

메인에서도 ArrayList를 만들어서 한 번에 데이터를 업데이트 하도록 합니다. 

 

for문을 돌려  NewsItem 객체에 데이터 넣고 ArrayList에 넣어줍니다.

for문이 끝난 후 adapter.setItem() 메소드에 ArrayList 넣고 데이터를 교체 후 갱신해주면 디바이스 화면에 리스트뷰에서 만든 아이템을 확인 할 수 있습니다. 


import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.ImageView;
import android.widget.ListView;

import java.util.ArrayList;

public class MainActivity extends AppCompatActivity {

ListView m_LvNews;
ArrayList<NewsItem> mItems = new ArrayList<>();
NewsAdapter adapter;


@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

m_LvNews = findViewById(R.id.lv_news);
adapter = new NewsAdapter(this, mItems);
m_LvNews.setAdapter(adapter);


for (int i = 0; i < 30; i++) {
NewsItem item = new NewsItem();
item.setImageRes(R.mipmap.ic_launcher);
item.setTitle("뉴스 제목 입니다. "+i);
item.setContens("뉴스에 표시될 간단한 내용입니다.");
item.setData("2018-12-07");
mItems.add(item);
}

adapter.setItem(mItems);

}
}


이렇게 하면  리스트뷰에 총 30개에 리스트 아이템이 생성됩니다. 

실행결과 화면을 보도록 하겠습니다. 





이렇게 자신이 원하는 디자인으로 리스트뷰를 구성하여 보여질 수 있습니다. 레이아웃 디자인을 변경으로 좀더 다양한 형태에 리스트뷰를 구성 할 수도 있습니다. 


감사합니다. 










728x90
반응형
LIST

'dev > android' 카테고리의 다른 글

안드로이드 공유하기  (0) 2018.12.20
안드로이드 수행시간 체크  (0) 2018.12.19
안드로이드 콜백 만들기  (0) 2018.12.18
android custom dialog 만들기  (0) 2018.12.18
Android 이미지로딩 Glide 라이브러리  (0) 2018.11.20