반응형

앞선 실습인 "ViewPager2(뷰페이저 2) 실습#1"에 이어서 화면 상단에 Tab Layout(Bar)를 추가해서 탭바로도 이동할 수 있도록 하고, "One" 첫 페이지에 간단히 텍스트 에디트(Text Edit) 기능을 넣어서 간단히 다루어 볼게요.  보통은 Tab Layout과 뷰페이저2을 함께 연결하여 서로 간 스크롤(연동)이 가능하도록 사용하는 것이 일반적이에요.

 

먼저 앞선 실습#1게시글을 참고해 주세요.

[App개발/Android_Studio] - 【AndroidStudio】 ViewPager2(뷰페이저2) 실습 #1

1. 먼저 activity_main.xml 파일에 아래와 같이 ViewPager2위에 TabLayout을 추가해 주세요.(연동하기)

<code>

<?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:id="@+id/main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <com.google.android.material.tabs.TabLayout
        android:id="@+id/tab_layout"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_marginTop="24dp"
        android:background="#E8EDA7"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.0"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        tools:ignore="SpeakableTextPresentCheck" />

    <androidx.viewpager2.widget.ViewPager2
        android:id="@+id/pager"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/tab_layout" />

</androidx.constraintlayout.widget.ConstraintLayout>

다음, MainActivity.kt 에 아래와 같은 코드를 추가해 볼게요.

TabLayoutMediator(binding.tabLayout, binding.pager) { tab, position ->
    tab.text = when(position) {
        0 -> "Home"
        1 -> "Profile"
        else -> "Details"
    }
}.attach()

<MainActivity.kt 의 전체 code>

package com.example.viewpager2_fragment
import android.os.Bundle
import androidx.activity.enableEdgeToEdge
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment
import com.example.viewpager2_fragment.databinding.ActivityMainBinding
import com.google.android.material.tabs.TabLayoutMediator

class MainActivity : AppCompatActivity() {
    private lateinit var binding: ActivityMainBinding
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        enableEdgeToEdge()
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)
        val fragments : List<Fragment> = listOf(
            FragmentOne(),
            FragmentTwo(),
            FragmentThree()
        )
        val adapter = MyFragmentAdapter(fragments, supportFragmentManager, lifecycle)
        binding.pager.adapter = adapter

//        TabLayoutMediator(binding.tabLayout, binding.pager) { tab, position ->
//            tab.text = "Tab $position"
//        }.attach()
        TabLayoutMediator(binding.tabLayout, binding.pager) { tab, position ->
            tab.text = when(position) {
                0 -> "Home"
                1 -> "Profile"
                else -> "Details"
            }
        }.attach()
    }
}

여기까지만 하면 Tab Layout과 연동이 될 거예요.
<TabLayou 연동결과>

 

2. fragment_one.xml 에 아래와 같이 "EditText"와 "Button"을 추가해 주세요.

<code>

<?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:id="@+id/frameLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#8B71C3"
    tools:context=".FragmentOne">
    <TextView
        android:id="@+id/tv_one"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="148dp"
        android:text="One"
        android:textAlignment="center"
        android:textColor="@color/white"
        android:textSize="34sp"
        android:textStyle="bold"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
    <EditText
        android:id="@+id/et"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="72dp"
        android:ems="10"
        android:hint="enter your name"
        android:inputType="text"
        android:padding="16dp"
        app:layout_constraintBottom_toTopOf="@+id/btn1"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.497"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/tv_one"
        app:layout_constraintVertical_bias="0.279" />
    <Button
        android:id="@+id/btn1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="152dp"
        android:text="Change Title"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

그럼, 추가된 버튼을 클릭하면 EditText에 입력된 내용이 TextView에 업데이트되도록  FragmentOne.kt 에 아래처럼 코드를 추가해 볼게요.

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)

    binding.btn1.setOnClickListener {
        binding.tvOne.text = binding.et.text
    }
}

< FragmentOne.kt 전체 code>

package com.example.viewpager2_fragment
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.example.viewpager2_fragment.databinding.FragmentOneBinding

