로그인 UI

- 입력창 크기 및 UI 수정
This commit is contained in:
klaus 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
binding.etPassword.setOnEditorActionListener { _, actionId, _ ->
if (actionId == EditorInfo.IME_ACTION_DONE) {
login()
true
} 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)
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!!)
}
}

View File

@ -4,6 +4,7 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:animateLayoutChanges="true"
android:background="@color/black">
<TextView
@ -22,99 +23,68 @@
tools:text="바로, 상담 가능한 크리에이터" />
<LinearLayout
android:id="@+id/ll_login_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true"
android:gravity="center"
android:orientation="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<LinearLayout
<com.google.android.material.textfield.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="26.7dp"
android:orientation="vertical">
android:layout_marginHorizontal="13.3dp"
android:hint="이메일"
app:boxBackgroundColor="@color/color_cc333333"
app:boxBackgroundMode="filled"
app:boxCornerRadiusBottomEnd="6.7dp"
app:boxCornerRadiusBottomStart="6.7dp"
app:boxCornerRadiusTopEnd="6.7dp"
app:boxCornerRadiusTopStart="6.7dp"
app:boxStrokeColor="@color/color_cc333333">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginHorizontal="6.7dp"
android:fontFamily="@font/gmarket_sans_medium"
android:text="이메일"
android:textColor="@color/color_eeeeee"
android:textSize="12sp" />
<EditText
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/et_email"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/edittext_underline"
android:fontFamily="@font/gmarket_sans_medium"
android:hint="이메일 주소를 입력하세요"
android:importantForAutofill="no"
android:inputType="textWebEmailAddress"
android:paddingHorizontal="6.7dp"
android:paddingTop="12dp"
android:paddingBottom="8dp"
android:inputType="textEmailAddress"
android:paddingVertical="16dp"
android:textColor="@color/color_eeeeee"
android:textColorHint="@color/color_777777"
android:textCursorDrawable="@drawable/edit_text_cursor"
android:textSize="13.3sp"
android:theme="@style/EditTextStyle"
tools:ignore="LabelFor" />
android:textSize="15sp" />
</com.google.android.material.textfield.TextInputLayout>
</LinearLayout>
<LinearLayout
<com.google.android.material.textfield.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="26.7dp"
android:layout_marginTop="33.3dp"
android:orientation="vertical">
android:layout_marginHorizontal="13.3dp"
android:layout_marginTop="16dp"
android:hint="비밀번호"
app:boxBackgroundColor="@color/color_cc333333"
app:boxBackgroundMode="filled"
app:boxCornerRadiusBottomEnd="6.7dp"
app:boxCornerRadiusBottomStart="6.7dp"
app:boxCornerRadiusTopEnd="6.7dp"
app:boxCornerRadiusTopStart="6.7dp"
app:boxStrokeColor="@color/color_cc333333"
app:endIconMode="password_toggle">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginHorizontal="6.7dp"
android:fontFamily="@font/gmarket_sans_medium"
android:text="비밀번호"
android:textColor="@color/color_eeeeee"
android:textSize="12sp" />
<EditText
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/et_password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/edittext_underline"
android:fontFamily="@font/gmarket_sans_medium"
android:hint="비밀번호를 입력하세요"
android:importantForAutofill="no"
android:inputType="textWebPassword"
android:paddingHorizontal="6.7dp"
android:paddingTop="12dp"
android:paddingBottom="8dp"
android:imeOptions="actionDone"
android:inputType="textPassword"
android:paddingVertical="16dp"
android:textColor="@color/color_eeeeee"
android:textColorHint="@color/color_777777"
android:textCursorDrawable="@drawable/edit_text_cursor"
android:textSize="13.3sp"
android:theme="@style/EditTextStyle"
tools:ignore="LabelFor" />
<TextView
android:id="@+id/tv_visible_password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:drawablePadding="13.3dp"
android:fontFamily="@font/gmarket_sans_medium"
android:gravity="center_vertical"
android:text="비밀번호 표시"
android:textColor="@color/color_eeeeee"
android:textSize="13.3sp"
app:drawableStartCompat="@drawable/ic_select" />
</LinearLayout>
android:textSize="15sp" />
</com.google.android.material.textfield.TextInputLayout>
<TextView
android:id="@+id/tv_login"
@ -130,28 +100,13 @@
android:textColor="@color/white"
android:textSize="15sp" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="40dp"
android:orientation="horizontal">
<TextView
android:id="@+id/tv_forgot_password"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="40dp"
android:fontFamily="@font/gmarket_sans_medium"
android:text="비밀번호 재설정"
android:textColor="@color/color_bbbbbb"
android:textSize="13.3sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginHorizontal="4dp"
android:fontFamily="@font/gmarket_sans_medium"
android:text="|"
android:text="비밀번호를 잊으셨나요?"
android:textColor="@color/color_bbbbbb"
android:textSize="13.3sp" />
@ -159,10 +114,10 @@
android:id="@+id/tv_sign_up"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:fontFamily="@font/gmarket_sans_medium"
android:text="회원가입"
android:text="보이스온 회원이 아닌가요? 지금 가입하세요."
android:textColor="@color/color_bbbbbb"
android:textSize="13.3sp" />
</LinearLayout>
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>