앱 만들기/안드로이드 study

커스텀 리스트 뷰 만들기(직접 리스트 뷰 설계하기)

나도처음이야 2021. 4. 21.

이번 시간에는 직접 리스트뷰를 개발자가 만들어서 사용해 보겠습니다.

이를 커스텀 리스트뷰 라고 부르며, 개발자가 원하는 대로 복잡한 UI 의 리스트뷰 등도 얼마든지 만들 수 있습니다.

기본 리스트뷰는 지난 포스팅을 참고해주세요.

결과 화면을 먼저 보도록 하겠습니다.

 

위와 같이 국기와 더불어 국가명 수도명을 표시해보았습니다.

그럼 시작해보겠습니다.

 

1. 커스텀 레이아웃 만들기.

# 자신이 만들고 싶은 리스트뷰 한줄을 표현하는 화면입니다.

   저는 오른쪽 화면처럼 화면을 구성해 보았습니다. 여러분이 원하시는 화면을 구성하면 됩니다.

   여기서 구성한 화면이 바로 리스트뷰 한줄의 기본 레이아웃이 됩니다.

 

2. 기본 레이아웃 만들기.

# 리스트 뷰를 만듭니다.

  우리가 생성한 리스트 뷰는 코드상에서 실제 연결을 하게됩니다.

  하지만 tools:listitem ="내가 만든 레이아웃" 을 하기 처럼 적어주면 레이아웃 미리보기에 리스트 뷰의 완성된 모습을 볼 수 있습니다. 

 

3. 소스 작업 - MainActivity 만들기

# 앱을 실행하는 MainActivity 에서는 listView 를 자신이 만든 리스트뷰 아탑터와 연결하는 작업 과

   리스트 데이터를 준비하는 과정을 만들어 봅니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
public class MainActivity extends AppCompatActivity {
 
    static final int listCount = 15;
    ListView listView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
       
        //사용자 아답터뷰 데이터 준비
//각자 원하는 데이터를 관리하는 클래스를 만들어 주시고
//해당 클래스를 ArrayList 로 관리해줍니다.
        ArrayList<Flag> listData = new ArrayList<>();
        // 리스트에 들어갈 데이터를 만드는 과정.
        for(int i=0 ; i < listCount ; i++)
            listData.add(new"나라" + i , "수도" + i, i));
 
        //개발자가 만든 아답터를 연결하기 위해서
         MyListAdapter myListAdapter = new MyListAdapter(listData);
 
        listView = (ListView)findViewById(R.id.listView);
        listView.setAdapter(myListAdapter);
 
        //리스트 뷰 클릭시 동작하도록
        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                Log.i("info" , "### onItemClick");
                Toast.makeText(getApplicationContext(), position + " 번째 선택! ", Toast.LENGTH_LONG).show();
            }
        });
    }
}
cs

 

3. 소스작업 - Flag 클래스 만들기. ( 개발자가 원하는 데이터를 저장하는 클래스)

# 필자는 국기 이미지, 국가 및 수도 이름 총 3가지 데이터를 저장하고 있습니다.

   개발자가 원하는 데이터를 저장하는 포맷을 제작하면 됩니다. 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
// 국기 정보.
public class Flag {
 
    int[] flagImage={
            R.drawable.flag_of_afghanistan ,
            R.drawable.flag_of_albania,
            R.drawable.flag_of_algeria,
            R.drawable.flag_of_andorra,
            R.drawable.flag_of_angola,
 
            R.drawable.flag_of_antigua_and_barbuda,
            R.drawable.flag_of_argentina,
            R.drawable.flag_of_armenia,
            R.drawable.flag_of_australia,
            R.drawable.flag_of_austria,
 
            R.drawable.flag_of_azerbaijan,
            R.drawable.flag_of_bahamas,
            R.drawable.flag_of_bahrain,
            R.drawable.flag_of_bangladesh,
            R.drawable.flag_of_barbados,
    };
 
    Flag(String _country, String _capital, int _flagindex){
        country = _country;
        capital = _capital;
        flagIndex = _flagindex;
    }
    // 데이터 은닉화.
    private String country; //국가
    private String capital; //수도
    private int flagIndex; //국기 이미지 인덱스
 
    public int getFlagImage(){
        return flagImage[flagIndex];
    }
    public String getCountry() {
        return country;
    }
    public void setCountry(String _country) {
        this.country = _country;
    }
    public String getCapital() {
        return capital;
    }
    public void setCapital(String _capital) {
        this.capital = _capital;
    }
}
 
cs

 

4. 소스작업 - 커스텀 어댑터 만들기

 # 가장 중요한 커스텀 어댑터 부분입니다. 

   커스텀 어댑터를 만들기 위해서는 BaseAdapter 를 상속받습니다. 

   다른 함수들은 기본 리스튜와 동일합니다. 

   주요한 포인트는 바로,

   getView() 함수 입니다. 이 함수에서 리스트 한줄을 그려주는 역할을 합니다.

   바로, 우리가 만든 list 한줄 레이아웃을 불러들여(인플레이트) 화면 구성을 합니다.  

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
public class MyListAdapter extends BaseAdapter {
 
    private final List<Flag> mListData;
    public MyListAdapter(List listdata){
        // 리스트를 받는다.
        mListData = listdata;
    }
    @Override
    //아이템 개수
    public int getCount() {
        //리스트의 사이즈로 아이템 개수를 설정함.
        return mListData.size();
    }
 
    @Override
    // 포지션 번째의 아이템
    public Object getItem(int position) {
        //리스트의 포지션번째의 가져오기.
        return mListData.get(position);
    }
 
    @Override
    // 포지션 번째의 아이디 (리스트 뷰에서는 인덱스가 된다)
    public long getItemId(int position) {
        return position;
    }
 
    @Override
    // 포지션 번째 아이템뷰 만들기. 가장 중요한 함수
    // 각 아이템이 화면에 보일때마다 호출되는 함수.
    public View getView(int position, View convertView, ViewGroup parent) {

//레이아웃 인플레이트를 통해서 우리가 만든 레이아웃 View 를 불러온다.
        convertView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.item_list,parent,false);
 
        // 국기이미지, 국기, 수도
        ImageView flag = (ImageView)convertView.findViewById(R.id.flag_image);
        TextView country = (TextView)convertView.findViewById(R.id.country);
        TextView capital = (TextView)convertView.findViewById(R.id.capital);
        // 현재 position 의 국가 데이터
        Flag flagData = mListData.get(position);
        country.setText(flagData.getCountry());
        capital.setText(flagData.getCapital());
        flag.setImageResource(flagData.getFlagImage());
        return convertView;
       }
}
 
cs

 

크게 위 4가지 사항을 구현하면,

여러분이 원하시는 커스텀 어댑터 뷰를 손쉽게 제작 할 수 있습니다.

getView 에서 인플레이트 하여 데이터를 세팅하는 연습을 많이 해보는 것이 중요합니다.

감사합니다 :)

반응형

댓글