[안드로이드스튜디오-Kotlin]

[안드로이드 스튜디오] ListView

김채연채연 2022. 10. 3. 16:15

어려워서 강의를 여러번 본 파트. 계속해서 공부하면 좋을듯 싶다

xml에 들어간 후 팔레트에 listview 검색 -> Cpmponent tree 에 드래그하여 추가한다.

아마 이름이 dynamic 으로 바뀔것이다. 이것의 id 는 listView

후에 layout_width, layout_height 를 각각 0dp로 설정하여 세팅한다. (Constraint Eidget 설정 포함)

KT로 넘어간다.

package com.example.listvieskt

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.os.PersistableBundle
import android.widget.Adapter
import android.widget.ArrayAdapter
import com.google.firebase.firestore.auth.User
import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.android.synthetic.main.list_item_user.*


class MainActivity : AppCompatActivity() {

        override fun onCreate(savedInstanceState: Bundle?) { //엑티비티의 실행시작지점
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_main)

        val item = arrayOf("사과", "배" , "딸기" , "키위" , "김채연")
        listView.adapter = ArrayAdapter(this, android.R.layout.simple_list_item_1,item) //context는 한 엑티비티의 모든 정보를 담고있
            // 어댑터의 첫번쨰 인자는 THIS / 두번째 인자는 레이아웃(저건 제공받은 것으로, 텍스트뷰 하나로 구성된 레이아웃이다) / 마지막은 넣을 변수

   }
}

원하는 배열을 담을 변수 item을 선언하고 요소를 입력한다.

앞서 액티비티에서 listView 를 선언했기에, 바로 호출이 가능하다.

adapter : 리스트뷰에 데이터를 직접 넣을 수 있게 도와줌. listView와 짝꿍이다.

ArrayAdapter(this , 레이아웃 형태 , 넣을 값)

위에서 사용한 simple_list_item_1 은 제공받은거다. (텍스트뷰 하나로 구성된 레이아웃)

<이외에 listView에서 사용되는 레이아웃 예시>

simple_list_item_
텍스트뷰 두개로 구성된 레이아웃
simple_list_item_checked
오른쪽에 체크 표시가 됨
simple_list_item_single_choice
오른쪽에 라디오 버튼이 나옴
simple_list_item_multiple_choice
오른쪽에 체크버튼이 나옴

결과는 사과, 배, 딸기, 키위, 김채연 이 총 5칸으로 화면에 나타난다.

만약 한 칸 안에 리스트 하나 뿐 아니라 다양하게 넣는다면 ArrayAdapter 는 적절하지 않다.

이번엔 좀 더 다양한 listView 를 만들것이다.

그러면, 우선 모델 객체를 만들어줘야한다. JAVA 내 같은 파일에 User 라는 이름의 새 객체를 만들어준다.

package com.example.listvieskt
/*
*클래스 모델 객체
 */
class User (val profile: Int, val name: String, val age: String, val greet: String)

User 라는 이름으로 만들었기에 class명도 동일하게 만들어준다. 그리고 변수를 선언하면 된다.

이 역할은 '클래스 모델 객체' 로, 쉽게 설명하자면

listView 를 단순하게 만들땐 하나의 리스트만 넣었었는데, 다양한 요소를 넣을때

"이러한 요소를 뿌려주겠다" 라고 준비를 한 후 어댑터를 커스텀하면 활용된다.

res->layout 에 파일을 추가한다.(이름은 자유)

flaticon 에서 원하는 이미지를 다운받아 사용한다. (drawable 에 추가 이름은 대문자를 피한다.)

만든 레이아웃에 다운받은 이미지를 추가한다. (리스트로 만들거니까 크기는 작게 줄인다.)

이 이미지의 id는 iv_profile 이다.

레이아웃의 크기가 풀사이즈 이기에 height를 wrap_content 로 바꿔 줄여준다.

이제 이 레이아웃(리스트뷰 1개) 에 이름, 나이, 인사말 을 각각 텍스트뷰로 삽입해준다.

(위치나 크기 등은 알아서 설정)

id는 tv_name , tv_greet , tv_age 로 설정한다. 텍스트는 샘플로 아무거나 적어줘도 된다.

이제 listView에 띄울 준비는 됐다.

이제 커스텀 어댑터를 만들 순서이다.

package com.example.listvieskt

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

class UserAdaptor (val context: Context,val UserList: ArrayList<User>) : BaseAdapter() {
    //User 클래스에 만들어놓은 요소를 넣는다
    override fun getCount(): Int {
        return UserList.size
    }

