Android/Side Projects

Airbnb 앱 개발하기

화요밍 2022. 2. 24. 16:28
728x90
반응형
 
Side Project - Airbnb
네이버 지도 API를 활용해서 지도 위에 숙소 정보를 보여주는 Airbnb의 간단한 기능을 구현한 프로젝트

 

 

GitHub - hwayeon351/Airbnb

Contribute to hwayeon351/Airbnb development by creating an account on GitHub.

github.com

 


학습 회고

오늘은 Mocky 사이트를 이용해서 Airbnb 앱 내에 띄울 숙소 리스트를 Json으로 구성하고 해당 Json 데이터가 담긴 url을 생성하였다.

Retrofit2 라이브러리를 이용해서 url에 담긴 데이터를 받아오고 ViewPager와 Bottom Sheet Dialog 내의 RecyclerView에 적용해주고, 네이버 맵에 마커를 띄워 숙소 위치들을 표시하였다.


오늘 공부한 내용

  • Retrofit 2 라이브러리를 사용해서 서버에서 데이터 받아오기

지도에 숙소들의 위치를 마커로 찍기 위해서는 숙소 위치 값을 위도, 경도로 받아와야 한다.

또한, 숙소를 설명하는 제목과 가격, 이미지를 Bottom Sheet Dialog와 ViewPager2에 적용하기 위해서는 숙소 정보를 받아와야 한다.

따라서, 나는 임의로 Json 형식으로 숙소 데이터를 만들고 mocky 사이트를 활용해 URL을 통해 데이터를 받아올 수 있도록 하였다.

 

임의로 생성한 데이터는 다음과 같다.

이 데이터들이 담긴 URL을 통해 5개의 숙소 정보를 받아와 Airbnb 앱에 적용하였다.

{
    "items": [
        {
            "id" : 1,
            "title" : "강남역!! 최저가!! 레지던스!!",
            "price" : "23,000원",
            "lat" : 37.496058,
            "lng" : 127.020512,
            "imgUrl": "https://picsum.photos/200/200"
        },
        {
            "id" : 2,
            "title" : "강남역!! 위치 초 근접",
            "price" : "58,900원",
            "lat" : 37.494815,
            "lng" : 127.022905,
            "imgUrl": "https://picsum.photos/200/200"
        },
        {
            "id" : 3,
            "title" : "집 전체, 강남역 초근점, 강남의 야경",
            "price" : "109,755원",
            "lat" : 37.493215,
            "lng" : 127.028264,
            "imgUrl": "https://picsum.photos/200/200"
        },
        {
            "id" : 4,
            "title" : "아파트 전체, 동대문시장 특별한 추억, 빔프로젝터",
            "price" : "92,433원",
            "lat" : 37.489534,
            "lng" : 127.030653,
            "imgUrl": "https://picsum.photos/200/200"
        },
        {
            "id" : 5,
            "title" : "집 전체, Luxury Vintage Flat",
            "price" : "136,433원",
            "lat" : 37.492463,
            "lng" : 127.029478,
            "imgUrl": "https://picsum.photos/200/200"
        }
    ]
}

 

  • Retrofit Service 구현하기

Retrofit을 사용하려면 3가지가 필요하다.

네트워크 통신에 필요한 함수를 포함하는 Service 인터페이스, 서버와 주고 받는 데이터를 표현하는 모델 클래스, Json 으로 구성된 데이터들이 담긴 리스트로 받아와서 정의한 모델 객체 리스트로 만들기 위해 사용될 DTO를 구성해야 한다.

 

1. Service 인터페이스

interface HouseService {
    @GET("URL_ADDRESS")
    fun getHouseList(): Call<HouseDto>
}

 

2. 모델 클래스

data class HouseModel(
    val id: Int,
    val title: String,
    val price: String,
    val imgUrl: String,
    val lat: Double,
    val lng: Double
)

 

3. DTO

data class HouseDto (
    val items: List<HouseModel>
)

 

 

  • Service 객체 생성 및 데이터 받아오기

Retrofit 객체를 Builder를 통해 먼저 생성한 후, create() 메서드를 통해 Service 객체를 생성한다.

Service 객체를 통해 인터페이스에 정의한 함수를 호출해서 숙소 리스트를 Call 객체로 받아온다.

