안드로이드 앱 개발 - 숙련 마무리

kkomin·2023년 8월 24일
0

Android Studio

목록 보기
16/44
post-thumbnail

👉 앱 개발 숙련 개념 정리를 마무리해보자.


앱 개발 숙련 목표

  1. 뷰바인딩에 대해 이해하고 findViewById와의 차이점을 설명
  2. 어댑터 뷰의 기본 개념 및 종류, 리스트 뷰와 그리드 뷰의 설정 방법 이해
  3. 커스텀 항목 뷰를 정의하는 방법, RecyclerView를 사용하는 방법 이해
  4. 프래그먼트의 기본개념 및 프래그먼트 생명주기 이해
  5. 다이얼로그가 무엇인지 알고 구조에 대해 이해
  6. 알림의 중요도 순서를 이해

👀 ViewBinding

viewBinding은 View와 상호작용하는 코드를 쉽게 작성할 수 있고, 인스턴스에 상응하는 레이아웃에 ID가 있는 모든 View의 직접 참조가 포함된다.

ViewBinding V.S findViewById

1. Null Safety

뷰 바인딩은 View를 직접 참조를 생성하기 때문에 유효하지 않은 ID로 인해 Null 예외가 발생할 위험이 없다.

2. Type Safety

각 바인딩 클래스에 있는 필드의 유형이 xml 파일에서 참조하는 뷰와 일치해 클래스 변환 예외가 발생할 위험이 없다.


✅ AdapterView

어댑터 뷰는 여러 항목을 나열하고 선택이 가능하도록 기능을 제공하는 뷰로, ListView와 GridView가 있다. 표시할 항목 데이터를 직접 나열하지 않고 어댑터라는 객체로부터 공급받는다.

ListView는 항목들을 수직(vertical)로 나열하는 방식이고, GridView는 항목들을 격자 형태로 나열하는 방식을 말한다.

종류

  • BaseAdapter : 사용자 정의 어댑터 구현 시
  • ArrayAdapter : 정의된 배열로부터 데이터를 공급받음
  • CusorAdapter : 데이터베이스로부터 데이터를 공급받음
  • SimpleAdapter : 데이터를 Map의 리스트로 관리

📜 ListView

복수 개의 항목을 수직으로 나타내는 방식인 ListView의 설정방법을 정리해보자.

1. 메인화면 레이아웃에 ListView 위젯 정의

2. Adapter 생성

3. ListView 객체에 Adapter 연결


📸 GridView

항목들을 격자 형태로 나열해 이미지를 나열할 때 주로 사용하는 방식으로 GridView의 설정방법을 정리해보자.

1. 메인화면 레이아웃에 GridView 정의

2. ArrayAdapter 객체를 생성하고 GridView 객체에 연결


📘 CustomView

하나의 문자열이나 이미지뿐만 아니라, 다수의 문자열이나 이미지를 포함하는 임의의 이미지 뷰를 나열할 때 주로 사용하는 방식으로 CustomView의 설정방법을 정리해보자.

1. item_recyclerview 레이아웃에 CustomView 정의

<?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:id="@+id/iconItem"
        android:layout_width="@dimen/icon_size"
        android:layout_height="@dimen/icon_size"
        android:scaleType="centerCrop"
        android:padding="@dimen/icon_padding"
        android:layout_gravity="center_vertical"
        android:layout_weight="1"
        android:src="@drawable/sample_0" />
    <LinearLayout
        android:orientation="vertical"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="2">
        <TextView
            android:id="@+id/textItem1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textColor="@color/black"
            android:textSize="@dimen/list_item_text_size1"
            android:padding="@dimen/list_item_padding"
            android:hint="Name"
            />
        <TextView
            android:id="@+id/textItem2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textColor="@color/black"
            android:textSize="@dimen/list_item_text_size2"
            android:padding="@dimen/list_item_padding"
            android:hint="Age"
            />
    </LinearLayout>
</LinearLayout>

2. Dimen 파일 생성

TextView의 TextSize 및 padding이 dimen에서 가져오고 있기 때문에 이를 위한 dimen 파일을 생성하고 코드를 추가해준다.

3. 데이터 클래스 정의

항목과 관련된 데이터 클래스를 생성하고 정의해준다.

4. 어댑터 클래스 정의

class MyAdapter(val Context : Context, val mItems: MutableList<MyItem>) : BaseAdapter() {
    // 항목 총 개수 반환
    override fun getCount(): Int {
        return mItems.size
    }

    // 항목 중 position 위치의 항목 반환
    override fun getItem(position: Int): Any {
        return mItems[position]
    }

    // 항목 id를 항목의 위치로 간주함
    override fun getItemId(position: Int): Long {
        return position.toLong()
    }

