AdapterView_ListView&GridViwe&Spinner

소정·2023년 2월 16일
0

Android_with_Java

목록 보기
10/33
post-thumbnail

Adapter란?

뷰는 데이터를 보여주기 위한 액자이다 데이터가 적을땐 view를 각각 만들기 어렵지않지만 데이터가 많아지면 view를 각각 만들기 쉽지않다
그래서 대량의 데이터를 주면 그것을 받아 view를 알아서 만들어주는 친구 Adapter
Adapter : 서로 다른 규격을 맞춰주는 것! 들어온 데이터를 보고 알아서 필요한 뷰로 Activity엔 만들어 줌
Adapter = 대량의 데이터 + 모양설계 도면(xml)

액티비티는 변수를 직접 출력하지 못한다 그 문자를 보여줄 View를 통해 출력함
액티비티는 View를 하나밖에 못놓음 그래서 Layout을 놓아 여러개의 view를 보여준다


AdapterView란?


대량의 데이터를 화면에 보여주기 위해 사용하는
Adapter가 만든 뷰를 보여주는 view Group


AdapterView 생성 순서

① 대량의 데이터
② 어떤 모양으로 만들지 xml에 규격 정하기
③ Adapter 만들기
④ AdapterView 만들기


AdapterView 종류

1. ListView

데이터를 목록형태로 가져다 놓는 것, 위에서 아래로 쭉 널어 놓음

1) entries 사용하기

xml에서 ListView 만들때 android:entries 을 추가하면 Adapter를 자동으로 해줌
대신 xml에 등록된 정적인 String data만 쓸수 있다

<ListView
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   android:entries="@array/datas"/>
1. 대량이 데이터 준비

res폴더 values에 리소스파일 이름을 arrarys로 만들기


배열을 모아둔 R 장부 만들기 arrays 철자 틀리면 안됨

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <!-- String 배열 만들기 -->
    <string-array name="datas">
        <!--항목 생성-->
        <item>서울</item>
        <item>인천</item>
        <item>부산</item>
        <item>대전</item>
        <item>광주</item>
    </string-array>

</resources>

2. main.xml 리스트뷰 만들기

리스트 뷰 하위에 직접적으로 View를 만들면 안됨
entries가 Adapter의 역할을 대신한다
android:entries 추가 => String을 담고 있는 배열 리소스 파일만 올수있다

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="16dp"
    tools:context=".MainActivity">


    <ListView
        android:id="@+id/listview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:entries="@array/datas"/>
</RelativeLayout>

package com.bsj0420.ex21adapterlistview;

import androidx.appcompat.app.AppCompatActivity;

import android.content.res.Resources;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    ListView listView;

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

        listView = findViewById(R.id.listview);

        //리스트 뷰는 커다란 한 판이고 그 안에 item을 누르는 거니까 setOnItemClickListener
        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
                //adapterView 리스트 , view 누른 아이템, i 클릭한 아이템의 인덱스 번호, l 은 아이디로 참조
                //i와 l 같음

                //arrays.xml 에 datas라는 이름으로 작성된 문자열 배열을 참조하기
                // res폴더 안에 파일이 있기때문에 res 폴더의 관리자를 먼저 소환
                Resources res = getResources(); //this. 안쓴 이유 아웃터클래스의 getResources() 한것!
                String[] datas = res.getStringArray(R.array.datas);
                
                Toast.makeText(MainActivity.this, datas[i], Toast.LENGTH_SHORT).show();
            }
        });

    }
}



2) ArrayAdapter 사용

💡 ArrayAdapter
안드로이드가 adapter능력을 가진 클래스 만들어 넣은 것
대량의 데이터(String)를 적절한 뷰(TextView) 객체로 만들어주는 Adapter -> 대량의 데이터가 스트링 일때만 쓸수 있음

ArrayAdapter를 이용한 예제 근데 추가와 삭제 기능을 포함한

  1. 대량의 데이터 준비

  2. 데이터 보여줄 시안 만들기
    커스텀할 layout 생성
    res - layout - new layout

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="sample"
    android:textSize="18sp"
    android:textColor="@color/black"
    android:padding="16dp">

</TextView>
  1. ArrayApater 어답터 준비
  2. 리스트뷰 준비