class FragmentOne : Fragment() {

    private var _binding : FragmentOneBinding? = null
    private val binding get() = _binding!!

//        override fun onCreate(savedInstanceState: Bundle?) {
//        super.onCreate(savedInstanceState)
//    }
    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        _binding = FragmentOneBinding.inflate(inflater,container,false)
        return _binding?.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        binding.btn1.setOnClickListener {
            binding.tvOne.text = binding.et.text
        }
    }

    override fun onDestroyView() {
        super.onDestroyView()
        _binding = null
    }
}


이렇게까지만 해주면 EditText에 입력한 내용이 Button을 클릭하면 TextView에 적용이(업데이트) 됩니다. 

 

그리고 뷰페이저2와 TabLayout이 연동이 되어 작동되기 때문에, 손가락으로 화면을 좌우로 스와이프 하거나 TabLayer의 각각의 탭을 터치하면 동일하게 화면 전환 되는 것을 볼 수 있어요. 

그럼, 실제 동작되는 모습을 아래 영상으로 확인해 보세요.

 

 이번 시간에는 지난 시간에 이어 뷰페이저2에 TabLayout을 연동해 보고, EditText를 이용해 타이틀을 변경해 보는 기능에 대해 살펴보았습니다.  그럼 오늘 하루도 좋은 하루 보내세요~  

반응형

【AndroidStudio】 ViewPager2(뷰페이저2) 실습 #1

App개발/Android_Studio 2024. 11. 17. 17:44 Posted by 엑소더스팩토리
반응형

 안드로이드 스튜디오에서(with코틀린) 앱을 만들 때, 가장 많이 사용되는 기능 중 하나인 ViewPager2(뷰페이저 2) 사용법에 대해 다루어 볼게요. 

뷰페이저란? 
앱을 사용할 때 손가락으로 화면을 넘길 때 한 화면에서 다른 화면으로 넘어가며 보여주는 기능을 사용하려 할 때 사용되는 기능을 말해요.


1. New Project → Empty Views Activity를 선택하고  Title을 정해주세요.  여기서는 ViewPager2_fragment 라고 하였습니다. (페이지 구성을 fragment로 간단히 3개의 페이지로 구성해 볼게요)

이번 실습의 구현 결과는 아래와 같습니다.


프로젝트 구성은 아래와 같습니다.

 처음, 프로젝트를 생성하고서, 비어있는 Fragment 페이지 3개을 아래처럼 만들어주세요.
res >> layout 폴더에서 마우스 우클릭(RMB) 하거나,  app>>kotlin+java  폴더에서 RMB 한 다음, 

우선, FragmentOne으로 이름을 적으면, 그 아래 Layout 이름도 자동으로 네이밍 되면서 Layout File도 자동으로 생성됩니다.

이런 식으로, FragmentOne, FragmentTwo, FragmentThree 이렇게 3개의 파일을 생성해 주세요.
그럼 아래처럼 각각 3개씩의 .Xml 파일과 클래서(.kt) 생성되어 있을 거예요.

 

우선, binding 기능을 사용하기 위해서 와래와 같이 바인딩 기능을 설정해 주세요.

 viewBinding 사용법

① build.gradle.kts (Module:app) 파일을 클릭하여 android {  ...  }  항목 속에 아래코드를 추가해 주세요.

viewBinding.isEnabled = true

