CodeNewbie
  • [Android] 개발공부 32일차 TIL - Data Class 전달, Scope Function, Dialog(다이얼로그)
    2024년 01월 04일 16시 25분 13초에 업로드 된 글입니다.
    작성자: 짧은 코딩끈

    일자 : 2024.01.04


    금일 공부 목록

    • 스탠다드2주차 강의
    • 숙련 안드로이드 강의
    • 혼공컴운 강의
    • 객체지향 2차 세션 강의 (디자인패턴)

     

    다음 공부 목록

    • 리사이클러뷰 강의
    • 혼공컴운강의(운영체제)

    📝TIL 정리

    💬DataClass 전달


    • 복잡한 객체를 전달하는 데 사용
    • 데이터 클래스는 Serializable(자바) 또는 Parcelable(코틀린) 인터페이스 구현 필요.
    • (**Parcelable**은 성능이 더 우수)
    // Parcelable 인터페이스 구현
    @Parcelize ***
    data class User(val name: String, val age: Int) : Parcelable
    
    // 데이터 전달
    val user = User("John Doe", 30)
    val intent = Intent(this, SecondActivity::class.java).apply {
        putExtra("EXTRA_USER", user)
    }
    startActivity(intent)
    
    // 데이터 수신
    val receivedUser = intent.getParcelableExtra<User>("EXTRA_USER")

     

    @parcelize를 쓰려면 gradle plugin에 추가해줘야한다

    plugins {
        id("com.android.application")
        id("org.jetbrains.kotlin.android")
        id("kotlin-parcelize")
    }

    💬Scope Function(스코프 함수)


    - 코틀린의 스코프 함수(scope function)는 코드의 가독성을 향상시키고, 코드를 더 간결하게 작성하는 데 도움을 줌
    - 대표적인 스코프 함수: `let`, `run`, `with`, `apply`, `also`

    - apply 와 let, run의 차이는 객체 본인을 받는것인지 결과값 반환받는것인지의 차이

    apply는 this(객체 변수 그 자체를 지칭), let과 run은 it(중괄호 내의 결과값)

     

    1. apply

     

    객체의 생성과 초기화

    val newUser = User().apply {
        name = "John Doe"
        email = "john.doe@example.com"
    }

     

    뷰 설정

    val button = findViewById<Button>(R.id.button)?.apply {
        text = "Submit"
        setOnClickListener { /* ... */ }
        setOnFocusChangedLis~~~
    }

     

    Intent 설정

     

    val intent = Intent(context, MainActivity::class.java).apply {
        putExtra("EXTRA_KEY", "value")
        putExtra("EXTRA_KEY2", "value2")
        putExtra("EXTRA_KEY3", "value3")
    }

     

    2. also

     

    객체에 대한 부수적인 작업을 수행할 때 유용하게 사용

    객체 로깅 및 디버깅

    val request = Request.Builder()
        .url("http://example.com")
        .build()
        .also { println("Sending request to ${it.url}") }
    httpClient.newCall(request).execute()

     

    객체 상태 변경

    val file = File(path).also{
        println("File created: ${it.absolutePath}")
    }

     

    리스트나 컬렉션 조작

    val numbers = mutableListOf(1, 2, 3)
    numbers
    .also { println("Original numbers: $it") }
    .add(4)
    .also { println("Numbers after addition: $it") }

     

    3. run

     

    초기화 및 결과 반환

    val result = user.run{
        updateProfile()
        calculateScore()
    }

     

    복잡한 로직 수행 후 값 반환

    val fullName = person.run{
        val firstName = getFirstName()
        val lastName = getLastName()
        "$firstName $lastName"
    }

     

    4. let

     

    Null 검사와 사용

    val name: String? = getName()
    name?.let {
        println("Name is $it")
    }

     

    체이닝된 메소드 호출

    getUser()?.let {
        sendEmail(it.email)
        updateStatus(it.id, "Email sent")
    }

     

    5. with

     

    `with`는 주로 객체가 `null`이 아닐 것이 확실한 경우에 사용할 것(? 사용 불가)
     객체의 여러 속성 사용

    val person = Person("Alice", 30)
    with(person) {
        println("Name: $name, Age: $age")
    }

     

    복잡한 객체 구성

    val menu = Menu()
    with(menu) {
        addItem("Home")
        addItem("Profile")
        setOnClickListener { /* ... */ }
    }

    💬Dialog(다이얼로그)


    다이얼로그

    팝업창을 띄워서 무언가를 선택하거나 수정하도록 하거나

    보여주거나 등등 한다

     

    강의에서 배운것은 5가지인데

    마지막 로딩바같은 경우는 구식과 신식을 함께 보여준다.

     

    1. 기본 다이얼로그

    Builder를 통해서 창의 제목 메세지 아이콘을 정할 수 있다.

    //1. 기본 다이얼로그
            binding.btnAlert.setOnClickListener {
                var builder = AlertDialog.Builder(this)
                builder.setTitle("기본 다이얼로그 타이틀")
                builder.setMessage("기본 다이얼로그 메세지")
                builder.setIcon(R.drawable.sample_1)
    
                // 버튼 클릭시 무슨 작업을 할것인지
                val listener = object : DialogInterface.OnClickListener{
                    override fun onClick(dialog: DialogInterface?, which: Int) {
                        when(which) {
                            DialogInterface.BUTTON_POSITIVE -> binding.tvTitle.text = "확인 누름"
                            DialogInterface.BUTTON_NEUTRAL -> binding.tvTitle.text = "중립 누름"
                            DialogInterface.BUTTON_NEGATIVE -> binding.tvTitle.text = "거절 누름"
                        }
                    }
                }
                builder.setPositiveButton("확인", listener)
                builder.setNeutralButton("중립", listener)
                builder.setNegativeButton("거절", listener)
    
                builder.show() // 다이얼로그 보여주기
            }

     

    2. 커스텀 다이얼로그

    특정 레이아웃을 만든뒤에

    그 레이아웃을 다이얼로그에 띄운다

    //2. 커스텀 다이얼로그
            binding.btn2Custom.setOnClickListener {
                val builder = AlertDialog.Builder(this)
                builder.setTitle("커스텀 다이얼로그")
                builder.setIcon(R.drawable.sample_1)
    
                val v1 = layoutInflater.inflate(R.layout.dialog, null)
                builder.setView(v1)
    
                // p0에 해당 AlertDialog가 들어온다. findViewById를 통해 view를 가져온다.
                val listener = DialogInterface.OnClickListener{ p0, p1 ->
                    val alert = p0 as AlertDialog
                    val edit1 = alert.findViewById<EditText>(R.id.editText)
                    val edit2 = alert.findViewById<EditText>(R.id.editText2)
    
                    binding.tvTitle.text = "이름 : ${edit1?.text}"
                    binding.tvTitle.append("/ 나이 : ${edit2?.text}")
                }
                builder.setPositiveButton("확인", listener)
                builder.setNegativeButton("취소", null)
    
                builder.show()
    
            }

    <?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="match_parent"
        android:orientation="vertical">
    
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:padding="16dp"
            android:orientation="vertical">
    
            <EditText
                android:id="@+id/editText"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:ems="10"
                android:inputType="textPersonName"
                android:hint="Name" />
    
            <EditText
                android:id="@+id/editText2"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:ems="10"
                android:inputType="textPersonName"
                android:hint="AGE" />
        </LinearLayout>
    </LinearLayout>

     

    3. 날짜 선택 다이얼로그

    AlertDialog가 아닌 Calendar를 통해 인스턴스 생성

    캘린더 내에 있는 년 월 일을 get 해온다

    날짜 선택되었을 때 TextView에 그 날짜로 대체한다

    //3. 날짜 다이얼로그
            binding.btn3Date.setOnClickListener {
                val calendar = Calendar.getInstance()
                val year = calendar.get(Calendar.YEAR)
                val month = calendar.get(Calendar.MONTH)
                val day = calendar.get(Calendar.DAY_OF_MONTH)
    
                val listener = DatePickerDialog.OnDateSetListener{datePicker, i, i2, i3 ->
                    binding.tvTitle.text = "${i}년 ${i2+1}월 ${i3}일" // 월에 1을 붙이는 이유?
                }
    
                var pircker = DatePickerDialog(this, listener, year,month,day)
                pircker.show()
            }

     

    4. 시간 선택 다이얼로그

    날짜 선택 다이얼로그와 비슷

    시간은  24시간 또는 12시간 표현식을 정할 수 있다.

    //4. 시간 다이얼로그
            binding.btn4Time.setOnClickListener {
                val calendar = Calendar.getInstance()
                val hour = calendar.get(Calendar.HOUR)
                val minute = calendar.get(Calendar.MINUTE)
    
                val listener = TimePickerDialog.OnTimeSetListener{timePicker, i , i2 ->
                    binding.tvTitle.text = "${i}시 ${i2}분"
                }
    
                val picker = TimePickerDialog(this, listener, hour, minute,false)
                // true면 24시간 표시, false면 오전 오후
                picker.show()
            }

     

    5. 프로그레스 다이얼로그 (구식)

    //         5. 프로그레스 다이얼로그
            binding.btn5Progress.setOnClickListener {
                // 권장하진 않지만 사용은 가능하다.
                var pro = ProgressDialog.show(this, "타이틀입니다.", "메시지입니다.")
    
                // 핸들러를 통해서 종료 작업을 한다.
                val handler = Handler()
                val thread = Runnable { pro?.cancel() }
                handler.postDelayed(thread, 5000) // 딜레이는 5초
            }

     

    6. 프로그레스 다이얼로그 (신식)

    레이아웃을 만들어서 그것을 띄운다

    <?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="match_parent"
        android:gravity="center"
        android:orientation="vertical">
    
        <ProgressBar
            android:id="@+id/progressbar"
            android:layout_width="match_parent"
            android:layout_height="76dp"
            android:layout_gravity="center"
            android:layout_marginTop="48dp"
            android:indeterminate="false"/>
    
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="loading..."
            android:textSize="16sp"
            android:layout_marginTop="16dp"/>
    </LinearLayout>

    //        6. 프로그래스 다이얼로그 다른 방식. (커스텀과 비슷)
            binding.btn6Progress.setOnClickListener {
                val builder = AlertDialog.Builder(this)
                builder.setTitle("프로그래스바")
                builder.setMessage("로딩중입니다.")
                builder.setIcon(R.mipmap.ic_launcher)
    
                val v1 = layoutInflater.inflate(R.layout.progressbar, null)
                builder.setView(v1)
    
                builder.show()
    
                // indeterminate 처리 결과 속도에 대해서 불확정적 여부 묻는것 xml 파일에서 확인
            }

     

    위 내용들을 실행한 화면

     

     

    참고사이트 : 

    https://soopeach.tistory.com/140

     

    안드로이드[Android] 기본 dialog(대화창) 만들기(기본, 리스트, 라디오버튼, 체크박스)

    대화창(이하 다이어로그)는 일반적으로 상대방에게 알림을 보여주거나 추가적인 정보를 주고받을 수 있는 화면 전체를 가리지 않고 일부만 차지하는 화면입니다. dialog를 view, fragment등을 통해서

    soopeach.tistory.com

    https://todaycode.tistory.com/184

     

    안드로이드 다이얼로그 만들기(Custom Dialog까지)

    1. Dialog 1-1. 개념 1-2. 생명주기 2. 기본 Dialog 2-1. 텍스트만 2-2. 부정/긍정 버튼 2-3. 부정/긍정/중립 버튼 2-4. 리스트 2-5. 라디오 버튼 2-6. 체크박스 3. Custom Dialog 3-1. Dialog를 상속받는 방법 3-2. theme를

    todaycode.tistory.com

     

     

    금일 회고

    상태:😐

    회고: 

    하...

    TIL 적은게 반이 날아갔다..

    다시 적으려니 보낸 30분이 너무 아깝다

    미리미리 저장할걸 그랬다..ㅠㅠ

     

    갑자기 컴퓨터가 멈춰서 그전까지 열심히 적은 다이얼로그 내용들이 다 날아갔다

     

    여튼 오늘은 숙련강의 끝까지 완강했지만,

    전체 반은 이해 반은 이해못한채 끝냈다.

     

    확실히 숙련주차부터 어렵다고 하는데

    이것들을 온전히 다 이해못하면(리사이클러뷰, 프래그먼트)

    심화에서는 그냥 도태될것이다..

     

    열심히 하자(사실 회고록도 이거보다 길게 적었는데,,, 멘탈 깨져서 짧게)

     

     

    댓글