Skip to content

Commit 10ac472

Browse files
authored
Merge pull request #273 from SPOTeam/SPOT-258
Spot 258
2 parents e381f86 + 89474c5 commit 10ac472

25 files changed

+1226
-320
lines changed

SPOTeam_android/.idea/deploymentTargetSelector.xml

Lines changed: 21 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

SPOTeam_android/.idea/other.xml

Lines changed: 549 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

SPOTeam_android/app/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ dependencies {
6262
implementation(libs.androidx.material3.android)
6363
implementation(libs.androidx.media3.common)
6464
implementation(libs.filament.android)
65+
implementation(libs.firebase.crashlytics.buildtools)
6566
testImplementation(libs.junit)
6667
androidTestImplementation(libs.androidx.junit)
6768
androidTestImplementation(libs.androidx.espresso.core)

SPOTeam_android/app/src/main/java/com/example/spoteam_android/MainActivity.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,7 @@ class MainActivity : AppCompatActivity() {
314314
// // 아무 동작도 하지 않도록 설정
315315
// // super.onBackPressed()를 호출하지 않으면 기본 동작(뒤로 가기)이 수행되지 않습니다.
316316
// }
317+
317318
private fun logTokens(context: Context) {
318319
val sharedPreferences = context.getSharedPreferences("MyPrefs", Context.MODE_PRIVATE)
319320
val email = sharedPreferences.getString("currentEmail", null)

SPOTeam_android/app/src/main/java/com/example/spoteam_android/login/StartLoginActivity.kt

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
11
package com.example.spoteam_android.login
22

33
import android.content.Intent
4+
import android.content.pm.PackageManager
5+
import android.os.Build
46
import android.os.Bundle
7+
import android.util.Base64
58
import android.util.Log
69
import android.widget.Toast
710
import androidx.appcompat.app.AppCompatActivity
11+
import androidx.core.content.ContentProviderCompat.requireContext
812
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
913
import androidx.lifecycle.ViewModelProvider
1014
import androidx.lifecycle.lifecycleScope
@@ -28,6 +32,8 @@ import kotlinx.coroutines.launch
2832
import retrofit2.Call
2933
import retrofit2.Callback
3034
import retrofit2.Response
35+
import java.security.MessageDigest
36+
import java.security.NoSuchAlgorithmException
3137

3238
class StartLoginActivity : AppCompatActivity() {
3339
private lateinit var binding: ActivityStartLoginBinding
@@ -60,7 +66,10 @@ class StartLoginActivity : AppCompatActivity() {
6066

6167
setupObservers()
6268

63-
binding.itemLogoKakaoIb.setOnClickListener { loginViewModel.startKakaoLogin(this) }
69+
binding.itemLogoKakaoIb.setOnClickListener {
70+
getKeyHash()
71+
loginViewModel.startKakaoLogin(this)
72+
}
6473
binding.itemLogoNaverIb.setOnClickListener { loginViewModel.startNaverLogin(this) }
6574

6675
//테스트
@@ -136,6 +145,23 @@ class StartLoginActivity : AppCompatActivity() {
136145
Toast.makeText(this, message, Toast.LENGTH_SHORT).show()
137146
}
138147

148+
fun getKeyHash() {
149+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
150+
val packageInfo = packageManager.getPackageInfo(packageName, PackageManager.GET_SIGNING_CERTIFICATES)
151+
for (signature in packageInfo.signingInfo.apkContentsSigners) {
152+
try {
153+
val md = MessageDigest.getInstance("SHA")
154+
md.update(signature.toByteArray())
155+
Log.d("getKeyHash", "key hash: ${Base64.encodeToString(md.digest(), Base64.NO_WRAP)}")
156+
} catch (e: NoSuchAlgorithmException) {
157+
Log.w("getKeyHash", "Unable to get MessageDigest. signature=$signature", e)
158+
}
159+
}
160+
}
161+
}
162+
163+
164+
139165
}
140166

141167

SPOTeam_android/app/src/main/java/com/example/spoteam_android/ui/interestarea/InterestFilterFragment.kt

Lines changed: 87 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
package com.example.spoteam_android.ui.interestarea
22

3-
43
import android.content.Context
4+
import android.content.res.ColorStateList
5+
import android.graphics.Color
6+
import android.icu.text.NumberFormat
57
import android.os.Bundle
68
import android.util.Log
79
import android.view.LayoutInflater
810
import android.view.View
911
import android.view.ViewGroup
1012
import android.view.inputmethod.EditorInfo
1113
import android.view.inputmethod.InputMethodManager
12-
import android.widget.AdapterView
13-
import android.widget.ArrayAdapter
14-
import android.widget.Spinner
14+
import androidx.core.content.ContextCompat
1515
import androidx.fragment.app.Fragment
1616
import androidx.fragment.app.activityViewModels
1717
import com.example.spoteam_android.MainActivity
@@ -42,21 +42,23 @@ class InterestFilterFragment : Fragment() {
4242
setupRecruitingChips()
4343
setupGenderChips()
4444
setupAgeRangeSlider()
45+
setupActivityFeeSlider()
4546
setupActivityFeeChips()
4647
setupStudyThemeChips()
4748
setupSearchButton()
4849

50+
4951
restoreRecruitingChip()
5052
restoreGenderChip()
5153
restoreActivityFeeChip()
52-
restoreStudyThemeChip()
54+
restoreStudyThemeChips()
5355
}
5456

5557
private fun setupToolbar() {
5658
binding.toolbar.icBack.setOnClickListener {
5759
viewModel.reset() // 1. ViewModel 값 초기화
5860
val bundle = Bundle().apply {
59-
putString("source", "InterestFilterFragment")
61+
putString("source", "HouseFragment")
6062
}
6163
val interestFragment = InterestFragment().apply {
6264
arguments = bundle
@@ -87,6 +89,11 @@ class InterestFilterFragment : Fragment() {
8789
ageRangeSlider.stepSize = 1f
8890
ageRangeSlider.values = listOf(18f, 60f)
8991

92+
val customThumb = ContextCompat.getDrawable(requireContext(),R.drawable.custom_thumb)
93+
if (customThumb != null) {
94+
ageRangeSlider.setCustomThumbDrawable(customThumb)
95+
}
96+
9097
ageRangeSlider.addOnChangeListener { slider, _, _ ->
9198
val values = slider.values
9299
val minAge = values[0].toInt()
@@ -98,57 +105,100 @@ class InterestFilterFragment : Fragment() {
98105
}
99106
}
100107

108+
private fun setupActivityFeeSlider() {
109+
val activityfeeSlider = binding.activityfeeSlider
110+
val minValueText = binding.activityfeeMinValueText
111+
val maxValueText = binding.activityfeeMaxValueText
112+
113+
activityfeeSlider.valueFrom = 1000f
114+
activityfeeSlider.valueTo = 10000f
115+
activityfeeSlider.stepSize = 100f
116+
activityfeeSlider.values = listOf(1000f, 10000f)
117+
val customThumb = ContextCompat.getDrawable(requireContext(),R.drawable.custom_thumb)
118+
if (customThumb != null) {
119+
activityfeeSlider.setCustomThumbDrawable(customThumb)
120+
}
121+
122+
123+
124+
activityfeeSlider.addOnChangeListener { slider, _, _ ->
125+
val values = slider.values
126+
val minfee = values[0].toInt()
127+
val maxfee = values[1].toInt()
128+
val formattedMinFee = NumberFormat.getNumberInstance().format(minfee)
129+
val formattedMaxFee = NumberFormat.getNumberInstance().format(maxfee)
130+
// 코드 변경 필요
131+
// viewModel.minAge = minAge
132+
// viewModel.maxAge = maxAge
133+
minValueText.text = "$formattedMinFee"
134+
maxValueText.text = "$formattedMaxFee"
135+
}
136+
}
137+
101138
private fun setupActivityFeeChips() {
102139
val chipGroup1 = binding.chipGroup1
103-
val editText = binding.edittext1
104-
val behindEt = binding.behindEt
140+
105141

106142
chipGroup1.setOnCheckedChangeListener { _, checkedId ->
107143
if (checkedId != ChipGroup.NO_ID) {
108144
val checkedChip = chipGroup1.findViewById<Chip>(checkedId)
109145
if (checkedChip.id == R.id.chip1) {
110146
viewModel.activityFee = "있음"
111-
editText.visibility = View.VISIBLE
112-
behindEt.visibility = View.VISIBLE
113147
} else {
114148
viewModel.activityFee = "없음"
115-
editText.visibility = View.GONE
116-
behindEt.visibility = View.GONE
117149
}
118150
} else {
119151
viewModel.activityFee = "없음"
120-
editText.visibility = View.GONE
121-
behindEt.visibility = View.GONE
122152
}
123153
updateNextButtonState()
124154
}
125155

126-
editText.setOnEditorActionListener { _, actionId, _ ->
127-
if (actionId == EditorInfo.IME_ACTION_DONE) {
128-
val imm = activity?.getSystemService(Context.INPUT_METHOD_SERVICE) as? InputMethodManager
129-
imm?.hideSoftInputFromWindow(editText.windowToken, 0)
130-
editText.clearFocus()
131156

132-
viewModel.activityFeeAmount = editText.text.toString()
133-
updateNextButtonState()
134-
true
135-
} else false
136-
}
137157
}
138158

139159
private fun setupStudyThemeChips() {
140-
binding.chipGroup2.setOnCheckedChangeListener { group, checkedId ->
141-
if (checkedId != ChipGroup.NO_ID) {
142-
val selectedChip = group.findViewById<Chip>(checkedId)
143-
val selectedText = selectedChip?.text.toString()
144-
viewModel.selectedStudyTheme = selectedText
145-
Log.d("InterestFilterFragment", "Selected study theme: $selectedText")
160+
for (i in 0 until binding.chipGroup2.childCount) {
161+
val chip = binding.chipGroup2.getChildAt(i) as? Chip ?: continue
162+
163+
chip.setOnClickListener {
164+
val theme = chip.text.toString()
165+
val themes = viewModel.selectedStudyThemes
166+
167+
if (chip.isChecked) {
168+
if (!themes.contains(theme)) {
169+
themes.add(theme)
170+
}
171+
} else {
172+
themes.remove(theme)
173+
}
174+
175+
Log.d("InterestFilterFragment", "Selected study themes: $themes")
176+
updateNextButtonState()
146177
}
147-
updateNextButtonState()
148178
}
149179
}
150180

151181
private fun setupSearchButton() {
182+
//필터 초기화 클릭
183+
binding.txResetFilter.setOnClickListener {
184+
viewModel.reset()
185+
186+
binding.chipGroupRecruiting.clearCheck()
187+
binding.chipGroupGender.clearCheck()
188+
binding.chipGroup1.clearCheck()
189+
binding.chipGroup2.clearCheck()
190+
191+
// ✅ RangeSlider 초기화
192+
binding.ageRangeSlider.values = listOf(18f, 60f)
193+
binding.activityfeeSlider.values = listOf(1000f, 10000f)
194+
195+
// ✅ 텍스트뷰 값도 초기화 (선택사항)
196+
binding.minValueText.text = "18"
197+
binding.maxValueText.text = "60"
198+
binding.activityfeeMinValueText.text = "₩ 1,000"
199+
binding.activityfeeMaxValueText.text = "₩ 10,000"
200+
}
201+
152202
binding.fragmentIntroduceStudyBt.setOnClickListener {
153203
// ViewModel 값 → Bundle
154204
val bundle = Bundle().apply {
@@ -168,15 +218,11 @@ class InterestFilterFragment : Fragment() {
168218

169219
private fun updateNextButtonState() {
170220
val activityFee = viewModel.activityFee
171-
val activityFeeAmount = binding.edittext1.text.toString()
172221

173222
val isActivityFeeNoneSelected = activityFee == "없음"
174-
val isActivityFeeEntered = activityFee == "있음" &&
175-
activityFeeAmount.isNotEmpty() &&
176-
activityFeeAmount.toIntOrNull() != null
177-
223+
val isActivityFeeEntered = activityFee == "있음"
178224
val isSecondConditionMet = isActivityFeeNoneSelected || isActivityFeeEntered
179-
val isThirdConditionMet = viewModel.selectedStudyTheme != null
225+
val isThirdConditionMet = viewModel.selectedStudyThemes.isNotEmpty()
180226

181227
binding.fragmentIntroduceStudyBt.isEnabled = isSecondConditionMet && isThirdConditionMet
182228
}
@@ -192,28 +238,20 @@ class InterestFilterFragment : Fragment() {
192238
when (viewModel.activityFee) {
193239
"있음" -> {
194240
binding.chipGroup1.check(R.id.chip1)
195-
binding.edittext1.setText(viewModel.activityFeeAmount)
196-
binding.edittext1.visibility = View.VISIBLE
197-
binding.behindEt.visibility = View.VISIBLE
198241
}
199242
"없음" -> {
200243
binding.chipGroup1.check(R.id.chip2)
201-
binding.edittext1.visibility = View.GONE
202-
binding.behindEt.visibility = View.GONE
203244
}
204245
}
205246
}
206247

207-
private fun restoreStudyThemeChip() {
208-
val selectedText = viewModel.selectedStudyTheme ?: return
248+
private fun restoreStudyThemeChips() {
249+
val selectedThemes = viewModel.selectedStudyThemes
209250
val chipGroup = binding.chipGroup2
210251

211252
for (i in 0 until chipGroup.childCount) {
212-
val chip = chipGroup.getChildAt(i) as? Chip
213-
if (chip?.text == selectedText) {
214-
chipGroup.check(chip.id)
215-
break
216-
}
253+
val chip = chipGroup.getChildAt(i) as? Chip ?: continue
254+
chip.isChecked = selectedThemes.contains(chip.text.toString())
217255
}
218256
}
219257

SPOTeam_android/app/src/main/java/com/example/spoteam_android/ui/interestarea/InterestFilterViewModel.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ class InterestFilterViewModel : ViewModel() {
66
var gender: String? = null
77
var activityFee: String? = null
88
var activityFeeAmount: String? = null
9-
var selectedStudyTheme: String? = null
9+
var selectedStudyThemes: MutableList<String> = mutableListOf() // 복수 선택
1010
var minAge: Int = 18
1111
var maxAge: Int = 60
1212
var isRecruiting: String? = null
@@ -17,7 +17,7 @@ class InterestFilterViewModel : ViewModel() {
1717
maxAge = 60
1818
activityFee = null
1919
activityFeeAmount = null
20-
selectedStudyTheme = null
20+
selectedStudyThemes.clear()
2121
isRecruiting = null
2222
}
2323
}

0 commit comments

Comments
 (0)