최근에는 소개팅 어플을 만드는 강의를 듣고 있는데 소개팅어플에서 자주 사용이 되고 있는 CardStackView 위젯에 대해 먼저 공부를 해보고 있다. 이번에는 CardStackView에 대해 정리를 할 것이다.
CardStackView는 Android에서 카드 형태의 UI 요소를 스와이프하여 처리할 수 있는 뷰로써, CardStackView는 사용자가 Tinder와 같은 앱에서 카드를 좌우로 스와이프하여 새로운 카드를 탐색하는 인터페이스를 쉽게 구현할 수 있게 해준다.
CardStackView 또한 리사이클러뷰 같은 구조를 같는다. CardStackView를 사용할 액티비티에서 리사이클러뷰 Adapter로 리스트형태의 데이터를 넘겨주고 Adapter에서 리스트형태의 데이터를 이용하여 아이템을 구성한다.
CardStackView에서도 마찬가지로 리사이클러뷰에서 어댑터를 생성하듯이 어탭터를 생성한후 CardStackView어댑터에 연결을 하여 리스트의 데이터들을 ViewHolder를 이용하여 카드로 표현할수 있다. 또한 , CardStackLayoutManager를 이용하여 CardStackView에서의 드래그,스와이프,취소 등 이벤트 처리를 할수 있게 해준다.
우선 CardStackView를 사용하기 위해서는 라이브러리를 추가해줘야한다. 아래 github주소에 들어가보면 자세한 사용방법도 알아볼수 있다.
https://github.com/yuyakaido/CardStackView
CardStackView
<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.yuyakaido.android.cardstackview.CardStackView
android:id="@+id/cardStackView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
Item
<androidx.cardview.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/profileImageArea"
android:src="@drawable/question"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</androidx.cardview.widget.CardView>
class CardStackAdapter(val context : Context, val items : List<String>) : RecyclerView.Adapter<CardStackAdapter.ViewHolder>(){
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CardStackAdapter.ViewHolder {
val inflater = LayoutInflater.from(parent.context)
val view : View = inflater.inflate(R.layout.item_card,parent,false)
return ViewHolder(view)
}
override fun onBindViewHolder(holder: CardStackAdapter.ViewHolder, position: Int) {
holder.binding(items[position])
}
override fun getItemCount(): Int {
return items.size
}
inner class ViewHolder(view : View) : RecyclerView.ViewHolder(view){
fun binding(data : String){
}
}
}
class MainActivity : AppCompatActivity() {
lateinit var cardStackAdapter: CardStackAdapter
lateinit var manager : CardStackLayoutManager
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val cardStackView = findViewById<CardStackView>(R.id.cardStackView)
manager = CardStackLayoutManager(baseContext, object : CardStackListener{
override fun onCardDragging(direction: Direction?, ratio: Float) {
}
override fun onCardSwiped(direction: Direction?) {
}
override fun onCardRewound() {
}
override fun onCardCanceled() {
}
override fun onCardAppeared(view: View?, position: Int) {
}
override fun onCardDisappeared(view: View?, position: Int) {
}
})
val testList = mutableListOf<String>()
testList.add("a")
testList.add("b")
testList.add("c")
cardStackAdapter = CardStackAdapter(baseContext,testList)
cardStackView.layoutManager = manager
cardStackView.adapter = cardStackAdapter
}
}
보통 CardStackView에서의 스와이프 이벤트 처리는 CardStackViewManager에서 처리 할수 있지만, xml에서도 스와이프 방향에따라서 overlay 처리를 할수 있다.
<androidx.cardview.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_margin="20dp"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ImageView
android:id="@+id/profileImageArea"
android:src="@drawable/question"
android:layout_width="match_parent"
android:layout_height="500dp"/>
<TextView
android:layout_margin="5dp"
android:textSize="30dp"
android:textColor="@color/black"
android:textStyle="bold"
android:text="Name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:layout_margin="5dp"
android:textSize="30dp"
android:textColor="@color/black"
android:textStyle="bold"
android:text="Age"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:layout_margin="5dp"
android:textSize="30dp"
android:textColor="@color/black"
android:textStyle="bold"
android:text="City"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
<FrameLayout
android:id="@+id/right_overlay"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:src="@drawable/ok"
android:layout_gravity="center"
android:layout_width="100dp"
android:layout_height="100dp"/>
</FrameLayout>
<FrameLayout
android:id="@+id/left_overlay"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:src="@drawable/no"
android:layout_gravity="center"
android:layout_width="100dp"
android:layout_height="100dp"/>
</FrameLayout>
</androidx.cardview.widget.CardView>
이런식으로 스와이프 방향에 따라서 기존 이미지에 overlay 처리를 할수 있다.