    override fun getItem(position: Int): Any {
        return UserList[position]

    }

    override fun getItemId(position: Int): Long {
        return 0
    }

    override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View {
        val view:View = LayoutInflater.from(context).inflate(R.layout.list_item_user,null)

        val profile = view.findViewById<ImageView>(R.id.iv_profile)
        val name = view.findViewById<TextView>(R.id.tv_name)
        val age = view.findViewById<TextView>(R.id.tv_age)
        val greet = view.findViewById<TextView>(R.id.tv_greet)

        val user = UserList[position] //UserList 는 메인액티비티에서 생성

        profile.setImageResource(user.profile)
        name.text = user.name
        age.text = user.age
        greet.text = user.greet

        return view
    }
}

val 이나 var 로 선언하면 변수 형태가 뭔지 알 수 없기때문에 " : " 을 활용해서 변수 타입을 부여해준다.

class UserAdaptor (val context: Context,val UserList: ArrayList<User>)

ArrayList 안에 앞서 만든 User의 형태를 따르도록 담아준다.

그리고 " : BaseAdapter() " 를 상속시킨다. -> 어댑터 라는 기능을 기본적으로 클래스에 부여해준다.

에러지점에 엔터 눌러서 뜨는 구현가능한것들 모두 자동완성. (p0 -> position , p1 -> convertView , p2 -> ViewGroup , TODO는 모두 삭제)

1. getView ; 리스트뷰에서 뷰를 가져왔을때 어떻게 뿌려줄 것이냐 라는걸 구현.

-LayoutInflatter -> 뷰를 붙이는 과정

[profile]

-profile 이미지를 직접 어떤 리스트들이 붙건 만들어줄 준비를 한다.(view 를 따른다.)

-view.findViewById<이미지 형태>(id) -> id로부터 View를 찾아라.

이제 나머지 이름,나이,인사 는 위의 profile 형태와 같다. 복사 후 변수명만 바꿔주면 된다.

[user]

-앞서 클래스로 선언했던 유저 변수를 끌고와준다.

-position 은 말 그대로 자리(0부터 세준다.)

-profile.setImageResource(user.profile) -> 클래스 모델 객체랑 연결이 되었다.

아직 user에는 데이터가 담기지 않았다. 조금 뒤에 담아줄 것이다.

2. getItem : 어떤 아이템들을 끌고올것이냐

-리스트에 있는 위치들 만큼

3. getCount : 리스트가 연결되어있는 갯수

-리스트의 사이즈를 return 해준다.

이제 메인 액티비티로 가서 만들어놓은 어댑터를 연결만 하면 끝난다.

package com.example.listvieskt

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.os.PersistableBundle
import android.widget.Adapter
import android.widget.ArrayAdapter
import com.google.firebase.firestore.auth.User
import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.android.synthetic.main.list_item_user.*


class MainActivity : AppCompatActivity() {
        var UserList = arrayListOf<User>( 
            User(R.drawable.android3, name: "김채연" , age: "22" , greet: "핫핫핫"),
        User(R.drawable.android3, name: "김리나" , age: "22" , greet: "안녕하세요"),
        User(R.drawable.android3, name: "김도희" , age: "22" , greet: "안녕하세요"),
        User(R.drawable.android3, name: "한은경" , age: "22" , greet: "안녕하세요"),
        User(R.drawable.android3, name: "고유진" , age: "22" , greet: "안녕하세요"),
        User(R.drawable.android3, name: "김윾진" , age: "19" , greet: "안녕하세요"),
        User(R.drawable.android3, name: "윤민규" , age: "22" , greet: "안녕하세요"),
        )
        override fun onCreate(savedInstanceState: Bundle?) { //엑티비티의 실행시작지점
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_main)

            val Adapter = UserAdaptor(this, UserList)
            listView.adapter = Adapter
   
    }
}

User(이미지 경로 , 이름 , 나이 , 인사)

이렇게 만든 UserList 를 활용해주면 된다.

val Adapter = UserAdaptor(this, UserList) -> 만들어놓은 어댑터를 가져온다.

무슨 이유인지 여기서 계속 오류가 난다. 강의를 여러번 봐도 강의 속 코드와 똑같은데 오류가 난다.

원인은 모르겠따 ㅜ^ㅜ

++) 오류 찾으면 뒤에 버튼 클릭하는 기능 더 해보기 !