본문 바로가기
dev/android

안드로이드 HeadView & FooterView 커스텀 리스트뷰

by NCJ 2019. 1. 1.
728x90
반응형
SMALL

안드로이드 커스텀 리스트 뷰 만들기

HeadView 와 FooterView 사용도 같이 알아보겠습니다.

<설명>

위에 보시는 사진이 리스트 뷰에 위에 붙여질 headview입니다. 
리스트 뷰에 아이템들은 리스트 형식으로 뿌려지며 스크롤이 가능합니다. 
그런 리스트 뷰 상단에 해당 뷰를 고정시켜 놓고 사용할 수 있는 것이 HEADVIEW입니다. 
리스트 뷰를 스크롤 할 시 헤더 뷰도 같이 스크롤 할 수 있도록 합니다. 
즉 헤더 뷰를 붙여 리스트 뷰 최상단의 아이템이 되는 것입니다. 

아이템 리스트 최하단의 위치할 수 있는 FOOTERVIEW입니다. 리스트 뷰를 스크롤 하여 가장 최하단의 위치 시킬 수 있습니다. heradview 마찬가지로 스크롤 할 시 같이 움직입니다. 

<소스 코드>

activity_main.xml 
액티비티 메인의 리스트 뷰 하나만 생성합니다. 


<?xml version="1.0" encoding="utf-8"?> <LinearLayout 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:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="kr.co.ncj.myapplication.MainActivity"> <ListView android:id="@+id/list_view" android:layout_width="match_parent" android:layout_height="match_parent"> </ListView> </LinearLayout>


HEADTERVIEW 만들기

HEADTERVIEW를 새로운 XML로 만들어 줍니다. 

텍스트 뷰 백그라운드는 간단하게 만들어 봤습니다.
 drawable 폴더에서 새롭게 리소스를 생성하여 만들었습니다.

<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android"> <stroke android:color="#6b6b6b" android:width="2dp"/> <solid android:color="#fff"/> <corners android:radius="1dp"/> </shape>

<HEADTERVIER 소스 >

<?xml version="1.0" encoding="utf-8"?> <LinearLayout android:orientation="vertical" xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content"> <LinearLayout android:background="#291515" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="wrap_content"> <TextView android:textColor="#128ec7" android:textSize="35dp" android:gravity="center" android:layout_gravity="center" android:text="HERADTER VIEW" android:padding="20dp" android:layout_width="match_parent" android:layout_height="wrap_content"/> </LinearLayout> <LinearLayout android:orientation="horizontal" android:layout_margin="3dp" android:padding="5dp" android:layout_width="match_parent" android:layout_height="wrap_content"> <TextView android:padding="5dp" android:layout_margin="3dp" android:gravity="center" android:layout_gravity="center" android:background="@drawable/item" android:text="아이템" android:layout_weight="1" android:layout_width="wrap_content" android:layout_height="wrap_content"/> <TextView android:padding="5dp" android:layout_weight="1" android:layout_margin="3dp" android:gravity="center" android:layout_gravity="center" android:background="@drawable/item" android:text="가격" android:layout_width="wrap_content" android:layout_height="wrap_content"/> <TextView android:padding="5dp" android:layout_weight="1" android:layout_gravity="center" android:gravity="center" android:layout_margin="3dp" android:background="@drawable/item" android:text="갯수" android:layout_width="wrap_content" android:layout_height="wrap_content"/> </LinearLayout> </LinearLayout>

FOOTERVIEW도 새로운 xml의 만들어 줍니다. 

<FOOTERVIEW 소스>

<?xml version="1.0" encoding="utf-8"?> <LinearLayout android:orientation="vertical" xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content"> <LinearLayout android:background="#291515" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="wrap_content"> <TextView android:textColor="#128ec7" android:textSize="35dp" android:gravity="center" android:layout_gravity="center" android:text="FOOTER VIEW" android:padding="20dp" android:layout_width="match_parent" android:layout_height="wrap_content"/> </LinearLayout> </LinearLayout

커스텀 리스트 뷰 아이템 레이아웃

<item 소스>

<?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"> <LinearLayout android:orientation="horizontal" android:layout_margin="3dp" android:padding="5dp" android:layout_width="match_parent" android:layout_height="wrap_content"> <TextView android:id="@+id/item_name" android:padding="5dp" android:layout_margin="3dp" android:gravity="center" android:layout_gravity="center" android:background="@drawable/item" android:text="" android:layout_weight="1" android:layout_width="wrap_content" android:layout_height="wrap_content"/> <TextView android:id="@+id/item_price" android:padding="5dp" android:layout_weight="1" android:layout_margin="3dp" android:gravity="center" android:layout_gravity="center" android:background="@drawable/item" android:text="" android:layout_width="wrap_content" android:layout_height="wrap_content"/> <TextView android:id="@+id/item_count" android:padding="5dp" android:layout_weight="1" android:layout_gravity="center" android:gravity="center" android:layout_margin="3dp" android:background="@drawable/item" android:text="" android:layout_width="wrap_content" android:layout_height="wrap_content"/> </LinearLayout> <LinearLayout android:background="#6b6b6b" android:layout_width="match_parent" android:layout_height="1dp"> </LinearLayout> </LinearLayout>

