티스토리 뷰

https://world-of-larooly.tistory.com/50

 

Kotlin 연습 점심 추천 어플 만들기 1단계 준비

코틀린을 공부하기 시작은 했는데 진도가 너무 안 나가는 도중에 한분이 아이디어를 주셔서 기~~~~본을 이용해서 만들어 볼까 합니다. (해당 분에게 허락을 받아 공개로 돌립니다.) 1 탄은 기본

world-of-larooly.tistory.com

 

이번에는 점심 메뉴를 한번에 다 보여주는 페이지를 만들어 볼꺼에요. 

(사실 이거만 만들면 추천 만드는건 쉬워요)

 

Swift 였다면 UITableView를 써서 했을텐데 

여기는 이름이 다릅니다. 

대략 아래처럼 바뀌신다고 생각하시면 됩니다.

Swift Kotlin
UITableView RecyclerView
UITableViewCell RecyclerView.Adapter

 

* 아예 처음 하시는 분들을 위한 설명

- 메뉴판을 만드려면 여러개의 메뉴가 필요하겠죠?

- 근데 그걸 일일이 만들기는 힘들겠죠? 

- 아래 이미지를 예로 봅시다

이게 오늘 우리가 만들꺼에요.

- 이걸 일일이 만들기는 너무 힘들죠?

- 그래서 한 칸만 만든 다음 반복적으로 글자(데이터)만 바꿔서 화면에 찍어줄꺼에요. 

이렇게 잘린 한칸을 Adapter 라고 합니다.

아래 단계로 나누어 해볼께요.

1단계 Adapter 만들기 

2단계 보여줄 전체 View 만들기

 

1단계 Adapter 만들기 

그럼 일단 Adapter를 만들어 봅시다. (총 3개를 만들껍니다.)

* Adapter 레이아웃 (total_recycle_adapter.xml)

- 단순하게 만들어 봅시다.

저는 이런 모양으로 만들었어요.

<?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"
    xmlns:tools="http://schemas.android.com/tools"
    android:paddingHorizontal="20dp"
    android:paddingVertical="10dp"
    android:orientation="vertical"
    android:background="#00F8F291"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <TextView
        android:id="@+id/nameView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="음식 이름"
        android:textSize="20sp"
        android:textStyle="bold" />

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="horizontal">

            <TextView
                android:id="@+id/typeView"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="한식"
                android:textSize="16sp" />

            <TextView
                android:id="@+id/mealView"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="면류"
                android:textSize="16sp" />
        </LinearLayout>
</LinearLayout>

* Adapter 에 어울리는 데이터 형식도 만들어야겠죠? (FoodData.kt)

package com.example.forsukquiestion

data class FoodData(// 먹을거!
    var name : String,
    var typeFood : String, // 한식
    var typeMeal  : String // 밥면
)

* Adapter 에 데이터를 넣어 어떻게 화면에 보이게 할껀지 설정해야겠죠? (TotalRecycleAdapter.kt)

package com.example.forsukquiestion

import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import java.lang.reflect.Type
import java.util.jar.Attributes.Name


class TotalRecycleAdapter(private val dataSet: Array<FoodData>): RecyclerView.Adapter<TotalRecycleAdapter.ViewHolder>(){
    /**
     * Provide a reference to the type of views that you are using
     * (custom ViewHolder).
     */


    class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
        private val nameLbl :TextView
        private val foodLbl : TextView
        private val mealLbl : TextView

        init {
            // Define click listener for the ViewHolder's View.
            nameLbl = view.findViewById(R.id.nameView)
            foodLbl = view.findViewById(R.id.typeView)
            mealLbl = view.findViewById(R.id.mealView)
        }
        fun  bind(item : FoodData){//이렇게 만들어주시면 됩니다.
            nameLbl.text = item.name
            foodLbl.text = item.typeFood
            mealLbl.text = item.typeMeal
        }
    }

    // Create new views (invoked by the layout manager)
    override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): ViewHolder {
        // Create a new view, which defines the UI of the list item
        val view = LayoutInflater.from(viewGroup.context)
            .inflate(R.layout.total_recycle_adapter, viewGroup, false)

        return ViewHolder(view)
    }

    // Replace the contents of a view (invoked by the layout manager)
    override fun onBindViewHolder(viewHolder: ViewHolder, position: Int) {

        // Get element from your dataset at this position and replace the
        // contents of the view with that element
        viewHolder.bind(dataSet[position])

    }

    // Return the size of your dataset (invoked by the layout manager)
    override fun getItemCount() = dataSet.size
}

