본문 바로가기
  • GDG on campus Ewha Tech Blog
3-1기 스터디/안드로이드 기초

[4주차] Android basics in Kotlin Unit : 2 Layouts (3) , Unit : 3 Nevigation (1)

by 하동녹초오레오 2021. 11. 15.

  PATHWAY 3  Display a Scrollable List

1. Kotlin에서 목록 사용

목록 데이터 유형

  • 목록 : 특정 순서가 있는 항목의 모음
    • 코틀린의 목록 유형 : 사용시 포함될 수 있는 요소 유형을 지정해야함
      • ex) List<Int>
      • List : 읽기 전용 목록, 만든 후 수정 불가
      • MutableList : 변경 가능한 목록, 만든 후 수정 가능, 요소를 추가, 삭제, 업데이트 가능
      • listOf : 읽기 전용 목록을 반환
      • val numbers: List<Int> = listOf(1,2,3,4,5,6)
      listOf - Kotlin Programming Language
 

listOf - Kotlin Programming Language

 

kotlinlang.org

 

List 만들기

fun main()
{
    //val numbers:List<Int> = listOf(1,2,3,4,5,6)
    //타입 추론이 가능할 때, 변수의 데이터 유형을 생략할 수 있음
    val numbers = listOf(1,2,3,4,5,6)
    println("List : ${numbers}")
    //println("List : " + numbers)
    println("Size : ${numbers.size}")
}
  • 타입 추론이 가능할 때, 변수의 데이터 유형을 생략할 수 있음
  • 대괄호 [] : List임을 나타냄
  • 요소의 순서 == 요소를 만든 순서

 

List의 메소드

  • Listname.size : 목록의 크기를 반환, 메소드 아님, () 사용 x
  • Listname.get(index) : 각 요소에 index를 통해 액세스
  • println("First element: ${number.get(0)}")
  • Listname[index] : 각 요소에 index를 통해 액세스
  • println("Second element: ${numbers[1]}")
  • Listname.first() : 목록의 첫번째 요소를 반환
  • Listname.last() : 목록의 마지막 요소를 반환
  • Listname.contains() : 특정이름이 목록에 있는지 확인 가능
  • Listname.contains(특정이름)//목록에 있으면 true 반환, 없으면 false 반환

 

읽기 전용인 목록 List

  • List는 읽기 전용 목록이다.
    • 초기화 이후에 요소를 추가하거나 변경 불가
    fun main() {
        val colors = listOf("green", "orange", "blue")
    		colors.add("purple")//오류 발생
    		colors[0] = "yellow"//오류발생
    }
    
    • List에는 add() 메소드가 없음
    • 요소의 값을 변경할 수 없음

 

List에서 새 목록을 반환하는 작업

  • Listname.reversed() : 요소가 역순으로 있는 새 목록을 반환
  • Listname.sorted() : 요소가 오름차순으로 정렬된 새 목록을 반환
    • 요소가 문자열일 때 : 알파벳 순으로 정렬됨 (사전순)
  • 원본 List가 변경되지는 않음

 

변경 가능한 목록 : MutableList

  • mutableListOf() 호출하여 만듦
  • 목록 생성하기
    • 목록에 요소가 없기 때문에 타입 추론이 불가능 -> 타입 지정 필수
    • 변경 가능한 목록이지만 val 사용 가능
      • entrees 변수에는 목록 참조가 포함되어있음, entrees 가 val 이라는 것은 해당 목록 참조가 변경되지 않음을 의미함. 참조는 목록의 내용이 변하더라도 변경되지 않아서 상관없음.
      • ex) 어떤 객체가 val로 선언되었더라도 객체의 속성값은 변경 가능함
  • val entrees: MutableList<Int> = mutableListOf() //val entrees = mutableListOf<Int>()

 

MutableList 의 메소드 : MutableList 이름으로 접근

  • add() : 요소가 목록에 성공적으로 추가되면 true 반환, 추가되지 않으면 false 반환
    • 하나의 목록에는 하나의 데이터 유형으로 이루어진 요소들만 추가 가능
    println("Add noodles: ${entrees.add("noodles")}")
    println("Entrees: $entrees")
    
  • addAll() : 한번에 여러 요소를 추가할 수 있음
    • List 데이터 유형의 목록을 addAll()을 통해 MutableList에 추가 가능
    val moreItems = listOf("ravioli", "lasagna", "fettuccine")
    //moreItems 는 List 유형
    println("Add list: ${entrees.addAll(moreItems)}")
    println("Entrees: $entrees")
    
  • remove(요소) : 요소가 목록에서 성공적으로 삭제되면 true 반환, 삭제되지 않으면 false 반환.
    • 목록에 없는 항목을 삭제하려고 하면 false를 반환, 해당 목록은 변경되지 않음
  • removeAt(index) : index에 해당하는 요소를 삭제
    • println("${entrees.removeAt(0)}")
    • //해당 index에 있던 삭제된 요소를 반환
    • size-1보다 큰 index를 적으면? : false를 반환하는게 아니라 오류가 난다.
    • IndexOutOfBoundsException
  • clear() : 전체 목록 삭제
  • isEmpty() : 목록이 비어있으면 true, 아니면 false 반환
  • size (메소드 아닌듯) : 현재 크기를 반환

 

