package com.sw.dualscreen.view import android.graphics.Color import android.graphics.Typeface import android.graphics.drawable.ColorDrawable import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.lifecycle.lifecycleScope import androidx.recyclerview.widget.GridLayoutManager import com.google.android.material.bottomsheet.BottomSheetDialogFragment import com.sw.dualscreen.R import com.sw.dualscreen.adapter.GenericItemAdapter import com.sw.dualscreen.adapter.GridSpacingItemDecoration import com.sw.dualscreen.adapter.dpToPx import com.sw.dualscreen.databinding.BottomSheetDialogBinding import com.sw.dualscreen.databinding.ItemSearchFoodInfoBinding import com.sw.dualscreen.model.response.FoodInfo import com.sw.dualscreen.utils.Debouncer import com.sw.dualscreen.viewmodel.UserViewModel import kotlinx.coroutines.launch import timber.log.Timber class CustomBottomSheetDialog( val viewModel: UserViewModel, val itemClickCallback: (FoodInfo) -> Unit ) : BottomSheetDialogFragment() { private lateinit var binding: BottomSheetDialogBinding private lateinit var adapter: GenericItemAdapter private var checkedItem: FoodInfo? = null override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { binding = BottomSheetDialogBinding.inflate(layoutInflater, container, false) return binding.root } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) val debouncer = Debouncer(3000) initView() binding.ivSearch.setOnClickListener { debouncer.debounce { viewModel.searchByFoodName(binding.etSearch.text.toString()) } } } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setStyle(STYLE_NO_TITLE, R.style.BottomSheetDialogTheme) setDialogStyle() } private fun setDialogStyle() { dialog?.window?.let { it.decorView.background = ColorDrawable(Color.TRANSPARENT) it.decorView.setPadding(0, 0, 0, 0) it.attributes?.apply { width = ViewGroup.LayoutParams.MATCH_PARENT height = ViewGroup.LayoutParams.MATCH_PARENT } it.setLayout( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT ) } } companion object { fun newInstance( viewModel: UserViewModel, itemClickCallback: (FoodInfo) -> Unit ): CustomBottomSheetDialog { return CustomBottomSheetDialog(viewModel, itemClickCallback) } } private fun initView() { adapter = createAdapter() binding.recyclerview.layoutManager = GridLayoutManager(context, 2) // 添加间距装饰(12dp) binding.recyclerview.addItemDecoration( GridSpacingItemDecoration( spanCount = 2, spacing = requireContext().dpToPx(30), includeEdge = false // 包含边缘间距 ) ) binding.recyclerview.adapter = adapter registerDataChange() } private fun registerDataChange() { lifecycleScope.launch { viewModel.searchFoodInfoList.collect { adapter.updateData(it) } } } private fun createAdapter(): GenericItemAdapter { return GenericItemAdapter( items = emptyList(), bindingInflater = ItemSearchFoodInfoBinding::inflate, bindCallback = { item, position -> this.tvName.text = item.foodName if (item.id != checkedItem?.id) { this.tvName.typeface = Typeface.defaultFromStyle(Typeface.NORMAL) this.tvName.setTextColor(resources.getColor(R.color.search_normal)) this.llRoot.setBackgroundResource(R.drawable.grid_search_item_normal) } else { this.tvName.typeface = Typeface.defaultFromStyle(Typeface.BOLD) this.tvName.setTextColor(resources.getColor(R.color.search_checked)) this.llRoot.setBackgroundResource(R.drawable.grid_search_item_checked) } this.llRoot.setOnClickListener { Timber.d("itemClick ${item.foodName}, position = $position") checkedItem = item // viewModel.updateCurrentItem(item) itemClickCallback(item) adapter.notifyDataSetChanged() } } ) } override fun dismiss() { viewModel.cleanSearchFoodInfoList() super.dismiss() } }