한 걸음 두 걸음

android studio ] listview 등 adapter 연결시켜 사용하는 방법 정리 본문

FrontEnd/Android

android studio ] listview 등 adapter 연결시켜 사용하는 방법 정리

언제나 변함없이 2019. 2. 21. 17:01
반응형

리스트뷰 위치 설정

안드로이드스튜디오에서 activity_main.xml에 레이아웃 설정하고 listView 넣어서 위치 잡아줌.

1. 리스트뷰 껍데기 넣어줌

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

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <Button
            android:id="@+id/button3"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Button" />
    </LinearLayout>

    <ListView
        android:id="@+id/listView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_alignParentStart="true"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:layout_marginStart="0dp"
        android:layout_marginLeft="0dp"
        android:layout_marginTop="41dp" />

</RelativeLayout>

2. 메인액티비티 수정

일단 만들어놓은 리스트뷰를 가져와주고

public class MainActivity extends AppCompatActivity {

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

        ListView listView = (ListView)findViewById(R.id.listView);

    }

어뎁터도 하나 클래스로 만들어주자. 이 클래스는 BaseAdapter를 상속받아 사용할거야

 class SingerAdapter extends BaseAdapter{
        @Override
        public int getCount() {
            return 0;
        }

        @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) {
            return null;
        }
    }

여기서 4개의 함수는 BaseAdapter를 사용하기위해 반드시 필요한 4개의 implements야
오버라이드해줬어.

이제 어뎁터가 데이터를 관리해야하니까 ArrayList<String>를 하나 만들어주자.

근데 이 데이터는 String 하나밖에 데이터를 못받아. 즉 걸그룹에 대한 것이라면 걸그룹 이름 하나 정도만 받을 수 있는 거라는거야. 그래서 나는 다양한 데이터셋을 가진
자바 파일을 만들어주기로했어

이렇게 SinerItem이라는 이름으로 java 파일을 하나 만들어주고 안에
아래와 같이 name과 mobile을 갖는 클래스로 만들어줘.

package com.gkskfhdlstmapk.hanpinetree.mylistview;

public class SingerItem {

    String name;
    String moblie;

    public SingerItem(String name, String moblie) {
        this.name = name;
        this.moblie = moblie;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getMoblie() {
        return moblie;
    }

    public void setMoblie(String moblie) {
        this.moblie = moblie;
    }

    @Override
    public String toString() {
        return "SingerItem{" +
                "name='" + name + '\'' +
                ", moblie='" + moblie + '\'' +
                '}';
    }
}

여기는 getter / setter 등과 toString 생성자 등 기본적으로 필요한 것들만 넣어주었어.

그리고 이제 ArrayList를 만들 때 String이 아닌 SingerItem를


        ArrayList<SingerItem> items = new ArrayList<SingerItem>();

와 같이 넣어서 사용하지.

이제 implement로 넣어주었던 4개의 함수 수정해주고,


        //너네 어뎁터 안에 몇 개의 아이템이 있니? 아이템갯수 반환함수
        @Override
        public int getCount() {
            return items.size(); //위의 ArrayList내부의 아이템이 몇 개나 들었는지 알려주게됨
        }

        @Override
        public Object getItem(int position) {
            return items.get(position); //position번째의 아이템을 얻을거야.
        }

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


        //이게 중요! 어뎁터가 데이터를 관리하기 때문에 화면에 보여질 각각의 화면에 보일 뷰도 만들어달라는 것
        //각각의 아이템 데이터 뷰(레이아웃)을 만들어주어 객체를 만든다음에 데이터를 넣고 리턴해줄 것임
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            return null;
        }

3. getView에 붙여줄 레이아웃을 단독으로 새로 만들어주자


를 만들어서,

이와 같이 만들어주었음. 아래는 코드임~ 이 레이아웃의 최상위는 Linear인데 이 레이아웃의 Height를 wrap_content로 정해두어야 화면 전체로 안잡아먹겠지.