여기까지 만들었으면 이제 화면만 만들면 됩니다.

 

2단계 보여줄 전체 View 만들기

* 전체 화면 구성 (activity_total.xml) 

- 저는 화면이 심심한 것 같아서 귀여운 이미지를 추가했습니다. 

이런 식으로 설정했습니다.

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/mushroom_green">

    <ImageView
        android:id="@+id/imageView"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:layout_marginBottom="10dp"
        android:contentDescription="@string/icon_burger"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:srcCompat="@drawable/burger" />

    <androidx.recyclerview.widget.RecyclerView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginBottom="10dp"
        app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
        android:orientation="vertical"
        android:id="@+id/totalMenuList"
        app:layout_constraintBottom_toBottomOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

* 전체 화면 코드 구성 (TotalActivity.kt)

- 전체 코드를 보여드리고 부분적으로 잘라서 설명드릴께요.

package com.example.forsukquiestion

import android.os.Bundle
import android.os.PersistableBundle
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.RecyclerView
import org.json.JSONArray

class TotalActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_total)

        setDataList()

    }
    fun setDataList(){
        val recycleUI = findViewById<RecyclerView>(R.id.totalMenuList)
        recycleUI.adapter = TotalRecycleAdapter(getMenuList())

    }

    fun getMenuList() : Array<FoodData>{

        var resultArr = emptyArray<FoodData>()
        val jsonName = assets.open("LunchMenu.json").reader().readText()
        val lunchArray = JSONArray(jsonName)
        val lunchPick = lunchArray.getJSONObject(0)

        for (index in 0 until lunchArray.length()){
            val lunchPick = lunchArray.getJSONObject(index)
            val name = lunchPick.getString("Name")
            val kind = getMealOfFood( lunchPick.getString("Kind"))
            val type = getTypeOfFood( lunchPick.getString("Type"))
            var makeFood = FoodData(name = name, typeFood = kind, typeMeal = type)
            resultArr = resultArr.plus( makeFood)
        }

        return  resultArr
    }
    fun getTypeOfFood(word : String) : String{// 밥면빵
        return when( word ){
            "r" -> "밥류"
            "n" -> "면류"
            else -> "기타"
        }
    }
    fun  getMealOfFood(word: String) : String{// 한식
        return when( word ){
            "k" -> "한식"
            "j" -> "일식"
            "c" -> "중식"
            else -> "양식 / 동남아"
        }
    }
}

중요한 부분만 따로 잘라서 설명드릴께요. 

 

1. JSON 가져오기 

- 이전 포스트 1단계에서 미리 만들었던 json 파일을 기억하시나요? 

- 저는 그 파일에 있는 값을 가져와 보여주는 방법을 선택했고 해당 부분이 아래 부분입니다. 

fun getMenuList() : Array<FoodData>{

    var resultArr = emptyArray<FoodData>()
    val jsonName = assets.open("LunchMenu.json").reader().readText()
    val lunchArray = JSONArray(jsonName)// JSON 배열로 가져오기 

    //아래 부분에서 Json을 FoodData 로 바꿔서 배열 만들기
    for (index in 0 until lunchArray.length()){
        val lunchPick = lunchArray.getJSONObject(index)
        val name = lunchPick.getString("Name")
        val kind = getMealOfFood( lunchPick.getString("Kind"))
        val type = getTypeOfFood( lunchPick.getString("Type"))
        var makeFood = FoodData(name = name, typeFood = kind, typeMeal = type)
        resultArr = resultArr.plus( makeFood)
    }

    return  resultArr // 만든 배열 출력
}

2. RecyclerView 설정하기 

- 위에서 필요한 데이터를 가공했다면 이제 화면에 보여줘야겠죠?

- Adapter 에 데이터를 넣고 설정만 해주시면 간단하게 바로 보이게 됩니다. 

fun setDataList(){
    val recycleUI = findViewById<RecyclerView>(R.id.totalMenuList)
    recycleUI.adapter = TotalRecycleAdapter(getMenuList())// 데이터 넣기
}

 

 

* 최종 (여기까지 하셨으면 아래처럼 보이게 됩니다.)

 

짜잔!

 

이제 어려운 부분은 다 끝났습니다. 

 

3단계에서는 

진짜 메뉴 추천을 해주는 화면을 만들어 봅시다. 

 

그럼 다음 단계에서 만나요~

댓글