통신에 성공하면 서버에서 넘어온 데이터가 Response 객체로 전달되고 body에서 데이터를 받아와 마커와 ViewPager, RecyclerView의 데이터를 업데이트 한다.

    private fun getHouseListFromAPI() {
        val retrofit = Retrofit.Builder()
            .baseUrl("https://run.mocky.io")
            .addConverterFactory(GsonConverterFactory.create())
            .build()

        retrofit.create(HouseService::class.java).also {
            it.getHouseList()
                .enqueue(object: Callback<HouseDto>{
                    override fun onResponse(call: Call<HouseDto>, response: Response<HouseDto>) {
                        if (response.isSuccessful.not()) {

                            return
                        }

                        response.body()?.let { dto ->
                            updateMarker(dto.items)
                            viewPagerAdapter.submitList(dto.items)
                            recyclerViewAdapter.submitList(dto.items)
                        }
                    }

                    override fun onFailure(call: Call<HouseDto>, t: Throwable) {

                    }

                })
        }
    }

 

 

 

  • Bottom Sheet Dialog 구성하기

에어비앤비 앱을 보면 하단에 00개 이상의 숙소라고 되어있고 위로 스와이프하면 숙소 정보를 볼 수 있는 Bottom Sheet Dialog가 있다.

이 Bottom Sheet을 포함하는 레이아웃의 최상단을 Coordinatorlayout으로 하고 Child View인 Bottom Sheet Dialog의 최상단 layout에 layout_behavior 속성을 지정해서 구현할 수 있다.

<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <com.naver.maps.map.MapView
        android:id="@+id/mapView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginBottom="80dp"/>

    <androidx.viewpager2.widget.ViewPager2
        android:id="@+id/houseViewPager"
        android:layout_width="match_parent"
        android:layout_height="100dp"
        android:layout_gravity="bottom"
        android:layout_marginBottom="120dp"
        android:orientation="horizontal" />

    <com.naver.maps.map.widget.LocationButtonView
        android:id="@+id/currentLocationButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="top|start"
        android:layout_margin="12dp"/>

    <include layout="@layout/bottom_sheet" />

</androidx.coordinatorlayout.widget.CoordinatorLayout>
<?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="@drawable/top_radius_white_background"
    app:behavior_peekHeight="100dp"
    app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior">

    <View
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        android:background="#cccccc"
        android:layout_marginTop="12dp"
        android:layout_width="30dp"
        android:layout_height="3dp"/>

    <TextView
        android:id="@+id/bottomSheetTitleTextView"
        android:layout_width="0dp"
        android:layout_height="100dp"
        android:gravity="center"
        android:text="여러 개의 숙소"
        android:textColor="@color/black"
        android:textSize="15sp"
        android:textStyle="bold"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <View
        android:id="@+id/lineView"
        android:layout_width="0dp"
        android:layout_height="1dp"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toBottomOf="@id/bottomSheetTitleTextView"
        android:background="#cccccc"/>

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recyclerView"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@id/lineView" />

</androidx.constraintlayout.widget.ConstraintLayout>

Bottom Sheet Dialog의 레이아웃을 만들어 독립된 xml로 만들어 준 후에 Bottom Sheet Dialog를 포함하는 레이아웃에 include 해주었다.

즉, 디바이스 화면에서는 Bottom Sheet Dialog의 전체 화면이 가려져 있다가 사용자가 위로 스와이프할 경우에 가려져있는 뷰가 보이게 되는 원리이다.

 

Airbnb 앱에서는 Bottom Sheet Dialog를 통해 여러 숙소 정보들을 보여주기 위해서 RecyclerView를 사용하였다.

따라서, Bottom Sheet Dialog를 위로 스와이프하면 숙소 정보들이 담긴 RecyclerView를 볼 수 있다.

 

 

https://developer.android.com/reference/com/google/android/material/bottomsheet/BottomSheetBehavior

 

BottomSheetBehavior  |  Android Developers

From class androidx.coordinatorlayout.widget.CoordinatorLayout.Behavior boolean blocksInteractionBelow(CoordinatorLayout arg0, V arg1) boolean getInsetDodgeRect(CoordinatorLayout arg0, V arg1, Rect arg2) int getScrimColor(CoordinatorLayout arg0, V arg1) fl

developer.android.com

 

 

728x90
반응형

'Android > Side Projects' 카테고리의 다른 글

Airbnb 앱 개발하기  (0) 2022.02.26
Airbnb 앱 개발하기  (0) 2022.02.25
Airbnb 앱 개발하기  (0) 2022.02.23
당근마켓 앱 개발하기  (0) 2022.02.22
당근마켓 앱 개발하기  (0) 2022.02.21