캔 충전페이지

- 인 앱 결제 추가를 위해 단일 액티비티에서 탭 구성으로 변경
This commit is contained in:
klaus 2024-03-20 01:24:39 +09:00
parent 84b9dd0841
commit 79cb4b995a
13 changed files with 229 additions and 111 deletions

View File

@ -74,7 +74,7 @@ import kr.co.vividnext.sodalive.mypage.auth.AuthApi
import kr.co.vividnext.sodalive.mypage.auth.AuthRepository import kr.co.vividnext.sodalive.mypage.auth.AuthRepository
import kr.co.vividnext.sodalive.mypage.can.CanApi import kr.co.vividnext.sodalive.mypage.can.CanApi
import kr.co.vividnext.sodalive.mypage.can.CanRepository import kr.co.vividnext.sodalive.mypage.can.CanRepository
import kr.co.vividnext.sodalive.mypage.can.charge.CanChargeViewModel import kr.co.vividnext.sodalive.mypage.can.charge.pg.CanChargePgViewModel
import kr.co.vividnext.sodalive.mypage.can.coupon.CanCouponViewModel import kr.co.vividnext.sodalive.mypage.can.coupon.CanCouponViewModel
import kr.co.vividnext.sodalive.mypage.can.payment.CanPaymentViewModel import kr.co.vividnext.sodalive.mypage.can.payment.CanPaymentViewModel
import kr.co.vividnext.sodalive.mypage.can.status.CanStatusViewModel import kr.co.vividnext.sodalive.mypage.can.status.CanStatusViewModel
@ -178,7 +178,7 @@ class AppDI(private val context: Context, isDebugMode: Boolean) {
viewModel { LiveViewModel(get(), get(), get(), get()) } viewModel { LiveViewModel(get(), get(), get(), get()) }
viewModel { MyPageViewModel(get(), get()) } viewModel { MyPageViewModel(get(), get()) }
viewModel { CanStatusViewModel(get()) } viewModel { CanStatusViewModel(get()) }
viewModel { CanChargeViewModel(get()) } viewModel { CanChargePgViewModel(get()) }
viewModel { CanPaymentViewModel(get()) } viewModel { CanPaymentViewModel(get()) }
viewModel { LiveRoomDetailViewModel(get()) } viewModel { LiveRoomDetailViewModel(get()) }
viewModel { LiveRoomCreateViewModel(get()) } viewModel { LiveRoomCreateViewModel(get()) }

View File

@ -2,10 +2,10 @@ package kr.co.vividnext.sodalive.mypage.can
import io.reactivex.rxjava3.core.Single import io.reactivex.rxjava3.core.Single
import kr.co.vividnext.sodalive.common.ApiResponse import kr.co.vividnext.sodalive.common.ApiResponse
import kr.co.vividnext.sodalive.mypage.can.charge.CanResponse import kr.co.vividnext.sodalive.mypage.can.charge.pg.CanResponse
import kr.co.vividnext.sodalive.mypage.can.charge.ChargeRequest import kr.co.vividnext.sodalive.mypage.can.charge.pg.ChargeRequest
import kr.co.vividnext.sodalive.mypage.can.charge.ChargeResponse import kr.co.vividnext.sodalive.mypage.can.charge.pg.ChargeResponse
import kr.co.vividnext.sodalive.mypage.can.charge.VerifyRequest import kr.co.vividnext.sodalive.mypage.can.charge.pg.VerifyRequest
import kr.co.vividnext.sodalive.mypage.can.coupon.UseCanCouponRequest import kr.co.vividnext.sodalive.mypage.can.coupon.UseCanCouponRequest
import kr.co.vividnext.sodalive.mypage.can.status.GetCanStatusResponse import kr.co.vividnext.sodalive.mypage.can.status.GetCanStatusResponse
import kr.co.vividnext.sodalive.mypage.can.status.charge.GetCanChargeStatusResponseItem import kr.co.vividnext.sodalive.mypage.can.status.charge.GetCanChargeStatusResponseItem

View File

@ -1,7 +1,7 @@
package kr.co.vividnext.sodalive.mypage.can package kr.co.vividnext.sodalive.mypage.can
import kr.co.vividnext.sodalive.mypage.can.charge.ChargeRequest import kr.co.vividnext.sodalive.mypage.can.charge.pg.ChargeRequest
import kr.co.vividnext.sodalive.mypage.can.charge.VerifyRequest import kr.co.vividnext.sodalive.mypage.can.charge.pg.VerifyRequest
import kr.co.vividnext.sodalive.mypage.can.coupon.UseCanCouponRequest import kr.co.vividnext.sodalive.mypage.can.coupon.UseCanCouponRequest
import java.util.TimeZone import java.util.TimeZone

View File

@ -1,33 +1,26 @@
package kr.co.vividnext.sodalive.mypage.can.charge package kr.co.vividnext.sodalive.mypage.can.charge
import android.annotation.SuppressLint
import android.app.Activity import android.app.Activity
import android.content.Intent import android.content.Intent
import android.graphics.Rect
import android.os.Bundle import android.os.Bundle
import android.view.View import android.view.View
import android.widget.Toast
import androidx.activity.result.ActivityResultLauncher import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.result.contract.ActivityResultContracts
import androidx.recyclerview.widget.LinearLayoutManager import com.google.android.material.tabs.TabLayout
import androidx.recyclerview.widget.RecyclerView import kr.co.vividnext.sodalive.R
import kr.co.vividnext.sodalive.base.BaseActivity import kr.co.vividnext.sodalive.base.BaseActivity
import kr.co.vividnext.sodalive.common.Constants import kr.co.vividnext.sodalive.common.Constants
import kr.co.vividnext.sodalive.common.LoadingDialog import kr.co.vividnext.sodalive.common.SharedPreferenceManager
import kr.co.vividnext.sodalive.databinding.ActivityCanChargeBinding import kr.co.vividnext.sodalive.databinding.ActivityCanChargeBinding
import kr.co.vividnext.sodalive.extensions.dpToPx import kr.co.vividnext.sodalive.mypage.can.charge.pg.CanChargePgFragment
import kr.co.vividnext.sodalive.mypage.can.charge.pg.CanResponse
import kr.co.vividnext.sodalive.mypage.can.payment.CanPaymentActivity import kr.co.vividnext.sodalive.mypage.can.payment.CanPaymentActivity
import org.koin.android.ext.android.inject
class CanChargeActivity : BaseActivity<ActivityCanChargeBinding>( class CanChargeActivity : BaseActivity<ActivityCanChargeBinding>(
ActivityCanChargeBinding::inflate ActivityCanChargeBinding::inflate
) { ) {
private val viewModel: CanChargeViewModel by inject()
private var gotoPrevPage: Boolean = false private var gotoPrevPage: Boolean = false
private lateinit var adapter: CanChargeAdapter
private lateinit var loadingDialog: LoadingDialog
private lateinit var activityResultLauncher: ActivityResultLauncher<Intent> private lateinit var activityResultLauncher: ActivityResultLauncher<Intent>
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
@ -40,87 +33,86 @@ class CanChargeActivity : BaseActivity<ActivityCanChargeBinding>(
} }
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
bindData()
viewModel.getCanCharges()
}
override fun setupView() {
loadingDialog = LoadingDialog(this, layoutInflater)
binding.toolbar.tvBack.text = "충전하기"
binding.toolbar.tvBack.setOnClickListener { finish() }
gotoPrevPage = intent.getBooleanExtra( gotoPrevPage = intent.getBooleanExtra(
Constants.EXTRA_GO_TO_PREV_PAGE, Constants.EXTRA_GO_TO_PREV_PAGE,
false false
) )
val recyclerView = binding.rvChargeCan changeFragment(PG_TAG_KEY)
adapter = CanChargeAdapter {
val intent = Intent(applicationContext, CanPaymentActivity::class.java)
intent.putExtra(Constants.EXTRA_CAN, it)
intent.putExtra(Constants.EXTRA_GO_TO_PREV_PAGE, gotoPrevPage)
activityResultLauncher.launch(intent)
}
recyclerView.layoutManager = LinearLayoutManager(
applicationContext,
LinearLayoutManager.VERTICAL,
false
)
recyclerView.addItemDecoration(object : RecyclerView.ItemDecoration() {
override fun getItemOffsets(
outRect: Rect,
view: View,
parent: RecyclerView,
state: RecyclerView.State
) {
super.getItemOffsets(outRect, view, parent, state)
outRect.left = 13.3f.dpToPx().toInt()
outRect.right = 13.3f.dpToPx().toInt()
when (parent.getChildAdapterPosition(view)) {
0 -> {
outRect.top = 13.3f.dpToPx().toInt()
outRect.bottom = 6.7f.dpToPx().toInt()
}
adapter.itemCount - 1 -> {
outRect.top = 6.7f.dpToPx().toInt()
outRect.bottom = 26.7f.dpToPx().toInt()
}
else -> {
outRect.top = 6.7f.dpToPx().toInt()
outRect.bottom = 6.7f.dpToPx().toInt()
}
}
}
})
recyclerView.adapter = adapter
} }
@SuppressLint("NotifyDataSetChanged") override fun setupView() {
private fun bindData() { setupToolbar()
viewModel.canChargeLiveData.observe(this) { setupTabs()
adapter.items.addAll(it) }
adapter.notifyDataSetChanged()
private fun setupToolbar() {
binding.toolbar.tvBack.text = "충전하기"
binding.toolbar.tvBack.setOnClickListener { finish() }
}
private fun setupTabs() {
if (SharedPreferenceManager.isAuth) {
val tabs = binding.tabs
tabs.visibility = View.GONE
tabs.addTab(tabs.newTab().setText("인 앱 결제").setTag(IAP_TAG_KEY))
tabs.addTab(tabs.newTab().setText("PG").setTag(PG_TAG_KEY))
tabs.addOnTabSelectedListener(object : TabLayout.OnTabSelectedListener {
override fun onTabSelected(tab: TabLayout.Tab) {
val tag = tab.tag as String
changeFragment(tag)
}
override fun onTabUnselected(tab: TabLayout.Tab) {
}
override fun onTabReselected(tab: TabLayout.Tab) {
}
})
} else {
binding.tabs.visibility = View.GONE
}
}
private fun changeFragment(tag: String) {
val fragmentManager = supportFragmentManager
val fragmentTransaction = fragmentManager.beginTransaction()
val currentFragment = fragmentManager.primaryNavigationFragment
if (currentFragment != null) {
fragmentTransaction.hide(currentFragment)
} }
viewModel.toastLiveData.observe(this) { var fragment = fragmentManager.findFragmentByTag(tag)
it?.let { Toast.makeText(applicationContext, it, Toast.LENGTH_LONG).show() } if (fragment == null) {
} fragment = if (tag == PG_TAG_KEY) {
CanChargePgFragment()
viewModel.isLoading.observe(this) {
if (it) {
loadingDialog.show(screenWidth)
} else { } else {
loadingDialog.dismiss() CanChargePgFragment()
} }
fragmentTransaction.add(R.id.fl_container, fragment, tag)
} else {
fragmentTransaction.show(fragment)
} }
fragmentTransaction.setPrimaryNavigationFragment(fragment)
fragmentTransaction.setReorderingAllowed(true)
fragmentTransaction.commitNow()
}
fun selectCan(model: CanResponse) {
val intent = Intent(applicationContext, CanPaymentActivity::class.java)
intent.putExtra(Constants.EXTRA_CAN, model)
intent.putExtra(Constants.EXTRA_GO_TO_PREV_PAGE, gotoPrevPage)
activityResultLauncher.launch(intent)
}
companion object {
const val IAP_TAG_KEY = "iap"
const val PG_TAG_KEY = "pg"
} }
} }