while 루프

fun main()
{
   val guestsPerFamily = listOf(2,4,1,3)
   
   var i = 0
   var totalGuests = 0
   while(i<guestsPerFamily.size)
   {
       totalGuests += guestsPerFamily[i]
       i++ 
   }
   println("totalGuests : " + totalGuests)
}

 

for 루프

for (number in numberList) {
   // For each element in the list, execute this code block
}
fun main()
{
    val names = listOf("Jessica", "Henry", "Alicia", "Jose")

    println("${names}")
    
    for(name in names)
    {
        println(name)
    }
}
  • 목록의 요소에 직접 접근
  • for문 코드 블록이 실행된 뒤 자동으로 다음 요소에 접근하도록
  • 업데이트 해줌
  • for 루프 이용
    • for (item in list) print(item) // Iterate over items in a list
    • for (item in 'b'..'g') print(item) // Range of characters in an alphabet
    • for (item in 1..5) print(item) // Range of numbers
    • for (item in 5 downTo 1) print(item) // Going backward
    • for (item in 3..6 step 2) print(item) // Prints: 35

 

주문 정보 저장하는 코드 만들기

 

[Kotlin] 가변 인자(vararg) 사용하기, 배열을 가변 인자로 넘기기

Variable number of arguments 자바와 마찬가지로 코틀린은 가변 인자를 지원한다. 가변 인자를 사용하면 함수를 호출할 때 인자 개수를 유동적으로 지정할 수 있다. 사용하려면 인자 앞에 vararg 를 붙이

zion830.tistory.com

 

2. RecyclerView를 사용하여 스크롤 가능한 목록 표시

패키지 만들기

  • Project 창 - app > java > com.example.affirmations(프로젝트명, 앱 이름) 우클릭 > New > Package

 

앱에 RecyclerView 추가하기

  • 항목  : 표시할 목록의 단일 데이터 항목입니다. 앱의 Affirmation 객체 하나를 나타냅니다.
  • 어댑터 : RecyclerView에서 표시할 수 있도록 데이터를 가져와 준비합니다.
  • ViewHolder : 확인을 표시하기 위해 사용하거나 재사용할 RecyclerView용 뷰의 풀입니다.
  • RecyclerView : 화면에 표시되는 뷰입니다.
  • 리사이클러뷰 작동 원리

레이아웃 종류

  • ConstraintLayout : 한 레이아웃에 하위 뷰 여러개를 배치 할 경우 적합
  • FrameLayout : 단일 하위 뷰인 경우 적합

 

ViewHolder

  • ViewHolder는 RecyclerView의 단일 목록 항목 뷰를 나타냄
  • 재사용 가능
  • ViewHolder 인스턴스는 목록 항목 레이아웃 안에 개별 뷰의 참조를 보유함 → 새로운 데이터로 목록 항목 뷰를 더 쉽게 업데이트할 수 있음
  • 뷰 홀더는 RecyclerView가 화면에서 뷰를 효율적으로 이동하기 위해 사용하는 정보도 추가함
  • 어댑터만 뷰홀더를 사용하므로 중첩 클래스로 구현하는 것이 구조파악에 유리함

+) 중첩 클래스 : 다른 클래스 내부에 클래스를 정의하는 것

 

리사이클러뷰 구현 과정

  1. activity_main.xml 에 리사이클러뷰(리사이클러뷰 껍데기) 구현하기
  2. data item (항목, 이 코드랩에서는 Affirmation 객체) 만들기
  3. 어댑터 구현 - 어댑터 내에 중첩 클래스로 뷰홀더 구현하기
  4. MainActivity 수정해서 껍데기 뿐인 리사이클러뷰에 진짜 데이터를 이용한 뷰를 뿌려줄 코드 작성

 

3. 카드를 사용하여 이미지 목록 표시

Affirmation 클래스

  • 문자열만 취급하던 객체(data item) → 이미지까지 포함하도록 확장

      +) 리소스 주석 : 인자 전달 순서를 잘못 사용하는 경우 방지할 수 있음

           → 잘못된 유형의 리소스 ID를 제공하는 경우 경고 표시됨

 

Datasource 클래스의 loadAffirmations() 함수 업데이트

  • Affirmation 객체가 이미지까지 포함하도록 업데이트 되었음 → 그에 따라 datasource 클래스도 업데이트 해줘야함

 

목록 항목 레이아웃에 ImageView 추가

  • 각 항목에 대한 xml을 관리하는 list_item.xml 파일에 ImageView를 추가함

 

ItemAdapter 업데이트

  • ItemViewHolder 인스턴스가 이미지뷰에 대한 참조까지 포함하도록 수정

UI 수정

  • 패딩 추가 : 목록 사이에 공백 추가
    • 반복되는 각 아이템 항목에 대한 뷰에서 공백을 추가해야함
    • → list_item.xml 수정
  • text 스타일 변경 : android:textAppearance="?attr/textAppearanceHeadline6"

 