android {
    namespace = "com.example.resourcetest"
    compileSdk = 34
    viewBinding.isEnabled = true
    defaultConfig {
        applicationId = "com.example.resourcetest"
        minSdk = 24
        targetSdk = 34
        versionCode = 1
        versionName = "1.0"

        testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
    }

코드 추가 후 상단에 보이는 Sync Now를 클릭하여 적용시켜 주세요.(아래)

 

2. activity_main.xml 작성하기

아래와 같이 viewpager2 기능을 삽입하고 id는 "pager"라고 입력해 주세요.

 

3. fragment_one.xml 과 fragment_two.xml , fragment_three.xml 파일 작성하기
아래처럼 적당한 색상과 배경으로 3개의 파일의 id를 서로 다르게 하여 작성해 주세요.
(단, 이번 실습에서는, FrgmentOne~Three.kt 클래스 파일의 내용은 사용하지 않기 때문에 자동 생성된 형태 그대로 두세요)
① fragment_one.xml

<code>

<?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:id="@+id/frameLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#8B71C3"
    tools:context=".FragmentOne">

    <TextView
        android:id="@+id/tv_one"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="One"
        android:textAlignment="center"
        android:textColor="@color/white"
        android:textSize="34sp"
        android:textStyle="bold"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.5" />

</androidx.constraintlayout.widget.ConstraintLayout>

 

② fragment_two.xml

<code>

<?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:id="@+id/frameLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#4E8138"
    tools:context=".FragmentTwo">

    <!-- TODO: Update blank fragment layout -->
    <TextView
        android:id="@+id/tv_two"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Two"
        android:textSize="34sp"
        android:textStyle="bold"
        android:textAlignment="center"
        android:textColor="@color/white"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.5" />

</androidx.constraintlayout.widget.ConstraintLayout>

 

③ fragment_three.xml

<code>

<?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:id="@+id/frameLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#B46C01"
    tools:context=".FragmentThree">

    <!-- TODO: Update blank fragment layout -->
    <TextView
        android:id="@+id/tv_three"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Three"
        android:textSize="34sp"
        android:textStyle="bold"
        android:textAlignment="center"
        android:textColor="@color/white"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.5" />

</androidx.constraintlayout.widget.ConstraintLayout>

 

4. MyFragmentAdapter.kt 파일 작성하기
아래와 같은 이름으로 어댑터 클래스를 하나 만들고 내용을 입력해 주세요.

MyFragmentAdapter.kt 파일의 <code>

package com.example.viewpager2_fragment

import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
import androidx.lifecycle.Lifecycle
import androidx.viewpager2.adapter.FragmentStateAdapter

class MyFragmentAdapter(
    val fragments: List<Fragment>,
    fragmentManager: FragmentManager, lifecycle: Lifecycle): FragmentStateAdapter( fragmentManager, lifecycle
) {
    override fun getItemCount(): Int {
        return fragments.size
    }

    override fun createFragment(position: Int): Fragment {
        return fragments[position]
    }
}

 

5. MainActivity.kt 파일 작성하기
아래와 같은 코드로 MainActivity.kt 파일을 완성해 주세요.

package com.example.viewpager2_fragment

import android.os.Bundle
import androidx.activity.enableEdgeToEdge
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment
import com.example.viewpager2_fragment.databinding.ActivityMainBinding

class MainActivity : AppCompatActivity() {
    private lateinit var binding: ActivityMainBinding
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        enableEdgeToEdge()
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)

        val fragments : List<Fragment> = listOf(
            FragmentOne(),
            FragmentTwo(),
            FragmentThree()
        )
        val adapter = MyFragmentAdapter(fragments, supportFragmentManager, lifecycle)

        binding.pager.adapter = adapter
    }
}

 

6. 실행 결과 보기
여기까지 작성하고 에러가 나지 않는 다면, 실행해 보면 아래와 같은 결과를 보실 수 있습니다. 

 

<실행 영상>

 

그럼, 다음 시간에 이번 실습에 이어서 기능을 더 추가해 보도록 할게요.

감사합니다. 좋은 하루 되세요.

 

반응형
반응형

이번 시간에도 안드로이드 스튜디오에서(with코틀린) 가장 많이 활용되는 기능 중 하나인 RecyclerView를 연습해 볼 텐데요, 여기에 Card View 기능을 활용해 보려고 합니다.


1. New Project → Empty Views Activity를 선택하고  Title을 정해주세요.  여기서는 RecycleView4 라고 하였습니다.

프로젝트의 구성은 아래와 같습니다. 

실행결과는 아래와 같아요.

 

화면을 위아래로 스크롤 해서 여러 가지 메뉴를 보여주도록 했는데요, View를 재활용 보여줄 때 "Card View" 기능을 사용해서 보여주면 좀 더 입체적으로 보여줄 수 있어서 잘 활용하면 좋습니다.

