diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 4717a5c..4d64259 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -98,7 +98,9 @@
-
+
diff --git a/app/src/main/java/kr/co/vividnext/sodalive/user/Gender.kt b/app/src/main/java/kr/co/vividnext/sodalive/user/Gender.kt
index 7a0c27f..30c099d 100644
--- a/app/src/main/java/kr/co/vividnext/sodalive/user/Gender.kt
+++ b/app/src/main/java/kr/co/vividnext/sodalive/user/Gender.kt
@@ -5,8 +5,10 @@ import com.google.gson.annotations.SerializedName
enum class Gender {
@SerializedName("MALE")
MALE,
+
@SerializedName("FEMALE")
FEMALE,
+
@SerializedName("NONE")
NONE
}
diff --git a/app/src/main/java/kr/co/vividnext/sodalive/user/UserApi.kt b/app/src/main/java/kr/co/vividnext/sodalive/user/UserApi.kt
index 0153a1a..61520a3 100644
--- a/app/src/main/java/kr/co/vividnext/sodalive/user/UserApi.kt
+++ b/app/src/main/java/kr/co/vividnext/sodalive/user/UserApi.kt
@@ -4,7 +4,6 @@ import io.reactivex.rxjava3.core.Single
import kr.co.vividnext.sodalive.common.ApiResponse
import kr.co.vividnext.sodalive.explorer.profile.MemberBlockRequest
import kr.co.vividnext.sodalive.live.room.detail.GetRoomDetailUser
-import kr.co.vividnext.sodalive.main.GaidUpdateRequest
import kr.co.vividnext.sodalive.main.MarketingInfoUpdateRequest
import kr.co.vividnext.sodalive.main.PushTokenUpdateRequest
import kr.co.vividnext.sodalive.mypage.MyPageResponse
@@ -18,8 +17,8 @@ import kr.co.vividnext.sodalive.settings.signout.SignOutRequest
import kr.co.vividnext.sodalive.user.find_password.ForgotPasswordRequest
import kr.co.vividnext.sodalive.user.login.LoginRequest
import kr.co.vividnext.sodalive.user.login.LoginResponse
+import kr.co.vividnext.sodalive.user.signup.SignUpRequest
import okhttp3.MultipartBody
-import okhttp3.RequestBody
import retrofit2.http.Body
import retrofit2.http.GET
import retrofit2.http.Header
@@ -34,11 +33,9 @@ interface UserApi {
@POST("/member/login")
fun login(@Body request: LoginRequest): Single>
- @POST("/member/signup")
- @Multipart
+ @POST("/member/signup/v2")
fun signUp(
- @Part profileImage: MultipartBody.Part?,
- @Part("request") request: RequestBody
+ @Body request: SignUpRequest
): Single>
@POST("/member/forgot-password")
@@ -142,12 +139,6 @@ interface UserApi {
@Header("Authorization") authHeader: String
): Single>
- @PUT("/member/adid/update")
- fun updateGaid(
- @Body request: GaidUpdateRequest,
- @Header("Authorization") authHeader: String
- ): Single>
-
@PUT("/member/marketing-info/update")
fun updateMarketingInfo(
@Body request: MarketingInfoUpdateRequest,
diff --git a/app/src/main/java/kr/co/vividnext/sodalive/user/UserRepository.kt b/app/src/main/java/kr/co/vividnext/sodalive/user/UserRepository.kt
index f9ca8a8..1ae028c 100644
--- a/app/src/main/java/kr/co/vividnext/sodalive/user/UserRepository.kt
+++ b/app/src/main/java/kr/co/vividnext/sodalive/user/UserRepository.kt
@@ -13,16 +13,13 @@ import kr.co.vividnext.sodalive.settings.notification.UpdateNotificationSettingR
import kr.co.vividnext.sodalive.settings.signout.SignOutRequest
import kr.co.vividnext.sodalive.user.find_password.ForgotPasswordRequest
import kr.co.vividnext.sodalive.user.login.LoginRequest
+import kr.co.vividnext.sodalive.user.signup.SignUpRequest
import okhttp3.MultipartBody
-import okhttp3.RequestBody
class UserRepository(private val userApi: UserApi) {
fun login(request: LoginRequest) = userApi.login(request)
- fun signUp(profileImage: MultipartBody.Part?, request: RequestBody) = userApi.signUp(
- profileImage,
- request
- )
+ fun signUp(request: SignUpRequest) = userApi.signUp(request)
fun findPassword(request: ForgotPasswordRequest) = userApi.findPassword(request = request)
diff --git a/app/src/main/java/kr/co/vividnext/sodalive/user/signup/SignUpActivity.kt b/app/src/main/java/kr/co/vividnext/sodalive/user/signup/SignUpActivity.kt
index b1e9099..dbcdfa0 100644
--- a/app/src/main/java/kr/co/vividnext/sodalive/user/signup/SignUpActivity.kt
+++ b/app/src/main/java/kr/co/vividnext/sodalive/user/signup/SignUpActivity.kt
@@ -1,99 +1,50 @@
package kr.co.vividnext.sodalive.user.signup
+import android.app.Service
import android.content.Intent
import android.os.Bundle
-import android.view.View
+import android.os.Handler
+import android.os.Looper
+import android.view.inputmethod.InputMethodManager
import android.widget.Toast
-import androidx.activity.OnBackPressedCallback
-import androidx.activity.result.contract.ActivityResultContracts
-import coil.load
-import coil.transform.RoundedCornersTransformation
-import com.github.dhaval2404.imagepicker.ImagePicker
+import androidx.annotation.OptIn
+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
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.common.RealPathUtil
import kr.co.vividnext.sodalive.databinding.ActivitySignupBinding
-import kr.co.vividnext.sodalive.extensions.dpToPx
import kr.co.vividnext.sodalive.main.MainActivity
import kr.co.vividnext.sodalive.settings.terms.TermsActivity
-import kr.co.vividnext.sodalive.user.Gender
import org.koin.android.ext.android.inject
+@OptIn(UnstableApi::class)
class SignUpActivity : BaseActivity(ActivitySignupBinding::inflate) {
private val viewModel: SignUpViewModel by inject()
- private val onBackPressedCallback = object : OnBackPressedCallback(true) {
- override fun handleOnBackPressed() {
- onClickBackButton()
- }
- }
private lateinit var loadingDialog: LoadingDialog
+ private lateinit var imm: InputMethodManager
- private val imageResult =
- registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
- val resultCode = result.resultCode
- val data = result.data
-
- if (resultCode == RESULT_OK) {
- // Image Uri will not be null for RESULT_OK
- val fileUri = data?.data!!
- binding.ivProfile.background = null
- binding.ivProfile.load(fileUri) {
- crossfade(true)
- transformations(RoundedCornersTransformation(13.3f.dpToPx()))
- }
- viewModel.profileImageUri = fileUri
- } else if (resultCode == ImagePicker.RESULT_ERROR) {
- Toast.makeText(this, ImagePicker.getError(data), Toast.LENGTH_SHORT).show()
- }
- }
+ private val handler = Handler(Looper.getMainLooper())
override fun onCreate(savedInstanceState: Bundle?) {
+ imm = getSystemService(Service.INPUT_METHOD_SERVICE) as InputMethodManager
+
super.onCreate(savedInstanceState)
- onBackPressedDispatcher.addCallback(this, onBackPressedCallback)
-
- viewModel.getRealPathFromURI = {
- RealPathUtil.getRealPath(applicationContext, it)
- }
-
bindData()
}
override fun setupView() {
binding.toolbar.tvBack.text = "회원가입"
- binding.toolbar.tvBack.setOnClickListener { onClickBackButton() }
-
+ binding.toolbar.tvBack.setOnClickListener { finish() }
loadingDialog = LoadingDialog(this, layoutInflater)
- binding.ivPhotoPicker.setOnClickListener {
- ImagePicker.with(this)
- .crop()
- .galleryOnly()
- .galleryMimeTypes( // Exclude gif images
- mimeTypes = arrayOf(
- "image/png",
- "image/jpg",
- "image/jpeg"
- )
- )
- .createIntent { imageResult.launch(it) }
- }
-
- binding.tvMale.setOnClickListener {
- viewModel.changeGender(Gender.MALE)
- }
-
- binding.tvFemale.setOnClickListener {
- viewModel.changeGender(Gender.FEMALE)
- }
-
- binding.tvNone.setOnClickListener {
- viewModel.changeGender(Gender.NONE)
+ binding.etEmail.post {
+ binding.etEmail.requestFocus()
+ imm.showSoftInput(binding.etEmail, InputMethodManager.SHOW_IMPLICIT)
}
binding.tvTermsOfService.setOnClickListener {
@@ -108,15 +59,14 @@ class SignUpActivity : BaseActivity(ActivitySignupBinding
startActivity(intent)
}
- binding.ivTermsOfService.setOnClickListener {
- viewModel.onClickCheckboxTermsOfService()
- }
+ binding.rlTermsOfService.setOnClickListener { viewModel.onClickCheckboxTermsOfService() }
+ binding.ivTermsOfService.setOnClickListener { viewModel.onClickCheckboxTermsOfService() }
- binding.ivPrivacyPolicy.setOnClickListener {
- viewModel.onClickCheckboxPrivacyPolicy()
- }
+ binding.rlPrivacyPolicy.setOnClickListener { viewModel.onClickCheckboxPrivacyPolicy() }
+ binding.ivPrivacyPolicy.setOnClickListener { viewModel.onClickCheckboxPrivacyPolicy() }
binding.tvSignUp.setOnClickListener {
+ hideKeyboard()
viewModel.signUp {
it?.let { Toast.makeText(applicationContext, it, Toast.LENGTH_LONG).show() }
finishAffinity()
@@ -154,24 +104,6 @@ class SignUpActivity : BaseActivity(ActivitySignupBinding
}
)
- compositeDisposable.add(
- binding.etPasswordRe.textChanges().skip(1)
- .subscribeOn(Schedulers.io())
- .observeOn(AndroidSchedulers.mainThread())
- .subscribe {
- viewModel.passwordRe = it.toString()
- }
- )
-
- compositeDisposable.add(
- binding.etNickname.textChanges().skip(1)
- .subscribeOn(Schedulers.io())
- .observeOn(AndroidSchedulers.mainThread())
- .subscribe {
- viewModel.nickname = it.toString()
- }
- )
-
viewModel.isAgreeTermsOfServiceLiveData.observe(this) {
binding.ivTermsOfService.isSelected = it
}
@@ -180,40 +112,19 @@ class SignUpActivity : BaseActivity(ActivitySignupBinding
binding.ivPrivacyPolicy.isSelected = it
}
- viewModel.genderLiveData.observe(this) {
- binding.tvMale.isSelected = false
- binding.tvFemale.isSelected = false
- binding.tvNone.isSelected = false
-
- when (it) {
- Gender.MALE -> binding.tvMale.isSelected = true
- Gender.FEMALE -> binding.tvFemale.isSelected = true
- Gender.NONE -> binding.tvNone.isSelected = true
- else -> {
- }
- }
- }
-
viewModel.signUpErrorLiveData.observe(this) {
Toast.makeText(applicationContext, it.message, Toast.LENGTH_LONG).show()
when (it.errorProperty) {
"email" -> {
- viewModel.setStep(step = SignUpViewModel.EmailSignUpStep.STEP_1)
binding.etEmail.error = it.message
binding.etEmail.requestFocus()
}
"password" -> {
- viewModel.setStep(step = SignUpViewModel.EmailSignUpStep.STEP_1)
binding.etPassword.error = it.message
binding.etPassword.requestFocus()
}
-
- "nickname" -> {
- binding.etNickname.error = it.message
- binding.etNickname.requestFocus()
- }
}
}
@@ -228,27 +139,14 @@ class SignUpActivity : BaseActivity(ActivitySignupBinding
viewModel.toastLiveData.observe(this) {
it?.let { Toast.makeText(applicationContext, it, Toast.LENGTH_LONG).show() }
}
-
- viewModel.stepLiveData.observe(this) {
- if (it == SignUpViewModel.EmailSignUpStep.STEP_2) {
- binding.toolbar.tvBack.text = "프로필 설정"
- binding.tvSignUp.text = "회원가입"
- binding.llStep1.visibility = View.GONE
- binding.llStep2.visibility = View.VISIBLE
- } else {
- binding.toolbar.tvBack.text = "회원가입"
- binding.tvSignUp.text = "다음"
- binding.llStep1.visibility = View.VISIBLE
- binding.llStep2.visibility = View.GONE
- }
- }
}
- private fun onClickBackButton() {
- if (viewModel.stepLiveData.value!! == SignUpViewModel.EmailSignUpStep.STEP_2) {
- viewModel.setStep(SignUpViewModel.EmailSignUpStep.STEP_1)
- } else {
- finish()
- }
+ private fun hideKeyboard() {
+ handler.postDelayed({
+ imm.hideSoftInputFromWindow(
+ window.decorView.applicationWindowToken,
+ InputMethodManager.HIDE_NOT_ALWAYS
+ )
+ }, 100)
}
}
diff --git a/app/src/main/java/kr/co/vividnext/sodalive/user/signup/SignUpRequest.kt b/app/src/main/java/kr/co/vividnext/sodalive/user/signup/SignUpRequest.kt
index 3df7a24..188f7af 100644
--- a/app/src/main/java/kr/co/vividnext/sodalive/user/signup/SignUpRequest.kt
+++ b/app/src/main/java/kr/co/vividnext/sodalive/user/signup/SignUpRequest.kt
@@ -2,14 +2,11 @@ package kr.co.vividnext.sodalive.user.signup
import androidx.annotation.Keep
import com.google.gson.annotations.SerializedName
-import kr.co.vividnext.sodalive.user.Gender
@Keep
data class SignUpRequest(
@SerializedName("email") val email: String,
@SerializedName("password") val password: String,
- @SerializedName("nickname") val nickname: String,
- @SerializedName("gender") val gender: Gender,
@SerializedName("marketingPid") val marketingPid: String,
@SerializedName("isAgreeTermsOfService") val isAgreeTermsOfService: Boolean,
@SerializedName("isAgreePrivacyPolicy") val isAgreePrivacyPolicy: Boolean,
diff --git a/app/src/main/java/kr/co/vividnext/sodalive/user/signup/SignUpViewModel.kt b/app/src/main/java/kr/co/vividnext/sodalive/user/signup/SignUpViewModel.kt
index eb68329..5c0b06d 100644
--- a/app/src/main/java/kr/co/vividnext/sodalive/user/signup/SignUpViewModel.kt
+++ b/app/src/main/java/kr/co/vividnext/sodalive/user/signup/SignUpViewModel.kt
@@ -1,42 +1,19 @@
package kr.co.vividnext.sodalive.user.signup
-import android.net.Uri
import androidx.core.util.PatternsCompat
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
-import com.google.gson.Gson
-import com.google.gson.annotations.SerializedName
import com.orhanobut.logger.Logger
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import io.reactivex.rxjava3.schedulers.Schedulers
import kr.co.vividnext.sodalive.base.BaseViewModel
import kr.co.vividnext.sodalive.common.SharedPreferenceManager
import kr.co.vividnext.sodalive.tracking.FirebaseTracking
-import kr.co.vividnext.sodalive.user.Gender
import kr.co.vividnext.sodalive.user.UserRepository
-import okhttp3.MediaType.Companion.toMediaType
-import okhttp3.MultipartBody
-import okhttp3.RequestBody.Companion.asRequestBody
-import okhttp3.RequestBody.Companion.toRequestBody
-import java.io.File
class SignUpViewModel(private val repository: UserRepository) : BaseViewModel() {
- enum class EmailSignUpStep {
- @SerializedName("STEP_1")
- STEP_1,
- @SerializedName("STEP_2")
- STEP_2
- }
-
var email = ""
var password = ""
- var passwordRe = ""
- var nickname = ""
- var profileImageUri: Uri? = null
-
- private val _genderLiveData = MutableLiveData(Gender.NONE)
- val genderLiveData: LiveData
- get() = _genderLiveData
private val _isAgreeTermsOfServiceLiveData = MutableLiveData(false)
val isAgreeTermsOfServiceLiveData: LiveData
@@ -58,55 +35,19 @@ class SignUpViewModel(private val repository: UserRepository) : BaseViewModel()
val isLoading: LiveData
get() = _isLoading
- private val _stepLiveData = MutableLiveData(EmailSignUpStep.STEP_1)
- val stepLiveData: LiveData
- get() = _stepLiveData
-
- lateinit var getRealPathFromURI: (Uri) -> String?
-
- fun setStep(step: EmailSignUpStep = EmailSignUpStep.STEP_2) {
- _stepLiveData.postValue(step)
- }
-
fun signUp(onSuccess: (String?) -> Unit) {
- if (stepLiveData.value!! == EmailSignUpStep.STEP_1) {
- if (validationStep1()) return
-
- setStep()
- return
- }
-
- if (validationStep2()) return
-
+ if (!validation()) return
val request = SignUpRequest(
email = email,
password = password,
- nickname = nickname,
- gender = _genderLiveData.value!!,
marketingPid = SharedPreferenceManager.marketingPid,
isAgreeTermsOfService = _isAgreeTermsOfServiceLiveData.value!!,
isAgreePrivacyPolicy = _isAgreePrivacyPolicyLiveData.value!!
)
- val requestJson = Gson().toJson(request)
-
- val profileImage = if (profileImageUri != null) {
- val file = File(getRealPathFromURI(profileImageUri!!))
- MultipartBody.Part.createFormData(
- "profileImage",
- file.name,
- file.asRequestBody("image/*".toMediaType())
- )
- } else {
- null
- }
-
_isLoading.value = true
compositeDisposable.add(
- repository.signUp(
- profileImage,
- requestJson.toRequestBody("text/plain".toMediaType())
- )
+ repository.signUp(request)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
@@ -140,7 +81,7 @@ class SignUpViewModel(private val repository: UserRepository) : BaseViewModel()
)
}
- private fun validationStep1(): Boolean {
+ private fun validation(): Boolean {
if (email.isBlank()) {
_signUpErrorLiveData.postValue(
SignUpError(
@@ -149,7 +90,7 @@ class SignUpViewModel(private val repository: UserRepository) : BaseViewModel()
)
)
- return true
+ return false
}
if (password.isBlank()) {
@@ -160,18 +101,7 @@ class SignUpViewModel(private val repository: UserRepository) : BaseViewModel()
)
)
- return true
- }
-
- if (password != passwordRe) {
- _signUpErrorLiveData.postValue(
- SignUpError(
- "password",
- "비밀번호가 일치하지 않습니다."
- )
- )
-
- return true
+ return false
}
if (
@@ -185,7 +115,7 @@ class SignUpViewModel(private val repository: UserRepository) : BaseViewModel()
)
)
- return true
+ return false
}
if (!PatternsCompat.EMAIL_ADDRESS.matcher(email).matches()) {
@@ -196,7 +126,7 @@ class SignUpViewModel(private val repository: UserRepository) : BaseViewModel()
)
)
- return true
+ return false
}
if (
@@ -211,24 +141,11 @@ class SignUpViewModel(private val repository: UserRepository) : BaseViewModel()
"영문, 숫자 포함 8자 이상의 비밀번호를 입력해 주세요."
)
)
+
+ return false
}
- return false
- }
-
- private fun validationStep2(): Boolean {
- if (nickname.isBlank() || nickname.length < 2) {
- _signUpErrorLiveData.postValue(
- SignUpError(
- "nickname",
- "닉네임은 2자 이상 입력해 주세요."
- )
- )
-
- return true
- }
-
- return false
+ return true
}
fun onClickCheckboxTermsOfService() {
@@ -238,8 +155,4 @@ class SignUpViewModel(private val repository: UserRepository) : BaseViewModel()
fun onClickCheckboxPrivacyPolicy() {
_isAgreePrivacyPolicyLiveData.postValue(!_isAgreePrivacyPolicyLiveData.value!!)
}
-
- fun changeGender(gender: Gender) {
- _genderLiveData.postValue(gender)
- }
}
diff --git a/app/src/main/res/layout/activity_login.xml b/app/src/main/res/layout/activity_login.xml
index fad02f0..d998fe4 100644
--- a/app/src/main/res/layout/activity_login.xml
+++ b/app/src/main/res/layout/activity_login.xml
@@ -104,8 +104,9 @@
android:id="@+id/tv_forgot_password"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_marginTop="40dp"
+ android:layout_marginTop="30dp"
android:fontFamily="@font/gmarket_sans_medium"
+ android:paddingVertical="10dp"
android:text="비밀번호를 잊으셨나요?"
android:textColor="@color/color_bbbbbb"
android:textSize="13.3sp" />
@@ -116,6 +117,7 @@
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:fontFamily="@font/gmarket_sans_medium"
+ android:paddingVertical="10dp"
android:text="보이스온 회원이 아닌가요? 지금 가입하세요."
android:textColor="@color/color_bbbbbb"
android:textSize="13.3sp" />
diff --git a/app/src/main/res/layout/activity_signup.xml b/app/src/main/res/layout/activity_signup.xml
index 1e5078d..e83d642 100644
--- a/app/src/main/res/layout/activity_signup.xml
+++ b/app/src/main/res/layout/activity_signup.xml
@@ -1,7 +1,6 @@
-
+ android:layout_marginHorizontal="13.3dp"
+ android:layout_marginTop="20dp"
+ 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">
-
+ android:fontFamily="@font/gmarket_sans_medium"
+ android:importantForAutofill="no"
+ android:inputType="textEmailAddress"
+ android:paddingVertical="16dp"
+ android:textColor="@color/color_eeeeee"
+ android:textSize="15sp" />
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ 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">
-
+
+
-
+
-
+
+
+
+
-
+ android:fontFamily="@font/gmarket_sans_medium"
+ android:text="이용약관"
+ android:textColor="@color/color_eeeeee"
+ android:textSize="12sp" />
+
+
+
+
+
+
+
+
+ android:layout_centerVertical="true"
+ android:layout_marginStart="10dp"
+ android:layout_toEndOf="@+id/iv_privacy_policy">
-
+ android:fontFamily="@font/gmarket_sans_medium"
+ android:text="개인정보수집 및 이용동의"
+ android:textColor="@color/color_eeeeee"
+ android:textSize="12sp" />
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ android:layout_marginStart="6.7dp"
+ android:fontFamily="@font/gmarket_sans_medium"
+ android:text="(필수)"
+ android:textColor="@color/color_3bb9f1"
+ android:textSize="12sp" />
-
+
-
-
-
-
-
+ android:background="@drawable/bg_round_corner_10_3bb9f1"
+ android:fontFamily="@font/gmarket_sans_bold"
+ android:gravity="center"
+ android:paddingVertical="16dp"
+ android:text="회원가입"
+ android:textColor="@color/white"
+ android:textSize="18.3sp" />