코딩하는 일용직 노동자

안드로이드 MVVM 패턴으로 작업해보기 (5) 본문

안드로이드

안드로이드 MVVM 패턴으로 작업해보기 (5)

bacass 2020. 5. 1. 17:55

#1 어댑터
리사이클러뷰에 사용할 어댑터를 만듭니다.
3열의 그리드 형태로 표시할 수 있도록 속성값을 셋팅해줍니다.

<androidx.recyclerview.widget.RecyclerView
    android:id="@+id/rcList"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingLeft="20dp"
    android:paddingRight="20dp"
    app:layoutManager="androidx.recyclerview.widget.GridLayoutManager"
    app:spanCount="3"/>


Glide 를 이용해 이미지를 표시할 수 있도록 util 패키지 아래에 imageLoader 클래스를 만들었습니다.

class ImageLoader(private val context: Context) {

    fun imageLoadWithResourceID(resID: Int, v : ImageView) {
        Glide.with(this.context).load(resID).into(v)
    }

    fun imageLoadWithURL(url: String, v: ImageView) {
        Glide.with(this.context).load(url).into(v)
    }

    fun imageLoadWithFilePath(filePath: String, v: ImageView) {
        Glide.with(this.context).load(filePath).into(v)
    }

    fun imageLoadWithFile(f: File, v: ImageView) {
        Glide.with(this.context).load(f).into(v)
    }
}


이미지는 화면에 정사각형 형태로 표시되도록 width 값을 계산해서 layoutParam 으로 처리해줍니다.

class HomeImageAdapter(private val viewModel: HomeViewModel) :
    RecyclerView.Adapter<RecyclerView.ViewHolder>(), KoinComponent {

    private val imageLoader: ImageLoader = get()

    private var item_list = mutableListOf<ImageHits>()
    private var itemWidth = 150

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {

        itemWidth = (DeviceInfo.getDeviceWidth(parent.context) - 40f.toPixel(parent.context)) / 3

        return ItemViewHolder(
            DataBindingUtil.inflate(
                LayoutInflater.from(parent.context),
                R.layout.item_home,
                parent,
                false
            )
        )
    }

    override fun getItemCount(): Int = item_list.size

    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
        when (holder) {
            is ItemViewHolder -> {
                holder.bind(item_list[position], position)
            }
        }
    }

    fun initItem(list: List<ImageHits>?) {
        list?.let {
            this.item_list.addAll(it)
            notifyDataSetChanged()
        }
    }

    inner class ItemViewHolder(private val binding: ItemHomeBinding) :
        RecyclerView.ViewHolder(binding.root) {
        fun bind(item: ImageHits, position: Int) {
            binding.data = item

            binding.llContents.layoutParams = LinearLayout.LayoutParams(itemWidth, itemWidth)

            imageLoader.imageLoadWithURL(item.largeImageURL, binding.ivContent)
        }
    }
} 


#2 아이템 레이아웃
일단 화면에 이미지만 표시할 수 있도록 간단한 레이아웃을 만듭니다.
이미지에 padding을 2dp씩 줘서 이미지 간격에 여유를 뒀습니다.

<?xml version="1.0" encoding="utf-8"?>
<layout>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/llContents"
        android:layout_width="150dp"
        android:layout_height="150dp">
    
        <ImageView
            android:id="@+id/ivContent"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:adjustViewBounds="true"
            android:padding="2dp"
            android:scaleType="centerCrop"/>
    
    </LinearLayout>

</layout>


#3 이미지 검색기능 완성
우선 최대한 간단하게 작업된 결과물을 확인해봤습니다.

완성! (^o^)/

#4 작업을 마치며...
안드로이드 MVVM 패턴은 기존의 MVP 패턴에 비해 학습비용이 많이 듭니다.
AAC를 이용해서 작업을 하기 때문에 ViewModel, DataBinding, LifeCycleLifecycleObserver, LiveData 등등 미리 알아둬야 할것이 많았습니다.
의존성주입(DI)은 다루기 어려운 Dagger2 보다 Koin을 사용하는것이 더 익숙해서 이번 프로젝트에는 Koin을 이용했습니다.
또한 편의를 위해서 kotpref, Timber, Glide 도 이용했는데 kotpref 는 따로 포스팅을 작성해보도록 하겠습니다.

작업된 프로젝트파일은 GitHub에서 확인할 수 있습니다.
https://github.com/Bacass/MyMvvmSample

 

Bacass/MyMvvmSample

My kotlin MVVM Sample . Contribute to Bacass/MyMvvmSample development by creating an account on GitHub.

github.com