<MainActivity 소스>
LayoutInflater inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
View headterview = inflater.inflate(R.layout.headview, null);
View footerview = inflater.inflate(R.layout.footview, null);

layoutinflater를 통해 뷰에 레이아웃을 넣을 수 있습니다.

headterview 와 footerview의 레이아웃을 각각의 뷰에 넣고 

listView.addHeaderView(headterview);
listView.addFooterView(footerview);


addHeaderView() 메서드를 통해 리스트 뷰에 headview를 삽입합니다.
addFooterView() 메서드를 통해 리스트 뷰에 footerview를 삽입합니다.

 adepter = new Adepter(this, R.layout.listitem, values);
 listView.setAdapter(adepter);

만들어놓은 BaseAdepter로 만든 Adepter 클래스를 인스턴스 하고 listview의 어댑터로 사용합니다.
headterview & footerview를 사용하고 setAdapter 설정을 하지 않으면 오류가 발생합니다.
주의하십시오. 

package kr.co.ncj.myapplication; import android.content.ContentValues; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.view.LayoutInflater; import android.view.View; import android.widget.ListView; import java.util.ArrayList; public class MainActivity extends AppCompatActivity { private Adepter adepter = null; private ArrayList<ContentValues> values = new ArrayList<>(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ListView listView = findViewById(R.id.list_view); LayoutInflater inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE); View headterview = inflater.inflate(R.layout.headview, null); View footerview = inflater.inflate(R.layout.footview, null); listView.addHeaderView(headterview); listView.addFooterView(footerview); adepter = new Adepter(this, R.layout.listitem, values); listView.setAdapter(adepter); for (int i = 1; i <= 30; i++) { ContentValues item = new ContentValues(); item.put("item_name", "롱소드"); item.put("item_price", "300"); item.put("item_count", i); values.add(item); } adepter.notifyDataSetChanged(); } }

<Adepter 소스>
리스트 뷰는 화면으로 노출된 아이템을 만들고 스크롤 하면서 새롭게 나오는 아이템을 그때 그때마다 만들어줍니다.  
      if (convertView == null) 
리스트의 해당 아이템이 만들어져 있는지를 확인합니다. 
만들어진 게 있다면 굳이 새롭게 만들지 말고 수정을 통해 리스트 뷰를 보이는 것이 더욱 효율적이라고 할 수 있습니다. 
     convertView.setTag(holder);
        } else {
            holder = (Holder) convertView.getTag();
        } 

이 부분은 만들 때 태그들 달아놓고 만들어진 게 있다면 해당 태그를 이용하여 해당 아이템을 수정할 수 있도록 holder에 아이템 부들을 넣는 작업입니다. 

package kr.co.ncj.myapplication; import android.content.ContentValues; import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.TextView; import java.util.ArrayList; /** * Created by NCJ on 2018-02-11. */ public class Adepter extends BaseAdapter { Context context; int ResouesID; LayoutInflater inflater; ArrayList<ContentValues> values; public Adepter(Context context, int ResouesId, ArrayList<ContentValues> values) { this.context = context; this.ResouesID = ResouesId; this.values = values; inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); } @Override public int getCount() { return values.size(); } @Override public Object getItem(int position) { return values.get(position); } @Override public long getItemId(int position) { return position; } class Holder { TextView item_name; TextView item_price; TextView item_count; } @Override public View getView(int position, View convertView, ViewGroup parent) { ContentValues item = values.get(position); Holder holder = null; if (convertView == null) { holder = new Holder(); convertView = inflater.inflate(ResouesID, parent, false); holder.item_name = convertView.findViewById(R.id.item_name); holder.item_price = convertView.findViewById(R.id.item_price); holder.item_count = convertView.findViewById(R.id.item_count); convertView.setTag(holder); } else { holder = (Holder) convertView.getTag(); } holder.item_name.setText(item.getAsString("item_name")); holder.item_price.setText(item.getAsString("item_price")); holder.item_count.setText(item.getAsString("item_count")); return convertView; } }

앱 실행한 영상입니다. 

headview 와 footerview 추가시킨 커스텀 리스트 뷰 실행 영상입니다.


728x90
반응형
LIST