<?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="wrap_content"
    android:orientation="horizontal">

    <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="10dp"
        android:orientation="vertical">
        <TextView
            android:id="@+id/tetView1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="이름"
            android:textSize="30dp"
            android:textColor="@color/colorPrimaryDark"/>

        <TextView
            android:id="@+id/tetView2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="8dp"
            android:text="전화번호"
            android:textSize="24dp"
            android:textColor="@android:color/holo_orange_dark"/>
    </LinearLayout>

</LinearLayout>

4. 자바소스파일과 매칭시켜봅시다.

새로운 자바 단독 소스파일을 하나 더 만들어줄거에요.

여기서 이 자바파일은 LinearLayout을 상속받음으로 Singer_Item 뷰에서 썼던 최상위 레이아웃인 LinearLayout을 인플레이션한 다음에 여기에 그대로 붙여 사용할 수 있게 됩니다.

이제 만들어진 창에 override로 Constructor 2개 해줌

뷰를 생성할 때는 우리가 반드시 두 개의 필수 생성자가 필요하니 추가해줍니다.

package com.gkskfhdlstmapk.hanpinetree.mylistview;

import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.widget.LinearLayout;
import android.widget.TextView;

import org.w3c.dom.Text;

public class SingerItemView extends LinearLayout {
    TextView textView1;
    TextView textView2;

    public SingerItemView(Context context) {
        super(context);
        init(context);
    }

    public SingerItemView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }

    private void init(Context context){
        //만들어놓은 xml파일을 객체화해와서 붙이는 역할을 하면 되겠죠
        //서비스에서 제공하는 LAYOUT_INFLATER_SERVICE를 활용합니다.
        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        //객체화하기위해서 인플레이션 서비스를 활용함
        inflater.inflate(R.layout.singer_item,this,true);
        //이 소스가 Linear를 상속받았으므로 siger_item을 바로 this에 붙일 수 있음

        textView1 = findViewById(R.id.tetView1);
        textView2 = findViewById(R.id.tetView2);

    }

    //SigerItemView에 데이터를 설정할 수 있게끔 setter함수를 설정해줍시다.

    //먼저 걸그룸의 이름
    public  void setName(String name){
        textView1.setText(name);

    }
    // 다음 걸그룹의 연락처

    public void setMobile(String mobile){
        textView2.setText(mobile);
    }

}

만들어놓은 뷰를 객체화시켜서 가져온 뒤 데이터를 설정해주는 함수를 만들어주었습니다.

이제 MainActivity로 가서 getView를 마저 편집해보자면

 @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            SingerItemView view = new SingerItemView(getApplicationContext());
            //어떤 뷰든 안드로이드에서는 Context객체를 받게 되어있으므로 getApplicationCotext로 넣어줍니다.

            //이제 이 뷰를 반환해주면 되는데 이 뷰가 몇 번째 뷰를 달라는 것인지 position값이 넘어오므로
            SingerItem item  = items.get(position); //SigerItem은 참고로 Dataset임. 따로 기본적인것만 구현해놓음
            //이 position값을 갖는 아이템의 SigerItem객체를 새로 만들어준 뒤
            view.setName(item.getName());
            view.setMobile(item.getMoblie());
            //이렇게 해당 position에 맞는 값으로 설정해줍니다.

            //그렇게 설정을 잘 해놓은 다음에 view를 반환해야 데이터값이 들어간 레이아웃이 반환될거에요~
            return view;
        }

가 되며,

ArrayList<SingerItem> items = new ArrayList<SingerItem>();
        //걸그룹의 이름, 전화번호 등등이 필요할텐데 이거 하나로는 부족하니까
        //데이터형을 다양하게 담고있는 java파일을 하나 더 만들어줄거에요

        //!! 그런데 ArrayList에 데이터를 넣는 기능이 지금 없으므로 함수를 하나 더 만들어줄게요
        public void addItem(SingerItem item){
            items.add(item);
        }