    // position 위치의 항목에 해당되는 항목뷰를 반환하는 것이 목적
    override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View {
        
        // convertView : ListView에 항목을 띄울 view
        var convertView = convertView
        
        if(convertView == null)
            convertView = LayoutInflater.from(parent?.context).inflate(R.layout.item_recyclerview, parent, false)

        val item:MyItem = mItems[position]

        // convertView 변수로 참조되는 항목 뷰 객체 내에 포함된 객체를 id를 통해 얻어오기
        val iconImageView = convertView?.findViewById<View>(R.id.iconItem) as ImageView
        val tv_name = convertView.findViewById<View>(R.id.textItem1) as TextView
        val tv_age = convertView.findViewById<View>(R.id.textItem2) as TextView

        // 어댑터가 관리하는 항목 데이터 중에서 position 위치의 항목의 객체를 해당 항목에 설정
        iconImageView.setImageResource(item.aIcon)
        tv_name.text = item.aName
        tv_age.text = item.aAge

        return convertView
    }
}

5. 메인화면 레이아웃에 ListView 위젯 정의!

6. AdapterView 객체에 어댑터 연결


♻️ RecyclerView

한정적인 화면에 많은 데이터를 넣을 수 있는 view로, ListView를 삭제 및 생성을 반복하는 것을 보완한 방식으로, 사용자가 스크롤을 할 때, 위에 있던 항목이 다시 아래로 돌아오면서 재사용하는 방식이다.

RecyclerView 사용방법을 정리해보자.

1. 메인화면 레이아웃 설정

2. Adapter 클래스 정의

class MyAdapter(val mItems: MutableList<MyItem>) : RecyclerView.Adapter<MyAdapter.Holder>() {
    interface ItemClick {
        fun onClick(view: View, position: Int)
    }

    var itemClick : ItemClick? = null

    // ViewHolder 생성
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyAdapter.Holder {
        // View binding을 이용해 아이템 레이아웃을 inflate하고 View Holder 생성
        val binding = ItemRecyclerviewBinding.inflate(LayoutInflater.from(parent.context), parent, false)
        return Holder(binding)
    }
    
    // ViewHolder에 Data binding
    override fun onBindViewHolder(holder: Holder, position: Int) {
        // 아이템 뷰 클릭 이벤트 설정
        holder.itemView.setOnClickListener {
            itemClick?.onClick(it, position)
        }
        // 아이템 데이터 binding
        holder.iconImageView.setImageResource(mItems[position].aIcon)
        holder.name.text = mItems[position].aName
        holder.age.text = mItems[position].aAge
    }
    
    // id를 항목의 위치로 간주함 -> 아이템의 id 반환
    override fun getItemId(position: Int): Long {
        return position.toLong()
    }

    // 항목 총 개수 반환
    override fun getItemCount(): Int {
        return mItems.size
    }

    // Hoder 클래스 정의
    inner class Holder(val binding: ItemRecyclerviewBinding) : RecyclerView.ViewHolder(binding.root){
        val iconImageView = binding.iconItem
        val name = binding.textItem1
        val age = binding.textItem2
    }
}

3. MainActivity 정의

4. CustomView와의 차이점

Holder 코드를 먼저 만들어주어야 하고, onCreateViewHolder에서 Holder을 리턴해주어야 한다는 것

  • CustomView
  • RecyclerView

📄 Fragment

activity 위에서 동작하는 모듈화된 사용자 인터페이스로 하나의 activity에 여러 개의 fragment를 조합해 창이 여러 개인 UI를 구축할 수 있고, 하나의 fragemnt를 여러 activity에서 재사용이 가능하며, activity에서 activity로 넘어가는 것보다 빠르기 때문에 자주 사용된다.

fragment 생명주기

fragment의 생명주기는 activity의 생명주기와 연관되어 있다.

👉 자세한 설명은 evergreen_tree님의 블로그 참고


📚 Dialogue

사용자에게 결정을 내리거나 추가 정보를 입력하라는 메세지를 표시하는 작은 창을 말한다.

🚧 구조

구조는 제목, 콘텐츠 영역, 작업 버튼으로 이루어져 있다.


⏰ 알림

알림 기능은 사용자에게 앱과 관련된 정보를 보여주는 기능이다. 알림을 터치하면 앱으로 이동할 수 있으며, 상단 부분에 표시된다.

☃️ 알림 중요도 순서

  • 긴급 : IMPORTANCE_HIGH - 🔔, 헤드업 알림 표시
  • 높음 : IMPORTANCE_DEFAULT - 🔔
  • 보통 : IMPORTANCE_LOW - 🔔
  • 낮음 : IMPORTANCE_MIN - 🔕, 상태줄에 표시 ❌
profile
소소한 코딩 일기

0개의 댓글