1. activity_main.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"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/tv_title"
        android:layout_width="wrap_content"
        android:layout_height="0dp"
        android:layout_marginTop="32dp"
        android:text="Korean Delicious Food"
        android:textColor="#FF5722"
        android:textSize="20dp"
        android:textStyle="bold"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/rv_recyclerView"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_marginStart="8dp"
        android:layout_marginTop="16dp"
        android:layout_marginEnd="8dp"
        android:layout_marginBottom="8dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/tv_title"
         />
</androidx.constraintlayout.widget.ConstraintLayout>

 

2.  food_item.xml  작성하기

아래를 참고해서 레이아웃에서 cardview를 끌어다 놓고 작성을 해 주세요.

<코드>

<?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="wrap_content"
    android:orientation="vertical">
    <androidx.cardview.widget.CardView
        android:id="@+id/cardView"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginHorizontal="10dp"
        android:layout_marginVertical="6dp"
        android:layout_marginStart="10dp"
        android:layout_marginTop="8dp"
        android:layout_marginEnd="10dp"
        app:cardCornerRadius="20dp"
        app:cardElevation="8dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">
        <androidx.constraintlayout.widget.ConstraintLayout
            android:id="@+id/constraintLayout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
            <ImageView
                android:id="@+id/iV_foodImage"
                android:layout_width="100dp"
                android:layout_height="100dp"
                android:scaleType="fitXY"
                android:src="@drawable/bibimbab_01"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toTopOf="parent" />
            <TextView
                android:id="@+id/tv_foodName"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Bibimbap\n(비빔밥)"
                android:textAlignment="center"
                android:textSize="25dp"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintHorizontal_bias="0.52"
                app:layout_constraintStart_toEndOf="@+id/iV_foodImage"
                app:layout_constraintTop_toTopOf="parent" />
        </androidx.constraintlayout.widget.ConstraintLayout>
    </androidx.cardview.widget.CardView>

</androidx.constraintlayout.widget.ConstraintLayout>

 

3.  Food.kt  클래스 작성하기

<코드>

package com.example.recyclerview4

import android.os.Parcel
import android.os.Parcelable

data class Food(val image:Int, val name:String) : Parcelable {
    constructor(parcel: Parcel) : this(parcel.readInt(), parcel.readString()!!) {
    }
    override fun describeContents(): Int {
        return 0
    }
    override fun writeToParcel(parcel: Parcel, flags: Int) {
        parcel.writeInt(image)
        parcel.writeString(name)
    }
    companion object CREATOR : Parcelable.Creator<Food> {
        override fun createFromParcel(parcel: Parcel): Food {
            return Food(parcel)
        }
        override fun newArray(size: Int): Array<Food?> {
            return arrayOfNulls(size)
        }
    }
}

 

4.  FoodAdapter.kt  작성하기

아래를 참고해 Food Adapter를 만들어 줍니다.

<코드>

package com.example.recyclerview4

import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.AdapterView.OnItemClickListener
import android.widget.ImageView
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView

class FoodAdapter(private val foodList:ArrayList<Food>)
    : RecyclerView.Adapter<FoodAdapter.FoodViewHolder>() {
        var onItemClick : ((Food) -> Unit)? = null

        class FoodViewHolder(itemView:View) : RecyclerView.ViewHolder(itemView) {
            val imageView : ImageView = itemView.findViewById(R.id.iV_foodImage)
            val textView : TextView = itemView.findViewById(R.id.tv_foodName)
        }
        override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): FoodViewHolder {
            val view = LayoutInflater.from(parent.context).inflate(R.layout.food_item, parent, false)
            return FoodViewHolder(view)
        }
        override fun getItemCount(): Int {
            return foodList.size
        }
        override fun onBindViewHolder(holder: FoodViewHolder, position: Int) {
            val food = foodList[position]
            holder.imageView.setImageResource(food.image)
            holder.textView.text = food.name
            holder.itemView.setOnClickListener {
                onItemClick?.invoke(food)
            }
        }
}

 

