로그인 UI

- 입력창 크기 및 UI 수정
This commit is contained in:
2025-03-21 02:11:45 +09:00
parent 7c39d6c53a
commit 9331ba1276
3 changed files with 121 additions and 135 deletions

View File

@@ -1,9 +1,16 @@
package kr.co.vividnext.sodalive.user.login
import android.content.Intent
import android.graphics.Rect
import android.os.Bundle
import android.text.InputType
import android.transition.TransitionManager
import android.view.inputmethod.EditorInfo
import android.widget.LinearLayout
import android.widget.Toast
import androidx.annotation.OptIn
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.constraintlayout.widget.ConstraintSet
import androidx.media3.common.util.UnstableApi
import com.jakewharton.rxbinding4.widget.textChanges
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import io.reactivex.rxjava3.schedulers.Schedulers
@@ -11,11 +18,13 @@ import kr.co.vividnext.sodalive.base.BaseActivity
import kr.co.vividnext.sodalive.common.Constants
import kr.co.vividnext.sodalive.common.LoadingDialog
import kr.co.vividnext.sodalive.databinding.ActivityLoginBinding
import kr.co.vividnext.sodalive.extensions.dpToPx
import kr.co.vividnext.sodalive.main.MainActivity
import kr.co.vividnext.sodalive.user.find_password.FindPasswordActivity
import kr.co.vividnext.sodalive.user.signup.SignUpActivity
import org.koin.android.ext.android.inject
@OptIn(UnstableApi::class)
class LoginActivity : BaseActivity<ActivityLoginBinding>(ActivityLoginBinding::inflate) {
private val viewModel: LoginViewModel by inject()
@@ -24,33 +33,37 @@ class LoginActivity : BaseActivity<ActivityLoginBinding>(ActivityLoginBinding::i
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
bindData()
}
override fun setupView() {
binding.root.viewTreeObserver.addOnGlobalLayoutListener {
val rect = Rect()
binding.root.getWindowVisibleDisplayFrame(rect)
val keypadHeight = screenHeight - rect.bottom
if (keypadHeight > screenHeight * 0.15) {
updateMarginWithAnimation(
binding.llLoginContainer,
-100f.dpToPx().toInt()
)
} else {
updateMarginWithAnimation(binding.llLoginContainer, 0)
}
}
binding.tvToolbar.text = "로그인"
loadingDialog = LoadingDialog(this, layoutInflater)
binding.tvLogin.setOnClickListener {
viewModel.login {
it?.let { Toast.makeText(applicationContext, it, Toast.LENGTH_LONG).show() }
finishAffinity()
val nextIntent = Intent(applicationContext, MainActivity::class.java)
val extras = intent.getBundleExtra(Constants.EXTRA_DATA)
?: if (intent.extras != null) {
intent.extras
} else {
null
}
if (extras != null) {
nextIntent.putExtra(Constants.EXTRA_DATA, extras)
}
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP)
startActivity(nextIntent)
binding.etPassword.setOnEditorActionListener { _, actionId, _ ->
if (actionId == EditorInfo.IME_ACTION_DONE) {
login()
true
} else {
false
}
}
binding.tvLogin.setOnClickListener { login() }
binding.tvSignUp.setOnClickListener {
val nextIntent = Intent(applicationContext, SignUpActivity::class.java)
@@ -74,8 +87,26 @@ class LoginActivity : BaseActivity<ActivityLoginBinding>(ActivityLoginBinding::i
)
)
}
}
binding.tvVisiblePassword.setOnClickListener { viewModel.onClickVisiblePassword() }
private fun login() {
viewModel.login {
it?.let { Toast.makeText(applicationContext, it, Toast.LENGTH_LONG).show() }
finishAffinity()
val nextIntent = Intent(applicationContext, MainActivity::class.java)
val extras = intent.getBundleExtra(Constants.EXTRA_DATA)
?: if (intent.extras != null) {
intent.extras
} else {
null
}
if (extras != null) {
nextIntent.putExtra(Constants.EXTRA_DATA, extras)
}
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP)
startActivity(nextIntent)
}
}
private fun bindData() {
@@ -108,16 +139,24 @@ class LoginActivity : BaseActivity<ActivityLoginBinding>(ActivityLoginBinding::i
loadingDialog.dismiss()
}
}
}
viewModel.visiblePasswordLiveData.observe(this) {
binding.tvVisiblePassword.isSelected = it
if (it) {
binding.etPassword.inputType =
InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD
} else {
binding.etPassword.inputType =
InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_WEB_PASSWORD
}
}
private fun updateMarginWithAnimation(view: LinearLayout, newMargin: Int) {
val constraintLayout = view.parent as ConstraintLayout
val constraintSet = ConstraintSet()
constraintSet.clone(constraintLayout)
// 변경할 Constraint 적용 (margin 변경)
constraintSet.connect(
view.id,
ConstraintSet.TOP,
ConstraintSet.PARENT_ID,
ConstraintSet.TOP,
newMargin
)
// 애니메이션 적용
TransitionManager.beginDelayedTransition(constraintLayout)
constraintSet.applyTo(constraintLayout)
}
}

View File

@@ -14,10 +14,6 @@ class LoginViewModel(private val repository: UserRepository) : BaseViewModel() {
var email = ""
var password = ""
private val _visiblePasswordLiveData = MutableLiveData(false)
val visiblePasswordLiveData: LiveData<Boolean>
get() = _visiblePasswordLiveData
private val _toastLiveData = MutableLiveData<String?>()
val toastLiveData: LiveData<String?>
get() = _toastLiveData
@@ -71,8 +67,4 @@ class LoginViewModel(private val repository: UserRepository) : BaseViewModel() {
)
)
}
fun onClickVisiblePassword() {
_visiblePasswordLiveData.postValue(!_visiblePasswordLiveData.value!!)
}
}