Skip to content

Commit 5056d5b

Browse files
authored
Merge pull request #100 from boostcampwm-2022/fix/bug
각종 버그 수정
2 parents 23615a5 + aef4099 commit 5056d5b

File tree

22 files changed

+291
-175
lines changed

22 files changed

+291
-175
lines changed

buildSrc/src/main/java/com/wakeup/buildsrc/Depends.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import com.wakeup.buildsrc.Depends.Versions.appVersionCode
55
object Depends {
66

77
object Versions {
8-
const val appVersionCode = 1_000_000
8+
const val appVersionCode = 1_002_000
99
const val gradleVersion = "7.3.1"
1010
const val androidCompileSdkVersion = 32
1111
const val targetSdkVersion = 32

presentation/src/main/java/com/wakeup/presentation/extension/Extensions.kt

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import android.graphics.Canvas
99
import android.os.Build
1010
import android.util.TypedValue
1111
import android.view.View
12-
import android.view.WindowManager
1312
import android.view.inputmethod.InputMethodManager
1413
import android.widget.EditText
1514
import androidx.core.content.ContextCompat
@@ -92,16 +91,3 @@ fun View.showSnackBar(text: String, anchorViewResId: Int? = null) {
9291
}
9392
}.show()
9493
}
95-
96-
fun Fragment.setStatusBarTransparent() {
97-
this.requireActivity().window.setFlags(
98-
WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS,
99-
WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
100-
)
101-
}
102-
103-
fun Fragment.resetStatusBarTransparent() {
104-
this.requireActivity().window.clearFlags(
105-
WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
106-
)
107-
}

presentation/src/main/java/com/wakeup/presentation/lib/dialog/BaseDialog.kt

Lines changed: 22 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,18 @@ import android.content.Context
55
import android.graphics.Color
66
import android.graphics.drawable.ColorDrawable
77
import android.graphics.drawable.InsetDrawable
8-
import android.text.SpannableString
98
import android.view.Gravity
109
import android.view.View
1110
import android.view.WindowManager
1211
import android.widget.TextView
12+
import kotlin.properties.Delegates
1313