View File

@ -1,4 +1,4 @@
package kr.co.vividnext.sodalive.mypage.can.charge package kr.co.vividnext.sodalive.mypage.can.charge.pg
import android.content.Context import android.content.Context
import android.view.LayoutInflater import android.view.LayoutInflater
@ -10,9 +10,9 @@ import kr.co.vividnext.sodalive.databinding.ItemCanChargeBinding
import kr.co.vividnext.sodalive.extensions.fontSpan import kr.co.vividnext.sodalive.extensions.fontSpan
import kr.co.vividnext.sodalive.extensions.moneyFormat import kr.co.vividnext.sodalive.extensions.moneyFormat
class CanChargeAdapter( class CanChargePgAdapter(
private val onClick: (CanResponse) -> Unit private val onClick: (CanResponse) -> Unit
) : RecyclerView.Adapter<CanChargeAdapter.ViewHolder>() { ) : RecyclerView.Adapter<CanChargePgAdapter.ViewHolder>() {
val items = mutableListOf<CanResponse>() val items = mutableListOf<CanResponse>()

View File

@ -0,0 +1,101 @@
package kr.co.vividnext.sodalive.mypage.can.charge.pg
import android.annotation.SuppressLint
import android.graphics.Rect
import android.os.Bundle
import android.view.View
import android.widget.Toast
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import kr.co.vividnext.sodalive.base.BaseFragment
import kr.co.vividnext.sodalive.common.LoadingDialog
import kr.co.vividnext.sodalive.databinding.FragmentCanChargePgBinding
import kr.co.vividnext.sodalive.extensions.dpToPx
import kr.co.vividnext.sodalive.mypage.can.charge.CanChargeActivity
import org.koin.android.ext.android.inject
class CanChargePgFragment : BaseFragment<FragmentCanChargePgBinding>(
FragmentCanChargePgBinding::inflate
) {
private val viewModel: CanChargePgViewModel by inject()
private lateinit var adapter: CanChargePgAdapter
private lateinit var loadingDialog: LoadingDialog
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
setupView()
bindData()
viewModel.getCanCharges()
}
fun setupView() {
loadingDialog = LoadingDialog(requireActivity(), layoutInflater)
val recyclerView = binding.rvChargeCan
adapter = CanChargePgAdapter {
(requireActivity() as CanChargeActivity).selectCan(it)
}
recyclerView.layoutManager = LinearLayoutManager(
requireContext(),
LinearLayoutManager.VERTICAL,
false
)
recyclerView.addItemDecoration(object : RecyclerView.ItemDecoration() {
override fun getItemOffsets(
outRect: Rect,
view: View,
parent: RecyclerView,
state: RecyclerView.State
) {
super.getItemOffsets(outRect, view, parent, state)
outRect.left = 13.3f.dpToPx().toInt()
outRect.right = 13.3f.dpToPx().toInt()
when (parent.getChildAdapterPosition(view)) {
0 -> {
outRect.top = 13.3f.dpToPx().toInt()
outRect.bottom = 6.7f.dpToPx().toInt()
}
adapter.itemCount - 1 -> {
outRect.top = 6.7f.dpToPx().toInt()
outRect.bottom = 26.7f.dpToPx().toInt()
}
else -> {
outRect.top = 6.7f.dpToPx().toInt()
outRect.bottom = 6.7f.dpToPx().toInt()
}
}
}
})
recyclerView.adapter = adapter
}
@SuppressLint("NotifyDataSetChanged")
private fun bindData() {
viewModel.canChargeLiveData.observe(this) {
adapter.items.addAll(it)
adapter.notifyDataSetChanged()
}
viewModel.toastLiveData.observe(this) {
it?.let { Toast.makeText(requireActivity(), it, Toast.LENGTH_LONG).show() }
}
viewModel.isLoading.observe(this) {
if (it) {
loadingDialog.show(screenWidth)
} else {
loadingDialog.dismiss()
}
}
}
}

View File

@ -1,4 +1,4 @@
package kr.co.vividnext.sodalive.mypage.can.charge package kr.co.vividnext.sodalive.mypage.can.charge.pg
import androidx.lifecycle.LiveData import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
@ -9,7 +9,7 @@ import kr.co.vividnext.sodalive.base.BaseViewModel
import kr.co.vividnext.sodalive.common.SharedPreferenceManager import kr.co.vividnext.sodalive.common.SharedPreferenceManager
import kr.co.vividnext.sodalive.mypage.can.CanRepository import kr.co.vividnext.sodalive.mypage.can.CanRepository
class CanChargeViewModel(private val repository: CanRepository) : BaseViewModel() { class CanChargePgViewModel(private val repository: CanRepository) : BaseViewModel() {
private val _canChargesLiveData = MutableLiveData<List<CanResponse>>() private val _canChargesLiveData = MutableLiveData<List<CanResponse>>()
val canChargeLiveData: LiveData<List<CanResponse>> val canChargeLiveData: LiveData<List<CanResponse>>
get() = _canChargesLiveData get() = _canChargesLiveData

View File

@ -1,4 +1,4 @@
package kr.co.vividnext.sodalive.mypage.can.charge package kr.co.vividnext.sodalive.mypage.can.charge.pg
import android.os.Parcelable import android.os.Parcelable
import com.google.gson.annotations.SerializedName import com.google.gson.annotations.SerializedName

View File

@ -1,4 +1,4 @@
package kr.co.vividnext.sodalive.mypage.can.charge package kr.co.vividnext.sodalive.mypage.can.charge.pg
import com.google.gson.annotations.SerializedName import com.google.gson.annotations.SerializedName
import kr.co.vividnext.sodalive.mypage.can.payment.PaymentGateway import kr.co.vividnext.sodalive.mypage.can.payment.PaymentGateway

View File

@ -23,8 +23,8 @@ import kr.co.vividnext.sodalive.databinding.ActivityCanPaymentBinding
import kr.co.vividnext.sodalive.extensions.fontSpan import kr.co.vividnext.sodalive.extensions.fontSpan
import kr.co.vividnext.sodalive.extensions.moneyFormat import kr.co.vividnext.sodalive.extensions.moneyFormat
import kr.co.vividnext.sodalive.mypage.auth.BootpayResponse import kr.co.vividnext.sodalive.mypage.auth.BootpayResponse
import kr.co.vividnext.sodalive.mypage.can.charge.CanResponse import kr.co.vividnext.sodalive.mypage.can.charge.pg.CanResponse
import kr.co.vividnext.sodalive.mypage.can.charge.VerifyRequest import kr.co.vividnext.sodalive.mypage.can.charge.pg.VerifyRequest
import kr.co.vividnext.sodalive.mypage.can.status.CanStatusActivity import kr.co.vividnext.sodalive.mypage.can.status.CanStatusActivity
import org.koin.android.ext.android.inject import org.koin.android.ext.android.inject

View File

@ -8,8 +8,8 @@ import io.reactivex.rxjava3.schedulers.Schedulers
import kr.co.vividnext.sodalive.base.BaseViewModel import kr.co.vividnext.sodalive.base.BaseViewModel
import kr.co.vividnext.sodalive.common.SharedPreferenceManager import kr.co.vividnext.sodalive.common.SharedPreferenceManager
import kr.co.vividnext.sodalive.mypage.can.CanRepository import kr.co.vividnext.sodalive.mypage.can.CanRepository
import kr.co.vividnext.sodalive.mypage.can.charge.ChargeRequest import kr.co.vividnext.sodalive.mypage.can.charge.pg.ChargeRequest
import kr.co.vividnext.sodalive.mypage.can.charge.VerifyRequest import kr.co.vividnext.sodalive.mypage.can.charge.pg.VerifyRequest
class CanPaymentViewModel(private val repository: CanRepository) : BaseViewModel() { class CanPaymentViewModel(private val repository: CanRepository) : BaseViewModel() {

View File

@ -1,20 +1,29 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"> android:orientation="vertical">
<include <include
android:id="@+id/toolbar" android:id="@+id/toolbar"
layout="@layout/detail_toolbar" /> layout="@layout/detail_toolbar" />
<androidx.recyclerview.widget.RecyclerView <com.google.android.material.tabs.TabLayout
android:id="@+id/rv_charge_can" android:id="@+id/tabs"
android:layout_width="0dp" android:layout_width="match_parent"
android:layout_height="0dp" android:layout_height="50dp"
app:layout_constraintBottom_toBottomOf="parent" android:visibility="gone"
app:layout_constraintEnd_toEndOf="parent" app:tabIndicatorColor="@color/color_80d8ff"
app:layout_constraintStart_toStartOf="parent" app:tabIndicatorFullWidth="true"
app:layout_constraintTop_toBottomOf="@+id/toolbar" /> app:tabIndicatorHeight="1.3dp"
app:tabSelectedTextColor="@color/color_eeeeee"
app:tabTextAppearance="@style/tabText"
app:tabTextColor="@color/color_777777" />
</androidx.constraintlayout.widget.ConstraintLayout> <FrameLayout
android:id="@+id/fl_container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_charge_can"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>