5.  MainActivity.kt  작성하기

아래를 참고해 Main Activity를 만들어 줍니다.
먼저 binding 기능을 사용하기 위해, build.gradle.kts(Module:app) 그래들 설정에 아래처럼 바인딩 기능 사용을 추가해 주세요.

viewBinding.isEnabled = true

 

<코드>

package com.example.recyclerview4

import android.content.Intent
import android.os.Bundle
import androidx.activity.enableEdgeToEdge
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.example.recyclerview4.databinding.ActivityMainBinding

class MainActivity : AppCompatActivity() {
    private lateinit var recyclerView: RecyclerView
    private lateinit var foodList: ArrayList<Food>
    private lateinit var foodAdapter: FoodAdapter
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        enableEdgeToEdge()
        val binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)
        recyclerView = binding.rvRecyclerView
        recyclerView.setHasFixedSize(true)
        recyclerView.layoutManager = LinearLayoutManager(this)
        foodList = ArrayList()
        foodList.add(Food(R.drawable.bibimbab_01, "Bi-bim-bap\n(비빔밥)"))
        foodList.add(Food(R.drawable.samgyeopsal_02, "Sam-gyeop-sal\n(삼겹살)"))
        foodList.add(Food(R.drawable.galbitang_03, "Gal-bi-tang\n(갈비탕)"))
        foodList.add(Food(R.drawable.tteokguk_04, "tteok-guk\n(떡국)"))
        foodList.add(Food(R.drawable.tteokbokki_05, "tteok-bok-kki\n(떡볶이)"))
        foodList.add(Food(R.drawable.sundubujjigae_06, "Sun-dubu-jjigae\n(순두부 찌개)"))
        foodList.add(Food(R.drawable.koreanfc_07, "Korean-Fried-Chicken\n(한국식 프라이 치킨)"))
        foodList.add(Food(R.drawable.naengmyeon_09, "naeng-myeon\n(냉면)"))
        foodList.add(Food(R.drawable.doenjangjjigae_10, "Doen-jang-jjigae\n(된장찌개)"))
        foodList.add(Food(R.drawable.bulgogi_11, "Bul-go-gi\n(불고기)"))
        foodList.add(Food(R.drawable.kimchijeon_12, "Kimchi-jeon\n(김치전)"))
        foodAdapter = FoodAdapter(foodList)
        recyclerView.adapter = foodAdapter
    }
}

 

여기까지만 하면 기본적으로 RecyclerView 기능을 사용해서 보여줄 수 있게 되는데요, 
여기서 한 가지 기능을 더 추가해 볼게요,  화면을 스크롤하면서 원하는 음식(이미지)카드를 터치하면, 해당 음식에 대해 디테일하게 정보를 보여주는 View를 추가해 볼게요. 

6.  activity_detailed.xml  작성하기 

아래를 참고해 Main Activity를 만들어 줍니다.

res >> layout 폴더에서 마우스 우클릭 해서 New >> Activity >> Empty Views Activity를 클릭합니다. 

아래처럼 Activity Name에  "DetailedActivity" 를 입력하면 "DetailedActivity.kt"파일과 함께  그 아래에 activity_detailed.xml 파일도 함께 자동 생성됩니다. 

 

7.  activity_detailed  작성하기 

아래처럼 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"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".DetailedActivity">

    <ImageView
        android:id="@+id/iv_Detailed"
        android:layout_width="0dp"
        android:layout_height="250dp"
        android:scaleType="fitXY"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:srcCompat="@drawable/bibimbab_01" />

    <TextView
        android:id="@+id/tv_Detailed"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="173dp"
        android:layout_marginEnd="180dp"
        android:gravity="center"
        android:text="TextView"
        android:textSize="24sp"
        android:textStyle="bold"
        android:textColor="@color/black"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/iv_Detailed" />
</androidx.constraintlayout.widget.ConstraintLayout>

8.  DetailedActivity.kt  작성하기 