<?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:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="16dp"
    tools:context=".MainActivity">

    <ListView
        android:id="@+id/list_view"
        android:layout_width="match_parent"
        android:layout_height="250dp"/>

    <!-- 새로운 데이터 추가 -->
    <EditText
        android:id="@+id/et"
        android:layout_marginTop="24dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="new Data"
        android:inputType="text"/>


    <Button
        android:id="@+id/btn"
        android:layout_marginTop="24dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="add"/>


</LinearLayout>

package com.bsj0420.ex21adapterlistview2;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.Toast;

import java.util.ArrayList;

public class MainActivity extends AppCompatActivity {

    // 1.대량의 데이터를 저장하는 리스트객체 만들기
    ArrayList<String> datas = new ArrayList<>();

    //3.어답터 준비
    //대량의 데이터(String)를 적절한 뷰(TextView) 객체로 만들어주는 Adapter 객체의 참조변수 생성
    //안드로이드가 adapter능력 가능 클래스 만들어 넣은 거 있음 ArrayApater
    // 대량의 데이터가 스트링 일때만 쓸수 있음
    ArrayAdapter adapter;

    //4. 리스트뷰 준비
    ListView listView;

    //
    EditText et;
    Button btn;

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

        //1-1대량의 데이터들 추가
        datas.add(new String("aaa"));
        datas.add(new String("bbb"));
        datas.add(new String("ccc"));


        //3-1 아답터 객체 생성
        // new ArrayAdapter(Context, 만든 시안 레이아웃, 대량의 데이타);
        adapter = new ArrayAdapter(this,R.layout.listview_item,datas);

        //4. 리스트뷰에 셋팅
        //리스트뷰한테 셋팅한다고 말해줘야함
        //TextView 한테 set 하듯 아답터뷰한데 set 아답터 해주는 것

        listView = findViewById(R.id.list_view);
        listView.setAdapter(adapter);

        //리스트 항목 클릭 했을 때 반응
        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
                Toast.makeText(MainActivity.this, datas.get(i), Toast.LENGTH_SHORT).show();
            }
        });

        //리스트 아이템을 looooong클릭 했을 때 반응 -> 데이타 삭제
        listView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
            @Override
            public boolean onItemLongClick(AdapterView<?> adapterView, View view, int i, long l) {

                //대량의 데이터에서 현재 클릭한 아이템의 위치 데이터 요소를 제거
                datas.remove(i);

                //아답터한테 알리기
                adapter.notifyDataSetChanged();
                
                return true;
                // 클릭은 눌렀다 떼는 행위임 
                // 클릭이 롱클릭을 끝냈을 때 발동됨
                // 여기 리턴값은 여기서 이벤트를 cunsum 할거니? 묻는것
                // 여기서 이벤트를 소진하겠다란 뜻의 true로 바꿔야 다음 동작(클릭)이 발동하지 않음
            }
        });



        ///////////
        //새로운 데이터 추가
        et = findViewById(R.id.et);
        btn = findViewById(R.id.btn);

        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //editText에 써있는 글씨는 얻어와서
                //view가 늘어나는 건 listView에 직접 넣는 것이 아니라 item을 추가 한다는 뜻
                //아답터뷰는 아답터가 만든것만 넣을 수 있다!!!!!!!
                String data = et.getText().toString();
                et.setText("");

                //대량의 데이터인 datas에 추가
                datas.add(data);
                
                //데이타가 변경된 상황을 아답터에게 *공지*해줘야함
                adapter.notifyDataSetChanged();

                //리스트 뷰의 스크롤 위치 지정
                listView.setSelection(datas.size()-1); // 젤 마지막 넘

            }
        });


    }
}



2. Spinner

콤보박스안에 넣는 것

1) entries 사용하기


main화면

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="16dp"
    tools:context=".MainActivity">

    <Spinner
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:entries="@array/city"/>

</RelativeLayout>

values - arrays.xml 생성

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string-array name="city">
        <item>서울</item>
        <item>인천</item>
        <item>대전</item>
        <item>강원도</item>
        <item>부산</item>
    </string-array>
</resources>



2) ArrayAdapter 사용


#### main ```android
<!-- 내 맘대로 만들기 -->
<!-- 스피너모드를 dialog로 만들면 제목줄인 prompt 만들 수 있는데
    얜 글자 하드코딩 싫어함 res에 string.xml에서 가져와야함
 -->
 
