<?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">
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:text="TextView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<com.google.android.material.chip.ChipGroup
android:id="@+id/chipgroup"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
android:layout_marginTop="20dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView2"
app:singleSelection="true">
<com.google.android.material.chip.Chip
android:id="@+id/cloths_chip"
android:layout_width="wrap_content"
android:layout_height="40dp"
android:checkable="true"
android:text="의류"
android:textSize="12sp" />
<com.google.android.material.chip.Chip
android:id="@+id/machine_chip"
android:layout_width="wrap_content"
android:layout_height="40dp"
android:checkable="true"
android:text="가전제품"
android:textSize="12sp" />
<com.google.android.material.chip.Chip
android:id="@+id/sport_chip"
android:layout_width="wrap_content"
android:layout_height="40dp"
android:checkable="true"
android:text="스포츠"
android:textSize="12sp" />
<com.google.android.material.chip.Chip
android:id="@+id/art_chip"
android:layout_width="wrap_content"
android:layout_height="40dp"
android:checkable="true"
android:text="예술"
android:textSize="12sp" />
<com.google.android.material.chip.Chip
android:id="@+id/book_chip"
android:layout_width="wrap_content"
android:layout_height="40dp"
android:checkable="true"
android:text="독서"
android:textSize="12sp" />
<com.google.android.material.chip.Chip
android:id="@+id/beauty_chip"
android:layout_width="wrap_content"
android:layout_height="40dp"
android:checkable="true"
android:text="뷰티"
android:textSize="12sp" />
<com.google.android.material.chip.Chip
android:id="@+id/toy_chip"
android:layout_width="wrap_content"
android:layout_height="40dp"
android:checkable="true"
android:text="문구"
android:textSize="12sp" />
</com.google.android.material.chip.ChipGroup>
</androidx.constraintlayout.widget.ConstraintLayout>
interface CategorySelectionListener {
fun onCategorySelected(category: String)
} 리스너를 달아줘서 카테고리 변환을 감지하고,
fun setCategorySelectionListener(listener: CategorySelectionListener) {
categorySelectionListener = listener
}로 선택 된 category 값을 전달한다.
class CategoryDialogFragment : DialogFragment() {
private lateinit var binding: FragmentCategoryDialogBinding
//카테고리 선택 이벤트 리스닝
interface CategorySelectionListener {
fun onCategorySelected(category: String)
}
private var categorySelectionListener: CategorySelectionListener? = null
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding = FragmentCategoryDialogBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.chipgroup.setOnCheckedChangeListener { group, checkedId ->
val selectedChip = view.findViewById<Chip>(checkedId)
val selectedCategory = selectedChip.text.toString()
//selected된 값 전달
categorySelectionListener?.onCategorySelected(selectedCategory)
dismiss()
}
}
//home으로 기능 내보내기
fun setCategorySelectionListener(listener: CategorySelectionListener) {
categorySelectionListener = listener
}
}
class HomeAdapter(private val context: Context):
RecyclerView.Adapter<RecyclerView.ViewHolder>() {
private var homeDataItem: ArrayList<PostData> = ArrayList()
private var filteredDataItem: List<PostData> = ArrayList()
fun postDataFromFirestore() {
val fireStore = FirebaseFirestore.getInstance()
fireStore.collection("Post").get()
.addOnSuccessListener { result ->
Log.d("postDataFromFirestore", "nyh postDataFromFirestore suc: $result")
val newData = mutableListOf<PostData>()
for (i in result) {
if (i.exists()) {
Log.d("postDataFromFirestore", "nyh postDataFromFirestore suc: ${newData.size}, $newData")
val postData = i.toObject(PostData::class.java)
newData.add(postData)
}
}
homeDataItem.clear()
homeDataItem.addAll(newData)
filterByCategory("")
notifyDataSetChanged()
}
.addOnFailureListener { e ->
Log.e("FirestoreAdapter", "Error getting documents: $e")
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
val inflater = LayoutInflater.from(parent.context)
val binding = WriteItemBinding.inflate(inflater,parent,false)
return HomeHolder(binding)
}
override fun getItemCount(): Int {
return filteredDataItem.size
}
fun filterByCategory(category: String) {
if (category.isEmpty()) {
Log.d("nyh", "filterByCategory: ${filteredDataItem.size}")
filteredDataItem = homeDataItem // 전체 데이터 표시
} else {
filteredDataItem = homeDataItem.filter { it.category == category }
}
notifyDataSetChanged()
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
val homeItem = homeDataItem[position]
val homeHolder = holder as HomeHolder
val storage = Firebase.storage
val storageRef = storage.getReference("image")
val fileName = SimpleDateFormat("yyyyMMddHHmmss").format(Date())
val mountainRef = storageRef.child("${fileName}.png")
homeHolder.title.text = homeItem.title
homeHolder.subtitle.text = homeItem.mainText
homeHolder.category.text = homeItem.category
homeHolder.value.text = homeItem.value.toString()
}
inner class HomeHolder(val binding : WriteItemBinding):
RecyclerView.ViewHolder(binding.root) {
val title = binding.writeTittle
val subtitle = binding.writeSubtittle
val value = binding.writePrice
val category = binding.writeCategory
val image = binding.writeImage
}
}
위 두가지를 추가한다.
class HomeFragment : Fragment(), CategoryDialogFragment.CategorySelectionListener {
private lateinit var binding: FragmentHomeBinding
private lateinit var mContext: Context
private lateinit var homeAdapter: HomeAdapter
private val viewModel: HomeViewModel by viewModels()
private var selectedCategory: String = ""
override fun onAttach(context: Context) {
super.onAttach(context)
mContext = context
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding = FragmentHomeBinding.inflate(inflater, container, false)
return binding.root
}
override fun onResume() {
super.onResume()
homeAdapter.postDataFromFirestore()
Log.d("HomeFrag onResume", "nyh backbtnsuc??")
viewModel.refreshData.observe(viewLifecycleOwner) { refresh ->
if (refresh) {
homeAdapter.postDataFromFirestore()
viewModel.onRefreshComplete()
}
}
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
Log.d("Homefrag", "nyh backbtnsuc??")
mContext = requireContext()
homeAdapter = HomeAdapter(mContext)
binding.homeRecycle.layoutManager =
LinearLayoutManager(mContext, LinearLayoutManager.VERTICAL, false)
binding.homeRecycle.adapter = homeAdapter
binding.btnFilter.setOnClickListener {
val filterDialogFragment = CategoryDialogFragment()
//다이얼로그에있는 리스너를 달아준다
filterDialogFragment.setCategorySelectionListener(this)
filterDialogFragment.show(childFragmentManager, "filter_dialog_tag")
}
}
@SuppressLint("NotifyDataSetChanged")
override fun onCategorySelected(category: String) {
selectedCategory = category
// 선택된 카테고리로 항목을 filter한다
if (category.isNotEmpty()) {
homeAdapter.filterByCategory(category)
Log.d("HomeFrag", "nyh category = $category")
} else {
Log.d("nyh", "onCategorySelected: gg")
}
homeAdapter.notifyDataSetChanged()
}
}
작성자는 Adapter에서 초기설정함수를 데이터를 받아오는 곳에서 적용하는 부분을 놓쳐서 꽤 오랜 시간이 걸렸따..😂