1414
abstract class BaseDialog<T : BaseDialog<T>>(protected val context: Context) {
1515

1616
protected lateinit var builder: AlertDialog.Builder
1717
protected lateinit var dialog: AlertDialog
1818
protected lateinit var dialogView: View
19+
protected var baseLayoutId by Delegates.notNull<Int>()
1920

2021

2122
@Suppress("UNCHECKED_CAST")
@@ -64,14 +65,13 @@ abstract class BaseDialog<T : BaseDialog<T>>(protected val context: Context) {
6465
* @param onPositive dialog 의 positive 버튼 클릭 이벤트를 지정해준다.
6566
*
6667
*/
67-
fun setOnPositive(resId: Int, text: String, onPositive: (dialog: T) -> Unit): T {
68-
val positiveView = dialogView.findViewById<View>(resId)
69-
if (positiveView is TextView) { // Button is TextView's expand class
70-
positiveView.text = text
71-
}
72-
positiveView.setOnClickListener {
73-
onPositive(self())
74-
dialog.dismiss()
68+
fun setOnPositive(resId: Int, text: CharSequence? = null, onPositive: (dialog: T) -> Unit): T {
69+
dialogView.findViewById<TextView>(resId).apply {
70+
this.text = text ?: this.text
71+
setOnClickListener {
72+
onPositive(self())
73+
dialog.dismiss()
74+
}
7575
}
7676
return self()
7777
}
@@ -82,34 +82,23 @@ abstract class BaseDialog<T : BaseDialog<T>>(protected val context: Context) {
8282
* @param resId dialog negative button 을 지정한다.
8383
* @param onNegative dialog 의 negative 버튼 클릭 이벤트를 지정해준다.
8484
*/
85-
fun setOnNegative(resId: Int, text: String, onNegative: (dialog: T) -> Unit): T {
86-
val negativeView = dialogView.findViewById<View>(resId)
87-
if (negativeView is TextView) { // Button is TextView's expand class
88-
negativeView.text = text
89-
}
90-
negativeView.setOnClickListener {
91-
onNegative(self())
92-
dialog.dismiss()
85+
fun setOnNegative(resId: Int, text: CharSequence? = null, onNegative: (dialog: T) -> Unit): T {
86+
dialogView.findViewById<TextView>(resId).apply {
87+
this.text = text ?: this.text
88+
setOnClickListener {
89+
onNegative(self())
90+
dialog.dismiss()
91+
}
9392
}
9493
return self()
9594
}
9695

9796
/**
9897
*
9998
* @param resId dialog 제목을 지정한다.
100-
* @param text dialog 제목의 text를 결정한다.
99+
* @param text dialog 제목의 text 를 결정한다.
101100
*/
102-
fun setTitle(resId: Int, text: String): T {
103-
dialogView.findViewById<TextView>(resId).text = text
104-
return self()
105-
}
106-
107-
/**
108-
*
109-
* @param resId dialog 제목을 지정한다.
110-
* @param text dialog 제목의 text를 결정한다. (SpannableString 적용한 Text 전용)
111-
*/
112-
fun setTitle(resId: Int, text: SpannableString): T {
101+
fun setTitle(resId: Int, text: CharSequence): T {
113102
dialogView.findViewById<TextView>(resId).text = text
114103
return self()
115104
}
@@ -124,6 +113,10 @@ abstract class BaseDialog<T : BaseDialog<T>>(protected val context: Context) {
124113
dialog.show()
125114
}
126115

116+
/**
117+
*
118+
* dialog 를 화면에서 없앤다.
119+
*/
127120
fun dismiss() {
128121
dialog.dismiss()
129122
}

presentation/src/main/java/com/wakeup/presentation/lib/dialog/EditDialog.kt

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,20 +23,26 @@ class EditDialog private constructor(context: Context) :
2323
private lateinit var editText: EditText
2424

2525
companion object {
26+
private var INSTANCE: EditDialog? = null
2627

2728
/**
2829
* @param context 화면에 띄울 컨텍스트를 지정
2930
* @param layoutId 원하는 dialog 레이아웃을 넣어준다.
3031
* @param editTextId dialog 레이아웃 내부의 editText Id를 넣어준다.
3132
*/
3233
fun with(context: Context, layoutId: Int, editTextId: Int): EditDialog {
33-
return EditDialog(context).apply {
34+
val instance = INSTANCE
35+
if (instance?.baseLayoutId == layoutId) return instance
36+
37+
INSTANCE = EditDialog(context).apply {
3438
builder = AlertDialog.Builder(context)
3539
dialogView = LayoutInflater.from(context).inflate(layoutId, null)
3640
dialog = builder.setView(dialogView).create()
3741
editText = dialogView.findViewById(editTextId)
38-
editText.setSingleLine()
42+
baseLayoutId = layoutId
3943
}
44+
45+
return INSTANCE ?: throw IllegalStateException("Instance is null.")
4046
}
4147
}
4248

presentation/src/main/java/com/wakeup/presentation/lib/dialog/NormalDialog.kt

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,17 +17,24 @@ class NormalDialog private constructor(context: Context) :
1717
BaseDialog<NormalDialog>(context) {
1818

1919
companion object {
20+
private var INSTANCE: NormalDialog? = null
2021

2122
/**
2223
* @param context 화면에 띄울 컨텍스트를 지정
2324
* @param layoutId 원하는 dialog 레이아웃을 넣어준다.
2425
*/
2526
fun with(context: Context, layoutId: Int): NormalDialog {
26-
return NormalDialog(context).apply {
27+
val instance = INSTANCE
28+
if (instance?.baseLayoutId == layoutId) return instance
29+
30+
INSTANCE = NormalDialog(context).apply {
2731
builder = AlertDialog.Builder(context)
2832
dialogView = LayoutInflater.from(context).inflate(layoutId, null)
2933
dialog = builder.setView(dialogView).create()
34+
baseLayoutId = layoutId
3035
}
36+
37+
return INSTANCE ?: throw IllegalStateException("Instance is null.")
3138
}
3239
}
3340
}

presentation/src/main/java/com/wakeup/presentation/lib/dialog/PictureDialog.kt

Lines changed: 34 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import android.widget.ImageView
77
import com.bumptech.glide.Glide
88
import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions
99
import java.io.File
10+
import kotlin.properties.Delegates
1011

1112
/**
1213
* 'glide' is a required ImageDialog.
@@ -16,36 +17,60 @@ import java.io.File
1617
class PictureDialog private constructor(context: Context) :
1718
BaseDialog<PictureDialog>(context) {
1819

20+
data class Size(
21+
val width: Int,
22+
val height: Int
23+
)
24+
1925
private lateinit var imageView: ImageView
26+
private lateinit var size: Size
27+
private var errorImageId by Delegates.notNull<Int>()
28+
2029

2130
companion object {
31+
private var INSTANCE: PictureDialog? = null
32+
2233
/**
2334
* @param context 화면에 띄울 컨텍스트를 지정
2435
* @param layoutId 원하는 dialog 레이아웃을 넣어준다.
2536
* @param imageViewId dialog 레이아웃 내부의 imageView Id를 넣어준다.
2637
*/
2738
fun with(context: Context, layoutId: Int, imageViewId: Int): PictureDialog {
28-
return PictureDialog(context).apply {
39+
val instance = INSTANCE
40+
if (instance?.baseLayoutId == layoutId) return instance
41+
42+
INSTANCE = PictureDialog(context).apply {
2943
builder = AlertDialog.Builder(context)
3044
dialogView = LayoutInflater.from(context).inflate(layoutId, null)
3145
dialog = builder.setView(dialogView).create()
3246
imageView = dialogView.findViewById(imageViewId)
47+
baseLayoutId = layoutId
3348
}
49+
50+
return INSTANCE ?: throw IllegalStateException("Instance is null.")
3451
}
3552
}
3653

37-
fun setImageFilePath(
54+
fun setSize(width: Int, height: Int): PictureDialog {
55+
size = Size(width, height)
56+
return this
57+
}
58+
59+
fun setErrorImage(id: Int): PictureDialog {
60+
errorImageId = id
61+
return this
62+
}
63+
64+
65+
fun setImagePath(
3866
filePath: String,
39-
errorImageDrawableId: Int,
40-
width: Int,
41-
height: Int,
4267
): PictureDialog {
4368
Glide.with(imageView.context)
4469
.load(File(filePath))
45-
.placeholder(errorImageDrawableId)
46-
.fallback(errorImageDrawableId)
47-
.error(errorImageDrawableId)
48-
.override(width, height)
70+
.placeholder(errorImageId)
71+
.fallback(errorImageId)
72+
.error(errorImageId)
73+
.override(size.width, size.height)
4974
.transition(DrawableTransitionOptions.withCrossFade())
5075
.into(imageView)
5176
return this

presentation/src/main/java/com/wakeup/presentation/ui/MainActivity.kt

Lines changed: 45 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,18 @@ import android.Manifest
44
import android.animation.ObjectAnimator
55
import android.annotation.SuppressLint
66
import android.content.pm.PackageManager
7+
import android.graphics.Rect
78
import android.location.Location
89
import android.os.Build
910
import android.os.Bundle
11+
import android.view.MotionEvent
1012
import android.view.View
1113
import android.view.ViewTreeObserver
1214
import android.view.animation.AnticipateInterpolator
1315
import android.widget.AdapterView
1416
import android.widget.AdapterView.OnItemSelectedListener
1517
import android.widget.ArrayAdapter
18+
import android.widget.EditText
1619
import androidx.activity.viewModels
1720
import androidx.appcompat.app.AppCompatActivity
1821
import androidx.core.animation.doOnEnd
@@ -21,6 +24,7 @@ import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
2124
import androidx.core.view.isVisible
2225
import androidx.lifecycle.lifecycleScope
2326
import androidx.navigation.NavController
27+
import androidx.navigation.findNavController
2428
import androidx.navigation.fragment.NavHostFragment
2529
import androidx.navigation.ui.AppBarConfiguration
2630
import androidx.navigation.ui.setupWithNavController
@@ -29,6 +33,7 @@ import com.google.android.gms.location.LocationServices
2933
import com.google.android.gms.tasks.OnSuccessListener
3034
import com.wakeup.presentation.R
3135
import com.wakeup.presentation.databinding.ActivityMainBinding
36+
import com.wakeup.presentation.extension.hideKeyboard
3237
import com.wakeup.presentation.extension.showSnackBar
3338
import com.wakeup.presentation.model.LocationModel
3439
import com.wakeup.presentation.model.WeatherTheme
@@ -111,8 +116,12 @@ class MainActivity : AppCompatActivity() {
111116
if (result == null) return@getLastLocation
112117

113118
launch {
114-
viewModel.fetchWeather(LocationModel(result.latitude,
115-
result.longitude))
119+
viewModel.fetchWeather(
120+
LocationModel(
121+
result.latitude,
122+
result.longitude
123+
)
124+
)
116125
}
117126
}
118127

@@ -234,10 +243,14 @@ class MainActivity : AppCompatActivity() {
234243
}
235244

236245
private fun initLocationPermission() {
237-
if (ActivityCompat.checkSelfPermission(this,
238-
Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
239-
&& ActivityCompat.checkSelfPermission(this,
240-
Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED
246+
if (ActivityCompat.checkSelfPermission(
247+
this,
248+
Manifest.permission.ACCESS_FINE_LOCATION
249+
) != PackageManager.PERMISSION_GRANTED
250+
&& ActivityCompat.checkSelfPermission(
251+
this,
252+
Manifest.permission.ACCESS_COARSE_LOCATION
253+
) != PackageManager.PERMISSION_GRANTED
241254
) {
242255
viewModel.permissionState.value = false
243256
return
@@ -247,16 +260,38 @@ class MainActivity : AppCompatActivity() {
247260
}
248261

249262
private fun hasLocationPermissions(): Boolean {
250-
if (ActivityCompat.checkSelfPermission(this,
251-
Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
252-
&& ActivityCompat.checkSelfPermission(this,
253-
Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED
263+
if (ActivityCompat.checkSelfPermission(
264+
this,
265+
Manifest.permission.ACCESS_FINE_LOCATION
266+
) != PackageManager.PERMISSION_GRANTED
267+
&& ActivityCompat.checkSelfPermission(
268+
this,
269+
Manifest.permission.ACCESS_COARSE_LOCATION
270+
) != PackageManager.PERMISSION_GRANTED
254271
) {
255272
return false
256273
}
257274
return true
258275
}
259276

277+
278+
override fun dispatchTouchEvent(ev: MotionEvent?): Boolean {
279+
if (findNavController(R.id.nav_host_fragment).currentDestination?.id == R.id.home_fragment) {
280+
if (ev?.action == MotionEvent.ACTION_DOWN) {
281+
val v = currentFocus
282+
if (v is EditText) {
283+
val outRect = Rect()
284+
v.getGlobalVisibleRect(outRect)
285+
if (!outRect.contains(ev.rawX.toInt(), ev.rawY.toInt())) {
286+
v.clearFocus()
287+
hideKeyboard(v)
288+
}
289+
}
290+
}
291+
}
292+
return super.dispatchTouchEvent(ev)
293+
}
294+
260295
private companion object {
261296
const val EXIT_ANIM_DURATION = 2000L
262297
const val ONE_MINUTE = 60000L

0 commit comments

Comments
 (0)