위처럼 ArrayList의 dataset인 SingerItem을 넣는 함수가 없으므로
addItem함수를 하나 더 만들어줍니다.

이제 Main코드에서

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

            ListView listView = (ListView)findViewById(R.id.listView);


            SingerAdapter adapter = new SingerAdapter();
            //adapter에 data값을 줘봅시다.
            adapter.addItem(new SingerItem("소녀시대","010-4729-9200"));
            adapter.addItem(new SingerItem("소녀시대","010-4729-9200"));


            listView.setAdapter(adapter);
            //이렇게해서 listView껍데기가 어뎁터에게 몇 개의 데이터가 있고 어떤 뷰를 집어넣어야하는지
            //물어보면 어뎁터가 아래의 코드를 통해 만들어놓은 정보를 종합하여 전달함
        }

로 데이터값을 설정해주고, (imageview값은 따로 지정해주지 않았으므로 미리 넣어둔 값으로 설정됩니다.)
adapter를 listView에 붙여주면 구현 완성~


전체코드

Main.java

  package com.gkskfhdlstmapk.hanpinetree.mylistview;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ListView;

import java.util.ArrayList;

public class MainActivity extends AppCompatActivity {

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

            ListView listView = (ListView)findViewById(R.id.listView);


            SingerAdapter adapter = new SingerAdapter();
            //adapter에 data값을 줘봅시다.
            adapter.addItem(new SingerItem("소녀시대","010-4729-9200"));
            adapter.addItem(new SingerItem("소녀시대","010-4729-9200"));


            listView.setAdapter(adapter);
            //이렇게해서 listView껍데기가 어뎁터에게 몇 개의 데이터가 있고 어떤 뷰를 집어넣어야하는지
            //물어보면 어뎁터가 아래의 코드를 통해 만들어놓은 정보를 종합하여 전달함
        }
    //어뎁터를 사용해서 코드를 간단하게 만들 수 있음, 이미지 및 텍스트를 나중에 커스터마이징 사용해서 사용하기 때문에
    //그래서 처음부터 리스트뷰에 들어갈 아이템의 모양을 정해서 넣어주는 구조를 만드는 것이 좋아요
    // 그러니 각각의 아이템을 위한 뷰를 만들어서 각각 넣어줄 거에요

    class SingerAdapter extends BaseAdapter{
            //어뎁터가 데이터를 관리하며 데이터를 넣었다가 뺄 수도 있으므로 ArrayList를 활용하여 구현해보자.

        ArrayList<SingerItem> items = new ArrayList<SingerItem>();
        //걸그룹의 이름, 전화번호 등등이 필요할텐데 이거 하나로는 부족하니까
        //데이터형을 다양하게 담고있는 java파일을 하나 더 만들어줄거에요

        //!! 그런데 ArrayList에 데이터를 넣는 기능이 지금 없으므로 함수를 하나 더 만들어줄게요
        public void addItem(SingerItem item){
            items.add(item);
        }

        //너네 어뎁터 안에 몇 개의 아이템이 있니? 아이템갯수 반환함수
        @Override
        public int getCount() {
            return items.size(); //위의 ArrayList내부의 아이템이 몇 개나 들었는지 알려주게됨
        }

        @Override
        public Object getItem(int position) {
            return items.get(position); //position번째의 아이템을 얻을거야.
        }

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


        //이게 중요! 어뎁터가 데이터를 관리하기 때문에 화면에 보여질 각각의 화면에 보일 뷰도 만들어달라는 것
        //각각의 아이템 데이터 뷰(레이아웃)을 만들어주어 객체를 만든다음에 데이터를 넣고 리턴해줄 것임
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            SingerItemView view = new SingerItemView(getApplicationContext());
            //어떤 뷰든 안드로이드에서는 Context객체를 받게 되어있으므로 getApplicationCotext로 넣어줍니다.

            //이제 이 뷰를 반환해주면 되는데 이 뷰가 몇 번째 뷰를 달라는 것인지 position값이 넘어오므로
            SingerItem item  = items.get(position); //SigerItem은 참고로 Dataset임. 따로 기본적인것만 구현해놓음
            //이 position값을 갖는 아이템의 SigerItem객체를 새로 만들어준 뒤
            view.setName(item.getName());
            view.setMobile(item.getMoblie());
            //이렇게 해당 position에 맞는 값으로 설정해줍니다.

            //그렇게 설정을 잘 해놓은 다음에 view를 반환해야 데이터값이 들어간 레이아웃이 반환될거에요~
            return view;
        }
    }
}