<Spinner
    android:id="@+id/spinner"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:spinnerMode="dropdown"
    android:prompt="@string/prompt"
    android:background="@drawable/bg_spinner"
    />
```

values - string.xml 에 추가

<resources>
    <string name="app_name">Ex23AdapterSpinner</string>
    <string name="prompt">도시명</string>
</resources>

🔨🔨 스피너 커스텀 하기

layout 폴더 - bg_spinner.xml 추가


화면에 보여지는 모양

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">

    <stroke android:color="@color/black" android:width="1dp"/>
    <corners android:radius="3dp"/>
    <solid android:color="@color/white"/>

</shape>

spinner drop down 커스텀

layout 폴더 - spinner_dropdown.xml 추가

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/black"
    android:textColor="@color/white"
    android:padding="16dp">

</TextView>

스피너 아이템의 모양 바꿔보기

layout 폴더 - spinner_dropdown.xml 추가

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:text="sample"
    android:padding="8dp"
    android:textColor="@color/black"
    android:textStyle="bold"
    android:ems="8"
    android:drawableRight="@drawable/baseline_arrow_drop_down_24">
</TextView>

백그라운드를 바꾸면 기존 스티너의 화살표 살아짐 화살표는 그림이었던 것이다,,, 그래서 아이콘을 속성값으로 직접 넣어줌
android:drawableRight="@drawable/baseline_arrow_drop_down_24
-> 아이콘 모양 오른쪽에 넣어주기 속성


.java

package com.bsj0420.ex23adapterspinner;

import androidx.appcompat.app.AppCompatActivity;

import android.content.res.Resources;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Spinner;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    Spinner spinner;
    ArrayAdapter adapter;

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

        spinner = findViewById(R.id.spinner);
        
        //adapter = new ArrayAdapter<>();
        //대량의 데이터가 자바에 있을때만 씀
        //
        //1. getResource로 리소스 안의 배열 가져오기
        
        //2. ArrayAdapter.createFromResource()로 바로 접근후 가져오기
        adapter= ArrayAdapter.createFromResource(this, R.array.city, R.layout.spinner_item);

        // 드롭다운되는 아이템들의 뷰모양을 다르게 주고 싶다면.
        adapter.setDropDownViewResource(R.layout.spinner_dropdown);

        spinner.setAdapter(adapter);

        //3. 스피너의 드롭다운 되는 뷰의 위치를 조정 가능
        spinner.setDropDownVerticalOffset(160);



        // 스피너의 item이 """선택 됐을 때"""" 반응하기
        // 아이템 셀렉은 시작하자마자 한번 가동
        spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
                //선택하고 닫았을 때

                String[] city = getResources().getStringArray(R.array.city);

                Toast.makeText(MainActivity.this, city[i], Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onNothingSelected(AdapterView<?> adapterView) {
                //선택 안하고 닫았을 때
            }
        });


    }
}



3. GridView

격자 무늬로 놓기
entries 사용 못함


<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="16dp"
    tools:context=".MainActivity">

    <GridView
    	android:id="@+id/gridview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:numColumns="3"/>

</RelativeLayout>

package com.bsj0420.ex24adaptergridview;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.GridView;
import android.widget.Toast;

import java.util.ArrayList;

public class MainActivity extends AppCompatActivity {

    ArrayList<String> datas = new ArrayList<>();
    GridView gridView;

    //문자열을 String으로 쉽게 바꿔주는 아잡터
    ArrayAdapter adapter;

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

        //1. 대량의 데이타 준비
        datas.add("aaa");
        datas.add("bbb");
        datas.add("ccc");
        datas.add("ddd");
        datas.add("eee");
        datas.add("fff");

        gridView = findViewById(R.id.gridview);

        adapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1,datas);
        gridView.setAdapter(adapter);

        gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
                Toast.makeText(MainActivity.this, datas.get(i), Toast.LENGTH_SHORT).show();
            }
        });

    }
}



★★ ItemView 커스텀 해보기★★

① 대량의 데이터가 단순하게 text 하나가 아니라 다른 자료형 데이터를 여러개 가지고 있는 class로 만들어서 가져오기
② Item 설계도면을 layout으로 만들어보자
③ 나만의 Adapter 만들기 (BaseAdapter 상속 받은)
-> 이 안에 4가지는 메소드는 꼭 만들어야함 추상메소드로 제공됨 이 네가지는 개발자가 사용하려 만든게 아니고 adapter한테 adapter view가 접근할 때 사용
④ AdapterView 만들기

순서를 생각하며 만들어보자

[1] 아답터 뷰만 배치

java폴더에 데이터 클래스 준비

package com.bsj0420.ex25aeapterlistviewcustom;

public class Item {
    
    String name; 
    String nation;
    
    int imgId; //이미지 리소스 아이디

    //객체를 생성 할떄 자동으로 실행하는 특별한 메소드
    // 생성자
    public Item(String name, String nation, int imgId){
        this.name = name;
        this.nation = nation;
        this.imgId = imgId;
    }
    
}

[2] 대량의 데이터 준비

원래는 데이터베이스에서 가져와야하는데 아직 데이터베이스를 연동하는 방법은 배우지 않았으므로 .java파일에 만들어 두기로 한다

package com.bsj0420.ex25aeapterlistviewcustom;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.Toast;

import java.util.ArrayList;

public class MainActivity extends AppCompatActivity {

    //대량의 데이터 준비
    ArrayList<Item> items = new ArrayList<>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        //데이터 추가
        items.add(new Item("전현무", "대한민국", R.drawable.flag_korea));
        items.add(new Item("기욤페트리", "캐나다", R.drawable.flag_canada));
        items.add(new Item("타일러", "미국", R.drawable.flag_usa));
        items.add(new Item("알베르토 몬디", "이탈리아", R.drawable.flag_italy));
        items.add(new Item("샘 오취리", "가나", R.drawable.flag_ghana));
        items.add(new Item("타쿠야", "일본", R.drawable.flag_japan));
        items.add(new Item("전현무", "대한민국", R.drawable.flag_korea));
        items.add(new Item("기욤페트리", "캐나다", R.drawable.flag_canada));
        items.add(new Item("타일러", "미국", R.drawable.flag_usa));
        items.add(new Item("알베르토 몬디", "이탈리아", R.drawable.flag_italy));
        items.add(new Item("샘 오취리", "가나", R.drawable.flag_ghana));
        items.add(new Item("타쿠야", "일본", R.drawable.flag_japan));

    }
}

[3] 시안 준비

list에 보여질 item이 layout로 여러개의 view를 가진 친구를 만들기
layout 폴더 - listview_item.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="wrap_content"
    android:padding="8dp">

    <ImageView
        android:id="@+id/iv"
        android:layout_width="80dp"
        android:layout_height="80dp"
        android:src="@drawable/flag_korea"
        />

    <TextView
        android:id="@+id/tv_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="name"
        android:layout_toRightOf="@+id/iv"
        android:textSize="20sp"
        android:textStyle="bold"
        android:textColor="#673AB7"
        android:layout_marginLeft="8dp"
        android:padding="8dp"/>


    <TextView
        android:id="@+id/tv_nation"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="nation"
        android:layout_alignLeft="@+id/tv_name"
        android:layout_below="@+id/tv_name"
        android:textColor="#000000"
        android:padding="8dp"/>

</RelativeLayout>

[4] 나만의 adapter 만들기

adapter에서 데이터와 내가 만든 item의 레이아웃 시안을 조합 해줘야함!!!

  1. 나만의 adapter를 만들때 0에서 부터 만들긴 어려우니 BaseAdapter를 상속(extends)받은 자바파일을 만든다

  2. ArrayList에 넣은 데이터를 가져오기 위해서 참조변수만들고 .java에있는 데이터를 이쪽으로 가져오기 위해서 Myadater를 new 할때 데이터를 생성자로 쭉쭉 받아줄 준비 한다

  3. getView 빼고 우선 작업

 	//아이템이 만들어질 총개수 리턴
    @Override
    public int getCount() {
        return items.size();
    } //리턴은 데이터의 사이즈 만큼

    //이 아답터가 가지고 있는 아이템 중 특정 것 하나 줘
    @Override
    public Object getItem(int i) {
        return items.get(i);
    }

    //index번호 대신 식별자 정해 두기위한 것
    @Override
    public long getItemId(int i) {
        return i;
    }
  1. 중요한 getView()작업!!!
  • 리스트뷰가 보여줄 아이템 '한개'의 view 객체를 생성하여 리턴헤주는 메소드
  • 겟뷰 한번에 아이템 뷰 한번~!

안에서 할 작업 순서
1) create view : xml모양(내가 정한 시안)으로 view 객체를 생성
내가 만든 뷰 모양으로 객체 생성 하기 위해서는 context 능력이 필요하다

Myadapter 파일에는 context 능력을 상속받은 Activity가 없으니까 데이터를 받아올때 메인 액티비티를 생성자로 같이 받아온다!

package com.bsj0420.ex25aeapterlistviewcustom;

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 Myadapter extends BaseAdapter {

    //운영체제를 받을 참조변수
    Context context;

    //ArrayList에 넣은 데이터를 가져오기 위해서 참조변수만들기
    ArrayList<Item> items;
    
    //생성자에 Context 추가 하여 받기!!
    public Myadapter(Context context, ArrayList<Item> items){
        this.context = context;
        this.items = items;
    }

    //리스트뷰가 보여줄 아이템 '한개'의 view 객체를 생성하여 리턴헤주는 메소드
    //겟뷰 한번에 뷰 한번~!
    //xml에 만들어놓은 설계보고 inflater 함
    @Override
    public View getView(int i, View view, ViewGroup viewGroup) {
        //1. create view : xml모양(내가 정한 시안)으로 view 객체를 생성
        // xml을 읽어서 view객체로 만들어주는 객체를 운영체제로부터 소환 "LayoutInflater"
        // Context 의 능력중 LayoutInflater능력 쓰자
        //원래 운영체제거 쓰는 법 
        //LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        //LayoutInflater는 자주써서 따로 또 만드는 법 생김

        LayoutInflater inflater = LayoutInflater.from(context);
        View itemView= inflater.inflate(R.layout.listview_item, null); //root는 null로 놔야함

        
        LayoutInflater inflater = LayoutInflater.from(context);
        ImageView iv = inflater.inflate(R.layout.listview_item, null); //root는 null로
            
        
        //2. bind view : 생성된 view 객체안에 정보들을 설정(연결)
       

        return iv; //리스트 뷰가 이 리턴된 뷰를 화면에 목록 형태로 추가해줌
    }

}

2) bind view : 생성된 view 객체안에 정보들을 설정(연결)

//운영체제를 받을 참조변수
    Context context;

    //ArrayList에 넣은 데이터를 가져오기 위해서 참조변수만들기
    ArrayList<Item> items;
    
    //생성자에 Context 추가 하여 받기!!
    public Myadapter(Context context, ArrayList<Item> items){
        this.context = context;
        this.items = items;
    }

    //리스트뷰가 보여줄 아이템 '한개'의 view 객체를 생성하여 리턴헤주는 메소드
    //겟뷰 한번에 뷰 한번~!
    //xml에 만들어놓은 설계보고 inflater 함
    @Override
    public View getView(int i, View view, ViewGroup viewGroup) {
        //1. create view : xml모양(내가 정한 시안)으로 view 객체를 생성
        // xml을 읽어서 view객체로 만들어주는 객체를 운영체제로부터 소환 "LayoutInflater"
        // Context 의 능력중 LayoutInflater능력 쓰자
        //원래 운영체제거 쓰는 법 
        //LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        //LayoutInflater는 자주써서 따로 또 만드는 법 생김

        LayoutInflater inflater = LayoutInflater.from(context);
        View itemView= inflater.inflate(R.layout.listview_item, null); //root는 null로 놔야함

        
        LayoutInflater inflater = LayoutInflater.from(context);
        ImageView iv = inflater.inflate(R.layout.listview_item, null); //root는 null로
            
        
        //2. bind view : 생성된 view 객체안에 정보들을 설정(연결)
       //값을 뷰와 연결하는 일
        //이 메소드의 첫번째 파라미터 i = 현재 만들어야 할 번째 인덱스번호

        //현재번째 데이터(item 객체) 가져오기
        Item item = items.get(i);
        
        //item view 안에 있는 자식뷰들을 참조하기
        ImageView iv = view.findViewById(R.id.iv);
        TextView tvName = view.findViewById(R.id.tv_name);
        TextView tvNaion = view.findViewById(R.id.tv_nation);


        //각 뷰들에 현재번째 데이터를 연결
        tvName.setText(item.name);
        tvNaion.setText(item.nation);
        iv.setImageResource(item.imgId);

        return iv; //리스트 뷰가 이 리턴된 뷰를 화면에 목록 형태로 추가해줌
    }

}
  1. view를 무한히 만드면 서버가 난리나니까 재활용하도록 수정
//운영체제를 받을 참조변수
    Context context;

    //ArrayList에 넣은 데이터를 가져오기 위해서 참조변수만들기
    ArrayList<Item> items;
    
    //생성자에 Context 추가 하여 받기!!
    public Myadapter(Context context, ArrayList<Item> items){
        this.context = context;
        this.items = items;
    }

    //리스트뷰가 보여줄 아이템 '한개'의 view 객체를 생성하여 리턴헤주는 메소드
    //겟뷰 한번에 뷰 한번~!
    //xml에 만들어놓은 설계보고 inflater 함
    @Override
    public View getView(int i, View view, ViewGroup viewGroup) {
        //1. create view : xml모양(내가 정한 시안)으로 view 객체를 생성
        // xml을 읽어서 view객체로 만들어주는 객체를 운영체제로부터 소환 "LayoutInflater"
        // Context 의 능력중
        //원래 운영체제거 쓰는 법 
        //LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        //LayoutInflater는 자주써서 따로 또 만드는 법 생김

//        LayoutInflater inflater = LayoutInflater.from(context);
//        View itemView= inflater.inflate(R.layout.listview_item, null); //root는 null로 놔야함

        //inflate 는 new 를 하는것 이렇게 위처럼 하면 비효율적

        //재활용 하도록 만든다
        //혹시 재활용할 view가 없는가? - 이 메소드의 두번째 파라미터 view
        if(view == null) { //view가 null이라는 건 더이상 스크롤 할 view가 없다는 것
            LayoutInflater inflater = LayoutInflater.from(context);
            view= inflater.inflate(R.layout.listview_item, null); //root는 null로
            //이 뷰는 listview_item에 RelativeLayout를 말하는 것!!
        }
        
        //2. bind view : 생성된 view 객체안에 정보들을 설정(연결)
        //값을 뷰와 연결하는 일
        //이 메소드의 첫번째 파라미터 i = 현재 만들어야 할 번째 인덱스번호

        //현재번째 데이터(item 객체) 가져오기
        Item item = items.get(i);
        
        //item view 안에 있는 자식뷰들을 참조하기
        ImageView iv = view.findViewById(R.id.iv);
        TextView tvName = view.findViewById(R.id.tv_name);
        TextView tvNaion = view.findViewById(R.id.tv_nation);


        //각 뷰들에 현재번째 데이터를 연결
        tvName.setText(item.name);
        tvNaion.setText(item.nation);
        iv.setImageResource(item.imgId);

        return view; //리스트 뷰가 이 리턴된 뷰를 화면에 목록 형태로 추가해줌
    }

}

📢 1~5 과정 합친 총 코드

package com.bsj0420.ex25aeapterlistviewcustom;

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 Myadapter extends BaseAdapter {

    //운영체제를 받을 참조변수
    Context context;

    //ArrayList에 넣은 데이터를 가져오기 위해서 참조변수만들기
    ArrayList<Item> items;
    
    //생성자 만들기
    public Myadapter(Context context, ArrayList<Item> items){
        this.context = context;
        this.items = items;
    }

    //아이템이 만들어질 총개수 리턴
    @Override
    public int getCount() {
        return items.size();
    } //리턴은 데이터의 사이즈 만큼

    //이 아답터가 가지고 있는 아이템 중 특정 것 하나 줘
    @Override
    public Object getItem(int i) {
        return items.get(i);
    }

    //index번호 대신 식별자 정해 두기위한 것
    @Override
    public long getItemId(int i) {
        return i;
    }

    //리스트뷰가 보여줄 아이템 '한개'의 view 객체를 생성하여 리턴헤주는 메소드
    //겟뷰 한번에 뷰 한번~!
    //xml에 만들어놓은 설계보고 inflater 함
    @Override
    public View getView(int i, View view, ViewGroup viewGroup) {
        //1. create view : xml모양(내가 정한 시안)으로 view 객체를 생성
        // xml을 읽어서 view객체로 만들어주는 객체를 운영체제로부터 소환 "LayoutInflater"
        // Context 의 능력중
        //원래 운영체제거 쓰는 법 
        //LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        //LayoutInflater는 자주써서 따로 또 만드는 법 생김

//        LayoutInflater inflater = LayoutInflater.from(context);
//        View itemView= inflater.inflate(R.layout.listview_item, null); //root는 null로 놔야함

        //inflate 는 new 를 하는것 이렇게 위처럼 하면 비효율적

        //재활용 하도록 만든다
        //혹시 재활용할 view가 없는가? - 이 메소드의 두번째 파라미터 view
        if(view == null) { //view가 null이라는 건 더이상 스크롤 할 view가 없다는 것
            LayoutInflater inflater = LayoutInflater.from(context);
            view= inflater.inflate(R.layout.listview_item, null); //root는 null로
            //이 뷰는 listview_item에 RelativeLayout를 말하는 것!!
        }
        
        //2. bind view : 생성된 view 객체안에 정보들을 설정(연결)
        //값을 뷰와 연결하는 일
        //이 메소드의 첫번째 파라미터 i = 현재 만들어야 할 번째 인덱스번호

        //현재번째 데이터(item 객체) 가져오기
        Item item = items.get(i);
        
        //item view 안에 있는 자식뷰들을 참조하기
        ImageView iv = view.findViewById(R.id.iv);
        TextView tvName = view.findViewById(R.id.tv_name);
        TextView tvNaion = view.findViewById(R.id.tv_nation);


        //각 뷰들에 현재번째 데이터를 연결
        tvName.setText(item.name);
        tvNaion.setText(item.nation);
        iv.setImageResource(item.imgId);

        return view; //리스트 뷰가 이 리턴된 뷰를 화면에 목록 형태로 추가해줌
    }

}

[5] set adapter

.java에서 내가 만든 어답터로 set adapter하여 액티비티 화면에 보여주기!!

메인 화면

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="16dp"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/tv_title"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="비정상회담 정상 리스트"
        android:textSize="24sp"
        android:textColor="@color/black"
        android:gravity="center"
        android:padding="16dp"/>

    <ListView
        android:id="@+id/list_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_below="@+id/tv_title"

        />

</RelativeLayout>

자바화면

package com.bsj0420.ex25aeapterlistviewcustom;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.Toast;

import java.util.ArrayList;

public class MainActivity extends AppCompatActivity {

    //대량의 데이터 준비
    ArrayList<Item> items = new ArrayList<>();

    ListView listView;

    Myadapter myadapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        //데이터 추가
        items.add(new Item("전현무", "대한민국", R.drawable.flag_korea));
        items.add(new Item("기욤페트리", "캐나다", R.drawable.flag_canada));
        items.add(new Item("타일러", "미국", R.drawable.flag_usa));
        items.add(new Item("알베르토 몬디", "이탈리아", R.drawable.flag_italy));
        items.add(new Item("샘 오취리", "가나", R.drawable.flag_ghana));
        items.add(new Item("타쿠야", "일본", R.drawable.flag_japan));
        items.add(new Item("전현무", "대한민국", R.drawable.flag_korea));
        items.add(new Item("기욤페트리", "캐나다", R.drawable.flag_canada));
        items.add(new Item("타일러", "미국", R.drawable.flag_usa));
        items.add(new Item("알베르토 몬디", "이탈리아", R.drawable.flag_italy));
        items.add(new Item("샘 오취리", "가나", R.drawable.flag_ghana));
        items.add(new Item("타쿠야", "일본", R.drawable.flag_japan));

        //[4] 리스트 뷰에 붙이기~!
        //아답터객체를 생성하여 리스트뷰에 설정
        listView = findViewById(R.id.list_view);
        myadapter = new Myadapter(this,items);

        listView.setAdapter(myadapter);

        //리스트뷰의 아이템을 클릭했을 때 반응하기
        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
                Item item = items.get(i);
                Toast.makeText(MainActivity.this, item.name + ", " + item.nation , Toast.LENGTH_SHORT).show();
            }
        });

    }
}
profile
보조기억장치

0개의 댓글