카드 사용하기

  • 명언에 해당하는 텍스트와 이미지를 한 항목으로 묶여서 보여주는 카드 형식을 활용한다. → MeterialCardView 활용

 

색상 변경

  • 앱 테마 색상 변경 : 색상 리소스 추가 후 (colors.xml) themes.xml에서 colorPrimary, colorPrimaryVariant 수정

      +) 어두운 테마 색상 업데이트 : 다크 모드 실행시 적용되는 테마

 


  PATHWAY 1  Navigate between screens

1. Kotlin의 컬렉션

컬렉션

  • 단어 목록이나 직원 기록 모음과 같은 관련 항목 그룹
  • 순서 지정 or 순서 지정하지 않을 수 있음
  • 항목이 꼭 고유하지 않아도 괜찮음

 

집합

  • 컬렉션 유형 중 하나
  • 중복될 수 없음, 순서는 중요하지 않음
  • 집합의 수학적 개념과 유사
  • setOf()
  • intersect(), union()

 

맵(또는 사전)

  • 컬렉션 유형 중 하나이다.
  • 키 - 값 쌍의 집합
  • 특정 키가 부여된 값을 쉽게 찾을 수 있음
  • mutableMapOf<데이터 타입, 데이터 타입>()
  • put() : 항목 추가

 

for each

자동으로 모든 항목을 탐색한 후 항목별로 작업을 실행함

peopleAges.forEach { print("${it.key} is ${it.value}, ") }

 

filter()

  • 컬렉션에서 특정 조건과 일치하는 항목을 찾아줌
val filteredNames = peopleAges.filter { it.key.length < 4 }
println(filteredNames)

 

람다 표현식, 람다

  • 이름은 없지만 곧바로 표현식을 사용할 수 있는 함수
  • val triple: (Int) -> Int = { a: Int -> a * 3 }
  • val 변수명 : 변수유형 → 변수유형 = {람다식}

 

고차식

  • 함수를 다른 함수로 전달하거나 다른 함수에서 함수를 반환하는 것
  • 매개변수로 함수를 이용하는 경우    ex) Android의 OnClickListener 및 OnKeyListener

 

단어 목록 만들기

fun main() {
    val words = listOf("about", "acute", "awesome", "balloon", "best", "brief", "class", "coffee", "creative")
    val filteredWords = words.filter { it.startsWith("b", ignoreCase = true) } //B로 시작하는 단어
        .shuffled()//필터링된 단어 섞이도록
        .take(2)//두개의 항목만 가져오도록
        .sorted()//사전순으로 정렬
    println(filteredWords)//출력
}

 

2. 활동 및 인텐트

 

실행할 작업을 나타내는 객체

  1. 암시적 인텐트 : 보다 추상적, 링크 열기, 이메일 작성 등
  2. 명시적 인텐트 : 매우 구체적, 실행할 활동을 정확하게 알 수 있음. 대부분 자체 앱의 화면임

명시적 인텐트

클릭 리스너 설정 → Intent 생성(컨택스트, 클래스 전달)

❗ 클래스 이름 주의하기!!

 

암시적 인텐트

  • 버튼 클릭시 외부로 이어지는 경우
  • CATEGORY_APP_MAPS - 지도 앱 실행
  • CATEGORY_APP_EMAIL - 이메일 앱 실행
  • CATEGORY_APP_GALLERY - 갤러리(사진) 앱 실행
  • ACTION_SET_ALARM - 백그라운드에서 알람 설정
  • ACTION_DIAL - 전화 걸기

 

3. 활동 수명 주기 단계

활동 수명 주기

  • 활동 수명 주기 : 활동이 처음 초기화될 때부터 마지막으로 소멸되어 시스템에서 메모리를 회수할 떄까지 거쳐가는 여러 상태로 구성됨

 

단계별 과정

  1. Initialized 단계 : 새 Activity 객체가 메모리에 만들어짐
  2. onCreate() : 활동이 초기화된 직후 (새 Activity 객체가 메모리에 만들어질 때) 한번 호출, onCreate 실행되면 활동이 생성됨(Created)
  3. Created 단계 : 활동이 생성됨
  4. onStart() : onCreate() 직후 호출, 활동을 화면에 표시, 활동의 수명 주기에서 여러번 호출 가능
  5. Started 단계 : onStop() 호출을 통해 (사용자가 기기 홈 화면으로 돌아올 때) Created 단계로 변화, 또는 onResume() 호출을 통해 Resumed 단계로 변화
  6. onStop() : onStart()와 상응
  7. onResume() : 활동 포커스를 제공하고 사용자가 상호작용할 수 있도록 활동을 준비함

 

기기 회전시

  1. onSaveInstanceState() 사용하여 번들 데이터 저장
  2. onCreate() 사용하여 번들 데이터 복원

 

+) Frameworks detected Android framework is detected. -> facets 항목 수정해서 해당 오류 해결하고 실습 화면 추가하기

댓글