아래처럼 코드를 작성해 주세요. (binding 기능으로 사용하였고 기존 기능은 주석처리해 놓았으니 비교해 보세요)

package com.example.recyclerview4

import android.os.Bundle
import android.view.LayoutInflater
import android.widget.ImageView
import android.widget.TextView
import androidx.activity.enableEdgeToEdge
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import com.example.recyclerview4.databinding.ActivityDetailedBinding

class DetailedActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        enableEdgeToEdge()
        val binding = ActivityDetailedBinding.inflate(layoutInflater)
//        setContentView(R.layout.activity_detailed)
        setContentView(binding.root)
        val food = intent.getParcelableExtra<Food>("food")
        if (food != null) {
//            val textView : TextView = findViewById(R.id.tv_Detailed)
//            val imageView : ImageView = findViewById(R.id.iv_Detailed)
            binding.tvDetailed.text = food.name
            binding.ivDetailed.setImageResource(food.image)
        }
    }
}

마지막으로 MainActivity.kt 코드 끝에 아래와 같은 코드를 추가해 주세요. 

foodAdapter.onItemClick = {
    val intent = Intent(this, DetailedActivity::class.java)
    intent.putExtra("food",it)
    startActivity(intent)
}

MainActivity.kt 의 전체 완성된 코드는 아래와 같아요.

package com.example.recyclerview4

import android.content.Intent
import android.os.Bundle
import androidx.activity.enableEdgeToEdge
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.example.recyclerview4.databinding.ActivityMainBinding
class MainActivity : AppCompatActivity() {
    private lateinit var recyclerView: RecyclerView
    private lateinit var foodList: ArrayList<Food>
    private lateinit var foodAdapter: FoodAdapter
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        enableEdgeToEdge()
        val binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)
        recyclerView = binding.rvRecyclerView
        recyclerView.setHasFixedSize(true)
        recyclerView.layoutManager = LinearLayoutManager(this)
        foodList = ArrayList()
        foodList.add(Food(R.drawable.bibimbab_01, "Bi-bim-bap\n(비빔밥)"))
        foodList.add(Food(R.drawable.samgyeopsal_02, "Sam-gyeop-sal\n(삼겹살)"))
        foodList.add(Food(R.drawable.galbitang_03, "Gal-bi-tang\n(갈비탕)"))
        foodList.add(Food(R.drawable.tteokguk_04, "tteok-guk\n(떡국)"))
        foodList.add(Food(R.drawable.tteokbokki_05, "tteok-bok-kki\n(떡볶이)"))
        foodList.add(Food(R.drawable.sundubujjigae_06, "Sun-dubu-jjigae\n(순두부 찌개)"))
        foodList.add(Food(R.drawable.koreanfc_07, "Korean-Fried-Chicken\n(한국식 프라이 치킨)"))
        foodList.add(Food(R.drawable.naengmyeon_09, "naeng-myeon\n(냉면)"))
        foodList.add(Food(R.drawable.doenjangjjigae_10, "Doen-jang-jjigae\n(된장찌개)"))
        foodList.add(Food(R.drawable.bulgogi_11, "Bul-go-gi\n(불고기)"))
        foodList.add(Food(R.drawable.kimchijeon_12, "Kimchi-jeon\n(김치전)"))
        foodAdapter = FoodAdapter(foodList)
        recyclerView.adapter = foodAdapter
        foodAdapter.onItemClick = {
            val intent = Intent(this, DetailedActivity::class.java)
            intent.putExtra("food",it)
            startActivity(intent)
        }
    }
}

그럼, 앱을 실행하고 원하는 음식 이미지를 터치하면, 아래처럼 디테일 뷰를 볼 수 있습니다. 
아래 이미지에서 갈비탕 이미지를 터치하면, 상세 페이지를 볼 수 있으며, 실제로 추가적인 내용을 넣어 주면 됩니다.

 

이상으로 RecyclerView를 사용하면서 CardView 기능을 활용해 보는 시간을 가져봤습니다.

그럼, 오늘도 즐거운 하루 되세요~

반응형