singerItem.java

  package com.gkskfhdlstmapk.hanpinetree.mylistview;

public class SingerItem {

    String name;
    String moblie;

    public SingerItem(String name, String moblie) {
        this.name = name;
        this.moblie = moblie;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getMoblie() {
        return moblie;
    }

    public void setMoblie(String moblie) {
        this.moblie = moblie;
    }

    @Override
    public String toString() {
        return "SingerItem{" +
                "name='" + name + '\'' +
                ", moblie='" + moblie + '\'' +
                '}';
    }
}

SingerItemView.java

package com.gkskfhdlstmapk.hanpinetree.day24_1_mylist;

import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

import org.w3c.dom.Text;

public class SingerItemView extends LinearLayout {

    TextView textView;
    TextView textView2;
    ImageView imageView;
    //뷰를 생성할 때는 생성자가 두 개 이상이어야한다.
    public SingerItemView(Context context) {
        super(context);

        init(context);
    }

    public SingerItemView(Context context, AttributeSet attrs) {
        super(context, attrs);

        init(context);
    }

    private  void init(Context context){
        //만들어놓은 singer_item xml파일을 인플레이터시켜서 객체화한다음 SingerItemView에 붙여줄 수 있겠죠
        LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        //레이아웃 인플레이터ㅓ로 시스템서비스를 참조할 수 있음
        //시스템서비스는 화면에 보이지 않아도 돌아가고있음- 레아웃인플레이터를 이용하겠다.
        inflater.inflate(R.layout.singer_item,this,true);

        //이렇게 객체화시켜준 다음부터는 findViewById로 가져와 참조할 수 있음
         textView = (TextView)findViewById(R.id.textView);
         textView2 = (TextView)findViewById(R.id.textView2);
         imageView = (ImageView) findViewById(R.id.imageView);
    }

    //데이터를 설정할 수 있게 만든 함수
    public  void setName(String name){
        textView.setText(name);
        //걸그룹의 이름을 설정
    }
    public void setMobile(String mobile){
        textView2.setText(mobile);
    }

    public void setImageView(int resId){
        imageView.setImageResource(resId);
    }
}

main.xml

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

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <Button
            android:id="@+id/button3"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Button" />
    </LinearLayout>

    <ListView
        android:id="@+id/listView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_alignParentStart="true"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:layout_marginStart="0dp"
        android:layout_marginLeft="0dp"
        android:layout_marginTop="41dp" />

</RelativeLayout>

singer_Item.xml

  <?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="wrap_content"
    android:orientation="horizontal">

    <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="10dp"
        android:orientation="vertical">
        <TextView
            android:id="@+id/tetView1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="이름"
            android:textSize="30dp"
            android:textColor="@color/colorPrimaryDark"/>

        <TextView
            android:id="@+id/tetView2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="8dp"
            android:text="전화번호"
            android:textSize="24dp"
            android:textColor="@android:color/holo_orange_dark"/>
    </LinearLayout>

</LinearLayout>


참고
Java의 ArrayList
URL : https://slowlywalk1993.tistory.com/entry/Java-ArrayList%EB%9E%80

반응형