728x90
https://www.geeksforgeeks.org/how-to-create-expandable-recyclerview-items-in-android-using-kotlin/
에 있는 소스를 수정/보완했다.
RecyclerView 에서 해당 항목을 누르면 세부 내용을 보였다 사라졌다 하는 기능을 구현하는 걸 Expandable RecyclerView 라고 한다.
앱 build.gradle
- 다른 코드에서 사용하기 위해 dependancies 를 더 추가했다.
plugins {
id 'com.android.application'
id 'kotlin-android'
}
android {
compileSdkVersion 30
buildToolsVersion "30.0.2"
defaultConfig {
applicationId "com.link2me.expandablerv"
minSdkVersion 22
targetSdkVersion 30
versionCode 1
versionName "1.0"
}
buildFeatures {
viewBinding true
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
}
}
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation 'androidx.core:core-ktx:1.3.2'
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'com.google.android.material:material:1.3.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
// ViewPager2
implementation 'androidx.viewpager2:viewpager2:1.0.0'
implementation 'gun0912.ted:tedpermission:2.0.0'
implementation 'androidx.cardview:cardview:1.0.0' // 레이아웃으로 사용할 CardView
implementation 'androidx.recyclerview:recyclerview:1.1.0'
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
implementation 'com.squareup.okhttp3:logging-interceptor:4.4.0'
// 이미지 출력용 Glide
implementation 'com.github.bumptech.glide:glide:4.11.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.11.0'
}
레이아웃 만들기
<?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:background="#F5F8FD"
android:layout_height="match_parent"
tools:context=".MainActivity">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:listitem="@layout/single_item"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />
</androidx.constraintlayout.widget.ConstraintLayout>
single_item.xml
<?xml version="1.0" encoding="utf-8"?>
<com.google.android.material.card.MaterialCardView 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/card_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="3dp"
android:layout_marginEnd="3dp"
android:layout_marginBottom="3dp">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="@+id/tv_main_layout"
android:layout_width="match_parent"
android:layout_height="40dp"
android:orientation="horizontal"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
tools:ignore="MissingConstraints">
<!--Text view -->
<TextView
android:id="@+id/tv_main_name"
android:layout_width="wrap_content"
android:layout_height="40dp"
android:layout_marginStart="20dp"
android:layout_marginTop="10dp"
android:text="Language"
android:textColor="@color/black"
android:textSize="20sp"
android:textStyle="bold"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<View
android:layout_width="15dp"
android:layout_height="wrap_content"
android:layout_weight="1"/>
<ImageButton
android:id="@+id/viewMoreBtn"
android:tint="#666666"
android:src="@drawable/ic_arrow_drop_down_24"
android:background="?attr/selectableItemBackgroundBorderless"
android:layout_width="?attr/actionBarSize"
android:layout_height="?attr/actionBarSize" />
</LinearLayout>
<!--"expanded_view" -->
<LinearLayout
android:id="@+id/expanded_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginTop="10dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_main_layout">
<TextView
android:id="@+id/tv_description"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:text="Description Text"
android:textSize="18sp" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</com.google.android.material.card.MaterialCardView>
MainActivity.kt
class MainActivity : AppCompatActivity() {
// https://www.geeksforgeeks.org/how-to-create-expandable-recyclerview-items-in-android-using-kotlin/ 사이트 소스를 수정
// view binding for the activity
private var _binding: ActivityMainBinding? = null
private val binding get() = _binding!!
// get reference to the adapter class
private var languageList = ArrayList<DataItem>()
private lateinit var expandableAdapter: ExpandableAdapter
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
_binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
// define layout manager for the Recycler view
binding.rvList.layoutManager = LinearLayoutManager(this)
// attach adapter to the recyclerview
expandableAdapter = ExpandableAdapter(languageList)
getData()
binding.rvList.adapter = expandableAdapter
}
private fun getData() {
// 서버에서 가져온 데이터라고 가정한다.
// create new objects and add some row data
val language1 = DataItem(
"Java",
"Java is an Object Oriented Programming language." +
" Java is used in all kind of applications like Mobile Applications (Android is Java based), " +
"desktop applications, web applications, client server applications, enterprise applications and many more. ",
false
)
val language2 = DataItem(
"Kotlin",
"Kotlin is a statically typed, general-purpose programming language" +
" developed by JetBrains, that has built world-class IDEs like IntelliJ IDEA, PhpStorm, Appcode, etc.",
false
)
val language3 = DataItem(
"Python",
"Python is a high-level, general-purpose and a very popular programming language." +
" Python programming language (latest Python 3) is being used in web development, Machine Learning applications, " +
"along with all cutting edge technology in Software Industry.",
false
)
val language4 = DataItem(
"CPP",
"C++ is a general purpose programming language and widely used now a days for " +
"competitive programming. It has imperative, object-oriented and generic programming features. ",
false
)
// add items to list
languageList.add(language1)
languageList.add(language2)
languageList.add(language3)
languageList.add(language4)
expandableAdapter.notifyDataSetChanged()
}
// on destroy of view make the binding reference to null
override fun onDestroy() {
super.onDestroy()
_binding = null
}
}
DataItem.kt
class DataItem(
val name : String ="",
val description : String= "",
var expand : Boolean = false
)
ExpandableAdapter.kt
이미지가 펼쳐졌을 때, Up/Down 화살표가 변경되는 걸 추가하고자 한다면...
if(this.expand) binding.viewMoreBtn.setImageResource(R.drawable.ic_arrow_drop_up_24) else binding.viewMoreBtn.setImageResource(R.drawable.ic_arrow_drop_down_24)
를 추가하면 된다.
class ExpandableAdapter(private var itemList: List<DataItem>) : RecyclerView.Adapter<ExpandableAdapter.ViewHolder>() {
// create an inner class with name ViewHolder
// It takes a view argument, in which pass the generated class of single_item.xml
// ie SingleItemBinding and in the RecyclerView.ViewHolder(binding.root) pass it like this
inner class ViewHolder(val binding: SingleItemBinding) : RecyclerView.ViewHolder(binding.root)
// inside the onCreateViewHolder inflate the view of SingleItemBinding
// and return new ViewHolder object containing this layout
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val binding = SingleItemBinding.inflate(LayoutInflater.from(parent.context), parent, false)
return ViewHolder(binding)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
with(holder){
with(itemList[position]){
// set name of the language from the list
binding.tvMainName.text = this.name
binding.tvDescription.text = this.description
binding.expandedView.visibility = if (this.expand) View.VISIBLE else View.GONE
if(this.expand) binding.viewMoreBtn.setImageResource(R.drawable.ic_arrow_drop_up_24) else binding.viewMoreBtn.setImageResource(R.drawable.ic_arrow_drop_down_24)
binding.cardLayout.setOnClickListener {
this.expand = !this.expand
notifyDataSetChanged()
}
}
}
}
override fun getItemCount(): Int = itemList.size
}
GitHub 에 올린 전체 소스 코드
https://github.com/jsk005/KotlinProjects/tree/master/expandablerv
728x90
'안드로이드 > ListView, RecyclerView' 카테고리의 다른 글
[java] RecyclerView ListAdapter DiffUtil (0) | 2022.08.24 |
---|---|
[Java] RecyclerView view binding (0) | 2022.05.23 |
RecyclerView 역순으로 리스트 출력하기 (0) | 2020.08.05 |
RecyclerView Checkbox 처리 및 Interface 처리 (0) | 2020.07.17 |
RecyclerViewAdapter 만드는 방법 (0) | 2018.10.05 |