ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Android] [당근마켓 클론 코딩] 메인페이지 구현1 (RecyclerView/ addItemDecoration()/ Spinner/ ArrayAdapter)
    안드로이드 2024. 4. 16. 21:06

    ✏️ TIL(Today I Learned)

    당근마켓을 조금 간소화해서 구현했다.

     

    activity_main.xml은 아래와 같이 constraintlayout으로 만들었다.

    상단에는 Spinner와 Notification을 생성할 수 있는 종모양의 이미지뷰를 넣었다.

    그 아래로는 RecyclerView로 구성했다.

    <?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"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">
    
        <Spinner
            android:id="@+id/spinner_location"
            android:layout_width="wrap_content"
            android:layout_height="@dimen/spinner_height"
            android:layout_marginStart="@dimen/default_margin"
            android:spinnerMode="dropdown"
            style="@style/item.Head.M.Bold"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintStart_toStartOf="parent" />
    
        <ImageView
            android:id="@+id/iv_notification"
            android:layout_width="@dimen/icon_image_size"
            android:layout_height="@dimen/icon_image_size"
            android:layout_margin="@dimen/default_margin"
            android:background="@drawable/ic_notification"
            app:layout_constraintBottom_toBottomOf="@+id/spinner_location"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintTop_toTopOf="@+id/spinner_location" />
    
        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/recyclerView"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_marginTop="@dimen/spinner_height"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/spinner_location" />
    
        <com.google.android.material.floatingactionbutton.FloatingActionButton
            android:id="@+id/floatingButton"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginEnd="@dimen/floatingButton_margin"
            android:layout_marginBottom="@dimen/floatingButton_margin"
            android:clickable="true"
            android:visibility="invisible"
            android:src="@drawable/ic_arrow_up"
            android:adjustViewBounds="true"
            style="@style/floatingButton"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent" />
    
    </androidx.constraintlayout.widget.ConstraintLayout>

     

    스크롤을 최상단으로 이동시키는 FloatingActionButton도 만들었다.

    우선 invisible로 해두고, 스크롤이 거의 마지막에 왔을 때, visible 하도록 바꿔서 클릭 시 상단으로 이동한다.

     

     

    아이템 사이에 회색줄은 MainActivity.kt 에서 만들었다.

    // 아이템들 사이에 회색 라인을 추가
    binding.recyclerView.addItemDecoration(
        DividerItemDecoration(this, LinearLayoutManager.VERTICAL)
    )

     

     

    Spinner의 경우,

    선택된 항목인 경우 텍스트를 볼드체로 설정하는 CustomArrayAdapter를 만들어서 연결해줬다.

    class CustomArrayAdapter(context: Context, private val items: Array<String>) :
        ArrayAdapter<String>(context, R.layout.custom_spinner, items) {
    
        override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
            val view = super.getView(position, convertView, parent)
            val textView = view.findViewById<TextView>(R.id.textView)
    
            if (position == (parent as Spinner).selectedItemPosition) {
                textView.setTypeface(null, Typeface.BOLD)
            } else {
                textView.setTypeface(null, Typeface.NORMAL)
            }
    
            return view
        }
    }

     

    custom_spinner.xml을 만들어서 항목의 텍스트 스타일을 적용했다.

    // custom_spinner.xml
    
    <TextView xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/textView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        style="@style/item.Head.S" />
    // MainActivity.kt
    
    private fun setSpinner() {
    	binding.spinnerLocation.apply {
            val arrayAdapter = CustomArrayAdapter(
                this@MainActivity,
                locationList
            )
            arrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
            adapter = arrayAdapter
    
            setSelection(2)
            onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
                override fun onItemSelected(parent: AdapterView<*>, view: View?, position: Int, id: Long) {
                    setSelection(position)
                }
                override fun onNothingSelected(parent: AdapterView<*>) {
                }
            }
        }
    }

     

     


     

    📝 공부한 Kotlin 정리

    addItemDecoration() 메소드

    RecyclerView의 각 항목 사이에 분할선을 추가하기 위해 사용된다.

    이 메소드는 RecyclerView에 분할선을 그리는 데 필요한 ItemDecoration 객체를 추가한다.

    DividerItemDecoration은 안드로이드 프레임워크에서 제공하는 기본적인 ItemDecoration 구현 클래스 중 하나이다.

    이 클래스는 항목 사이에 수직으로 또는 수평으로 분할선을 추가하는 데 사용된다.

    // RecyclerView 가져오기
    val recyclerView: RecyclerView = findViewById(R.id.recyclerView)
    
    // LinearLayoutManager 설정
    recyclerView.layoutManager = LinearLayoutManager(this)
    
    // DividerItemDecoration 인스턴스 생성
    val dividerItemDecoration = DividerItemDecoration(this, LinearLayoutManager.VERTICAL)
    
    // DividerItemDecoration에 분할선 Drawable 설정 (선택 사항)
    val divider: Drawable? = ContextCompat.getDrawable(this, R.drawable.divider)
    divider?.let {
        dividerItemDecoration.setDrawable(it)
    }
    
    // RecyclerView에 DividerItemDecoration 추가
    recyclerView.addItemDecoration(dividerItemDecoration)
    
    // RecyclerView 어댑터 설정
    recyclerView.adapter = MyAdapter(getData())

     

    ArrayAdapter

    하나의 View에 배열이나 리스트와 같은 데이터를 연결하는 데 사용되는 어댑터이다. 주로 리스트 뷰(ListView), 스피너(Spinner), 그리드 뷰(GridView) 등과 함께 사용된다.

    • 데이터 배열이나 리스트를 받아서 각 항목을 보여주는 View로 변환한다.
    • 이러한 변환된 뷰들을 리스트나 스피너 등에 연결하여 화면에 표시한다.
    • 필요에 따라 커스텀 레이아웃을 사용하여 뷰를 생성할 수 있다.

    ArrayAdapter 생성자 매개변수

    • context: this@MainActivity와 같이 어떤 컨텍스트에서 어댑터가 사용되는지를 나타낸다.
    • resource: 스피너의 각 항목을 표시하는 데 사용되는 레이아웃 리소스이다. 
    • objects: 스피너에 표시될 항목들의 목록이다.
Designed by Tistory.