라이브 메인 - UI, Api 적용
|
@ -98,7 +98,7 @@ dependencies {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gson
|
// Gson
|
||||||
implementation "com.google.code.gson:gson:2.9.0"
|
implementation "com.google.code.gson:gson:2.9.1"
|
||||||
|
|
||||||
// Network
|
// Network
|
||||||
implementation "com.squareup.retrofit2:retrofit:2.9.0"
|
implementation "com.squareup.retrofit2:retrofit:2.9.0"
|
||||||
|
@ -115,6 +115,7 @@ dependencies {
|
||||||
implementation "io.github.ParkSangGwon:tedpermission-normal:3.3.0"
|
implementation "io.github.ParkSangGwon:tedpermission-normal:3.3.0"
|
||||||
|
|
||||||
implementation 'com.github.dhaval2404:imagepicker:2.1'
|
implementation 'com.github.dhaval2404:imagepicker:2.1'
|
||||||
|
implementation 'com.github.zhpanvip:bannerviewpager:3.5.7'
|
||||||
|
|
||||||
implementation 'com.google.android.gms:play-services-oss-licenses:17.0.1'
|
implementation 'com.google.android.gms:play-services-oss-licenses:17.0.1'
|
||||||
|
|
||||||
|
|
|
@ -10,11 +10,12 @@ object Constants {
|
||||||
const val PREF_USER_ROLE = "pref_user_role"
|
const val PREF_USER_ROLE = "pref_user_role"
|
||||||
const val PREF_PUSH_TOKEN = "pref_push_token"
|
const val PREF_PUSH_TOKEN = "pref_push_token"
|
||||||
const val PREF_PROFILE_IMAGE = "pref_profile_image"
|
const val PREF_PROFILE_IMAGE = "pref_profile_image"
|
||||||
|
const val PREF_IS_FOLLOWED_CREATOR_LIVE = "pref_is_followed_creator_live"
|
||||||
|
|
||||||
const val EXTRA_DATA = "extra_data"
|
const val EXTRA_DATA = "extra_data"
|
||||||
const val EXTRA_TERMS = "extra_terms"
|
const val EXTRA_TERMS = "extra_terms"
|
||||||
const val EXTRA_USER_ID = "extra_user_id"
|
|
||||||
const val EXTRA_ROOM_ID = "extra_room_id"
|
const val EXTRA_ROOM_ID = "extra_room_id"
|
||||||
|
const val EXTRA_USER_ID = "extra_user_id"
|
||||||
const val EXTRA_MESSAGE_ID = "extra_message_id"
|
const val EXTRA_MESSAGE_ID = "extra_message_id"
|
||||||
|
|
||||||
const val EXTRA_CONTENT_ID = "extra_content_id"
|
const val EXTRA_CONTENT_ID = "extra_content_id"
|
||||||
|
|
|
@ -98,4 +98,10 @@ object SharedPreferenceManager {
|
||||||
set(value) {
|
set(value) {
|
||||||
sharedPreferences[Constants.PREF_PUSH_TOKEN] = value
|
sharedPreferences[Constants.PREF_PUSH_TOKEN] = value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var isFollowedCreatorLive: Boolean
|
||||||
|
get() = sharedPreferences[Constants.PREF_IS_FOLLOWED_CREATOR_LIVE, false]
|
||||||
|
set(value) {
|
||||||
|
sharedPreferences[Constants.PREF_IS_FOLLOWED_CREATOR_LIVE] = value
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,8 +4,15 @@ import android.content.Context
|
||||||
import com.google.gson.GsonBuilder
|
import com.google.gson.GsonBuilder
|
||||||
import kr.co.vividnext.sodalive.BuildConfig
|
import kr.co.vividnext.sodalive.BuildConfig
|
||||||
import kr.co.vividnext.sodalive.common.ApiBuilder
|
import kr.co.vividnext.sodalive.common.ApiBuilder
|
||||||
|
import kr.co.vividnext.sodalive.live.LiveApi
|
||||||
|
import kr.co.vividnext.sodalive.live.LiveRepository
|
||||||
|
import kr.co.vividnext.sodalive.live.LiveViewModel
|
||||||
|
import kr.co.vividnext.sodalive.live.recommend.LiveRecommendApi
|
||||||
|
import kr.co.vividnext.sodalive.live.recommend.LiveRecommendRepository
|
||||||
import kr.co.vividnext.sodalive.main.MainViewModel
|
import kr.co.vividnext.sodalive.main.MainViewModel
|
||||||
import kr.co.vividnext.sodalive.network.TokenAuthenticator
|
import kr.co.vividnext.sodalive.network.TokenAuthenticator
|
||||||
|
import kr.co.vividnext.sodalive.settings.event.EventApi
|
||||||
|
import kr.co.vividnext.sodalive.settings.event.EventRepository
|
||||||
import kr.co.vividnext.sodalive.settings.terms.TermsApi
|
import kr.co.vividnext.sodalive.settings.terms.TermsApi
|
||||||
import kr.co.vividnext.sodalive.settings.terms.TermsRepository
|
import kr.co.vividnext.sodalive.settings.terms.TermsRepository
|
||||||
import kr.co.vividnext.sodalive.settings.terms.TermsViewModel
|
import kr.co.vividnext.sodalive.settings.terms.TermsViewModel
|
||||||
|
@ -58,6 +65,9 @@ class AppDI(private val context: Context, isDebugMode: Boolean) {
|
||||||
|
|
||||||
single { ApiBuilder().build(get(), UserApi::class.java) }
|
single { ApiBuilder().build(get(), UserApi::class.java) }
|
||||||
single { ApiBuilder().build(get(), TermsApi::class.java) }
|
single { ApiBuilder().build(get(), TermsApi::class.java) }
|
||||||
|
single { ApiBuilder().build(get(), LiveApi::class.java) }
|
||||||
|
single { ApiBuilder().build(get(), EventApi::class.java) }
|
||||||
|
single { ApiBuilder().build(get(), LiveRecommendApi::class.java) }
|
||||||
}
|
}
|
||||||
|
|
||||||
private val viewModelModule = module {
|
private val viewModelModule = module {
|
||||||
|
@ -66,11 +76,15 @@ class AppDI(private val context: Context, isDebugMode: Boolean) {
|
||||||
viewModel { TermsViewModel(get()) }
|
viewModel { TermsViewModel(get()) }
|
||||||
viewModel { FindPasswordViewModel(get()) }
|
viewModel { FindPasswordViewModel(get()) }
|
||||||
viewModel { MainViewModel(get()) }
|
viewModel { MainViewModel(get()) }
|
||||||
|
viewModel { LiveViewModel(get(), get(), get()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
private val repositoryModule = module {
|
private val repositoryModule = module {
|
||||||
factory { UserRepository(get()) }
|
factory { UserRepository(get()) }
|
||||||
factory { TermsRepository(get()) }
|
factory { TermsRepository(get()) }
|
||||||
|
factory { LiveRepository(get()) }
|
||||||
|
factory { EventRepository(get()) }
|
||||||
|
factory { LiveRecommendRepository(get()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
private val moduleList = listOf(
|
private val moduleList = listOf(
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
package kr.co.vividnext.sodalive.live
|
||||||
|
|
||||||
|
import com.google.gson.annotations.SerializedName
|
||||||
|
|
||||||
|
data class GetRoomListResponse(
|
||||||
|
@SerializedName("roomId") val roomId: Long,
|
||||||
|
@SerializedName("title") val title: String,
|
||||||
|
@SerializedName("content") val content: String,
|
||||||
|
@SerializedName("beginDateTime") val beginDateTime: String,
|
||||||
|
@SerializedName("numberOfParticipate") val numberOfParticipate: Int,
|
||||||
|
@SerializedName("numberOfPeople") val numberOfPeople: Int,
|
||||||
|
@SerializedName("coverImageUrl") val coverImageUrl: String,
|
||||||
|
@SerializedName("isAdult") val isAdult: Boolean,
|
||||||
|
@SerializedName("price") val price: Int,
|
||||||
|
@SerializedName("tags") val tags: List<String>,
|
||||||
|
@SerializedName("channelName") val channelName: String?,
|
||||||
|
@SerializedName("managerNickname") val managerNickname: String,
|
||||||
|
@SerializedName("managerId") val managerId: Long,
|
||||||
|
@SerializedName("isReservation") val isReservation: Boolean,
|
||||||
|
@SerializedName("isPrivateRoom") val isPrivateRoom: Boolean
|
||||||
|
)
|
|
@ -0,0 +1,20 @@
|
||||||
|
package kr.co.vividnext.sodalive.live
|
||||||
|
|
||||||
|
import io.reactivex.rxjava3.core.Flowable
|
||||||
|
import kr.co.vividnext.sodalive.common.ApiResponse
|
||||||
|
import kr.co.vividnext.sodalive.live.room.LiveRoomStatus
|
||||||
|
import retrofit2.http.GET
|
||||||
|
import retrofit2.http.Header
|
||||||
|
import retrofit2.http.Query
|
||||||
|
|
||||||
|
interface LiveApi {
|
||||||
|
@GET("/live/room")
|
||||||
|
fun roomList(
|
||||||
|
@Query("timezone") timezone: String,
|
||||||
|
@Query("dateString") dateString: String?,
|
||||||
|
@Query("status") status: LiveRoomStatus,
|
||||||
|
@Query("page") page: Int,
|
||||||
|
@Query("size") size: Int,
|
||||||
|
@Header("Authorization") authHeader: String
|
||||||
|
): Flowable<ApiResponse<List<GetRoomListResponse>>>
|
||||||
|
}
|
|
@ -1,7 +1,403 @@
|
||||||
package kr.co.vividnext.sodalive.live
|
package kr.co.vividnext.sodalive.live
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint
|
||||||
|
import android.content.Intent
|
||||||
|
import android.graphics.Rect
|
||||||
|
import android.net.Uri
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.view.View
|
||||||
|
import android.webkit.URLUtil
|
||||||
|
import android.widget.LinearLayout
|
||||||
|
import android.widget.Toast
|
||||||
|
import androidx.core.content.ContextCompat
|
||||||
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import com.zhpan.bannerview.BaseBannerAdapter
|
||||||
|
import com.zhpan.indicator.enums.IndicatorSlideMode
|
||||||
|
import com.zhpan.indicator.enums.IndicatorStyle
|
||||||
|
import kr.co.vividnext.sodalive.R
|
||||||
import kr.co.vividnext.sodalive.base.BaseFragment
|
import kr.co.vividnext.sodalive.base.BaseFragment
|
||||||
|
import kr.co.vividnext.sodalive.common.LoadingDialog
|
||||||
|
import kr.co.vividnext.sodalive.common.SharedPreferenceManager
|
||||||
import kr.co.vividnext.sodalive.databinding.FragmentLiveBinding
|
import kr.co.vividnext.sodalive.databinding.FragmentLiveBinding
|
||||||
|
import kr.co.vividnext.sodalive.extensions.dpToPx
|
||||||
|
import kr.co.vividnext.sodalive.live.event_banner.EventBannerAdapter
|
||||||
|
import kr.co.vividnext.sodalive.live.now.LiveNowAdapter
|
||||||
|
import kr.co.vividnext.sodalive.live.recommend.RecommendLiveAdapter
|
||||||
|
import kr.co.vividnext.sodalive.live.recommend_channel.LiveRecommendChannelAdapter
|
||||||
|
import kr.co.vividnext.sodalive.live.reservation.LiveReservationAdapter
|
||||||
|
import kr.co.vividnext.sodalive.settings.notification.MemberRole
|
||||||
|
import org.koin.android.ext.android.inject
|
||||||
|
import kotlin.math.roundToInt
|
||||||
|
|
||||||
class LiveFragment : BaseFragment<FragmentLiveBinding>(FragmentLiveBinding::inflate) {
|
class LiveFragment : BaseFragment<FragmentLiveBinding>(FragmentLiveBinding::inflate) {
|
||||||
|
private val viewModel: LiveViewModel by inject()
|
||||||
|
|
||||||
|
private lateinit var liveNowAdapter: LiveNowAdapter
|
||||||
|
private lateinit var liveReservationAdapter: LiveReservationAdapter
|
||||||
|
private lateinit var liveRecommendChannelAdapter: LiveRecommendChannelAdapter
|
||||||
|
|
||||||
|
private lateinit var loadingDialog: LoadingDialog
|
||||||
|
|
||||||
|
private var message = ""
|
||||||
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
|
||||||
|
setupView()
|
||||||
|
setupRecommendLive()
|
||||||
|
setupRecommendChannel()
|
||||||
|
setupLiveNow()
|
||||||
|
setupLiveReservation()
|
||||||
|
setupEvent()
|
||||||
|
|
||||||
|
message = "라이브를 불러오고 있습니다."
|
||||||
|
viewModel.getSummary()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setupView() {
|
||||||
|
loadingDialog = LoadingDialog(requireActivity(), layoutInflater)
|
||||||
|
|
||||||
|
viewModel.toastLiveData.observe(viewLifecycleOwner) {
|
||||||
|
it?.let { Toast.makeText(requireActivity(), it, Toast.LENGTH_LONG).show() }
|
||||||
|
}
|
||||||
|
|
||||||
|
viewModel.isLoading.observe(viewLifecycleOwner) {
|
||||||
|
if (it) {
|
||||||
|
loadingDialog.show(screenWidth, message)
|
||||||
|
} else {
|
||||||
|
loadingDialog.dismiss()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
binding.ivMakeRoom.visibility =
|
||||||
|
if (SharedPreferenceManager.role == MemberRole.CREATOR.name) {
|
||||||
|
View.VISIBLE
|
||||||
|
} else {
|
||||||
|
View.GONE
|
||||||
|
}
|
||||||
|
binding.ivMakeRoom.setOnClickListener {}
|
||||||
|
|
||||||
|
binding.swipeRefreshLayout.setOnRefreshListener { refreshSummary() }
|
||||||
|
|
||||||
|
val ivHowToUseLp = binding.ivHowToUse.layoutParams as LinearLayout.LayoutParams
|
||||||
|
ivHowToUseLp.width = screenWidth
|
||||||
|
ivHowToUseLp.height = (200 * screenWidth) / 1080
|
||||||
|
binding.ivHowToUse.layoutParams = ivHowToUseLp
|
||||||
|
binding.ivHowToUse.setOnClickListener {
|
||||||
|
val url = "https://blog.naver.com/yozmlive"
|
||||||
|
if (URLUtil.isValidUrl(url)) {
|
||||||
|
startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(url)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun refreshSummary() {
|
||||||
|
liveNowAdapter.clear()
|
||||||
|
liveRecommendChannelAdapter.clear()
|
||||||
|
liveReservationAdapter.clear()
|
||||||
|
|
||||||
|
message = "라이브를 불러오고 있습니다."
|
||||||
|
viewModel.getSummary()
|
||||||
|
|
||||||
|
binding.swipeRefreshLayout.isRefreshing = false
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressLint("NotifyDataSetChanged")
|
||||||
|
private fun setupRecommendLive() {
|
||||||
|
val layoutParams = binding
|
||||||
|
.layoutRecommendLive
|
||||||
|
.pager
|
||||||
|
.layoutParams as LinearLayout.LayoutParams
|
||||||
|
|
||||||
|
val pagerWidth = screenWidth.toDouble() - 26.7f.dpToPx()
|
||||||
|
val pagerHeight = (pagerWidth * 0.53).roundToInt()
|
||||||
|
layoutParams.width = pagerWidth.roundToInt()
|
||||||
|
layoutParams.height = pagerHeight
|
||||||
|
|
||||||
|
binding
|
||||||
|
.layoutRecommendLive
|
||||||
|
.pager
|
||||||
|
.layoutParams = layoutParams
|
||||||
|
|
||||||
|
binding.layoutRecommendLive.pager.apply {
|
||||||
|
adapter = RecommendLiveAdapter(pagerWidth.roundToInt(), pagerHeight) {
|
||||||
|
} as BaseBannerAdapter<Any>
|
||||||
|
|
||||||
|
setLifecycleRegistry(lifecycle)
|
||||||
|
setScrollDuration(1000)
|
||||||
|
setInterval(4 * 1000)
|
||||||
|
}.create()
|
||||||
|
|
||||||
|
binding
|
||||||
|
.layoutRecommendLive
|
||||||
|
.pager
|
||||||
|
.setIndicatorView(binding.layoutRecommendLive.indicator2)
|
||||||
|
.setIndicatorStyle(IndicatorStyle.ROUND_RECT)
|
||||||
|
.setIndicatorSlideMode(IndicatorSlideMode.SMOOTH)
|
||||||
|
.setIndicatorVisibility(View.GONE)
|
||||||
|
.setIndicatorSliderColor(
|
||||||
|
ContextCompat.getColor(requireContext(), R.color.color_909090),
|
||||||
|
ContextCompat.getColor(requireContext(), R.color.color_9970ff)
|
||||||
|
)
|
||||||
|
.setIndicatorSliderWidth(4f.dpToPx().toInt(), 10f.dpToPx().toInt())
|
||||||
|
.setIndicatorHeight(4f.dpToPx().toInt())
|
||||||
|
|
||||||
|
viewModel.recommendLiveData.observe(viewLifecycleOwner) {
|
||||||
|
if (it.isNotEmpty()) {
|
||||||
|
binding.layoutRecommendLive.root.visibility = View.VISIBLE
|
||||||
|
binding.layoutRecommendLive.pager.refreshData(it)
|
||||||
|
} else {
|
||||||
|
binding.layoutRecommendLive.root.visibility = View.GONE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setupRecommendChannel() {
|
||||||
|
liveRecommendChannelAdapter = LiveRecommendChannelAdapter(
|
||||||
|
onClick = {},
|
||||||
|
onClickMore = {}
|
||||||
|
)
|
||||||
|
|
||||||
|
binding.layoutRecommendChannel.rvRecommendChannel.layoutManager = LinearLayoutManager(
|
||||||
|
requireContext(),
|
||||||
|
LinearLayoutManager.HORIZONTAL,
|
||||||
|
false
|
||||||
|
)
|
||||||
|
|
||||||
|
binding
|
||||||
|
.layoutRecommendChannel
|
||||||
|
.rvRecommendChannel
|
||||||
|
.addItemDecoration(object : RecyclerView.ItemDecoration() {
|
||||||
|
override fun getItemOffsets(
|
||||||
|
outRect: Rect,
|
||||||
|
view: View,
|
||||||
|
parent: RecyclerView,
|
||||||
|
state: RecyclerView.State
|
||||||
|
) {
|
||||||
|
super.getItemOffsets(outRect, view, parent, state)
|
||||||
|
|
||||||
|
when (parent.getChildAdapterPosition(view)) {
|
||||||
|
0 -> {
|
||||||
|
outRect.left = 0.dpToPx().toInt()
|
||||||
|
outRect.right = 8.3f.dpToPx().toInt()
|
||||||
|
}
|
||||||
|
|
||||||
|
liveRecommendChannelAdapter.itemCount - 1 -> {
|
||||||
|
outRect.left = 8.3f.dpToPx().toInt()
|
||||||
|
outRect.right = 0.dpToPx().toInt()
|
||||||
|
}
|
||||||
|
|
||||||
|
else -> {
|
||||||
|
outRect.left = 8.3f.dpToPx().toInt()
|
||||||
|
outRect.right = 8.3f.dpToPx().toInt()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
binding.layoutRecommendChannel.rvRecommendChannel.adapter = liveRecommendChannelAdapter
|
||||||
|
binding.layoutRecommendChannel.ivSwitch.setOnClickListener {
|
||||||
|
viewModel.toggleIsFollowedCreatorLive()
|
||||||
|
}
|
||||||
|
|
||||||
|
viewModel.recommendChannelLiveData.observe(viewLifecycleOwner) {
|
||||||
|
binding.layoutRecommendChannel.root.visibility = View.VISIBLE
|
||||||
|
liveRecommendChannelAdapter.addItems(it)
|
||||||
|
binding.layoutRecommendChannel.rvRecommendChannel.requestLayout()
|
||||||
|
binding.layoutRecommendChannel.root.requestLayout()
|
||||||
|
}
|
||||||
|
|
||||||
|
viewModel.isFollowedCreatorLive.observe(viewLifecycleOwner) {
|
||||||
|
liveRecommendChannelAdapter.isFollowedCreatorLive = it
|
||||||
|
liveRecommendChannelAdapter.clear()
|
||||||
|
|
||||||
|
if (it) {
|
||||||
|
binding.layoutRecommendChannel.ivSwitch.setImageResource(R.drawable.btn_toggle_on_big)
|
||||||
|
binding.layoutRecommendChannel.llTitle2.visibility = View.VISIBLE
|
||||||
|
binding.layoutRecommendChannel.llTitle1.visibility = View.GONE
|
||||||
|
} else {
|
||||||
|
binding.layoutRecommendChannel.ivSwitch.setImageResource(R.drawable.btn_toggle_off_big)
|
||||||
|
binding.layoutRecommendChannel.llTitle1.visibility = View.VISIBLE
|
||||||
|
binding.layoutRecommendChannel.llTitle2.visibility = View.GONE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressLint("NotifyDataSetChanged")
|
||||||
|
private fun setupLiveNow() {
|
||||||
|
binding
|
||||||
|
.layoutLiveNow
|
||||||
|
.tvAllView
|
||||||
|
.setOnClickListener {}
|
||||||
|
|
||||||
|
val recyclerView = binding
|
||||||
|
.layoutLiveNow
|
||||||
|
.rvSudaNow
|
||||||
|
|
||||||
|
liveNowAdapter = LiveNowAdapter {}
|
||||||
|
|
||||||
|
recyclerView.layoutManager = LinearLayoutManager(
|
||||||
|
requireContext(),
|
||||||
|
LinearLayoutManager.HORIZONTAL,
|
||||||
|
false
|
||||||
|
)
|
||||||
|
|
||||||
|
recyclerView.addItemDecoration(object : RecyclerView.ItemDecoration() {
|
||||||
|
override fun getItemOffsets(
|
||||||
|
outRect: Rect,
|
||||||
|
view: View,
|
||||||
|
parent: RecyclerView,
|
||||||
|
state: RecyclerView.State
|
||||||
|
) {
|
||||||
|
super.getItemOffsets(outRect, view, parent, state)
|
||||||
|
|
||||||
|
when (parent.getChildAdapterPosition(view)) {
|
||||||
|
0 -> {
|
||||||
|
outRect.left = 13.3f.dpToPx().toInt()
|
||||||
|
outRect.right = 5.dpToPx().toInt()
|
||||||
|
}
|
||||||
|
|
||||||
|
liveNowAdapter.itemCount - 1 -> {
|
||||||
|
outRect.left = 5.dpToPx().toInt()
|
||||||
|
outRect.right = 13.3f.dpToPx().toInt()
|
||||||
|
}
|
||||||
|
|
||||||
|
else -> {
|
||||||
|
outRect.left = 5.dpToPx().toInt()
|
||||||
|
outRect.right = 5.dpToPx().toInt()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
recyclerView.adapter = liveNowAdapter
|
||||||
|
|
||||||
|
viewModel.liveNowLiveData.observe(viewLifecycleOwner) {
|
||||||
|
if (liveNowAdapter.items.isEmpty() && it.isEmpty()) {
|
||||||
|
recyclerView.visibility = View.GONE
|
||||||
|
binding.layoutLiveNow.tvAllView.visibility = View.GONE
|
||||||
|
binding.layoutLiveNow.llNoItems.visibility = View.VISIBLE
|
||||||
|
binding.layoutLiveNow.tvMakeRoom.setOnClickListener {}
|
||||||
|
|
||||||
|
recyclerView.requestLayout()
|
||||||
|
binding.layoutLiveNow.llNoItems.requestLayout()
|
||||||
|
} else {
|
||||||
|
binding.layoutLiveNow.tvAllView.visibility = View.VISIBLE
|
||||||
|
binding.layoutLiveNow.llNoItems.visibility = View.GONE
|
||||||
|
liveNowAdapter.items.addAll(it)
|
||||||
|
liveNowAdapter.notifyDataSetChanged()
|
||||||
|
recyclerView.visibility = View.VISIBLE
|
||||||
|
recyclerView.requestLayout()
|
||||||
|
}
|
||||||
|
|
||||||
|
binding.layoutLiveNow.root.requestLayout()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressLint("NotifyDataSetChanged")
|
||||||
|
private fun setupLiveReservation() {
|
||||||
|
val recyclerView = binding
|
||||||
|
.layoutLiveReservation
|
||||||
|
.rvSudaReservation
|
||||||
|
|
||||||
|
liveReservationAdapter = LiveReservationAdapter(isMain = true) {}
|
||||||
|
|
||||||
|
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 = 0f.dpToPx().toInt()
|
||||||
|
outRect.bottom = 6.7f.dpToPx().toInt()
|
||||||
|
}
|
||||||
|
|
||||||
|
liveReservationAdapter.itemCount - 1 -> {
|
||||||
|
outRect.top = 6.7f.dpToPx().toInt()
|
||||||
|
outRect.bottom = 13.3f.dpToPx().toInt()
|
||||||
|
}
|
||||||
|
|
||||||
|
else -> {
|
||||||
|
outRect.top = 6.7f.dpToPx().toInt()
|
||||||
|
outRect.bottom = 6.7f.dpToPx().toInt()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
recyclerView.adapter = liveReservationAdapter
|
||||||
|
|
||||||
|
viewModel.liveReservationLiveData.observe(viewLifecycleOwner) {
|
||||||
|
if (liveReservationAdapter.items.isEmpty() && it.isEmpty()) {
|
||||||
|
recyclerView.visibility = View.GONE
|
||||||
|
binding.layoutLiveReservation.tvAllView.visibility = View.GONE
|
||||||
|
binding.layoutLiveReservation.llNoItems.visibility = View.VISIBLE
|
||||||
|
binding.layoutLiveReservation.tvMakeRoom.setOnClickListener {}
|
||||||
|
|
||||||
|
recyclerView.requestLayout()
|
||||||
|
binding.layoutLiveReservation.llNoItems.requestLayout()
|
||||||
|
} else {
|
||||||
|
binding.layoutLiveReservation.tvAllView.visibility = View.VISIBLE
|
||||||
|
binding.layoutLiveReservation.llNoItems.visibility = View.GONE
|
||||||
|
liveReservationAdapter.items.addAll(it)
|
||||||
|
liveReservationAdapter.notifyDataSetChanged()
|
||||||
|
|
||||||
|
recyclerView.visibility = View.VISIBLE
|
||||||
|
recyclerView.requestLayout()
|
||||||
|
}
|
||||||
|
|
||||||
|
binding.layoutLiveReservation.root.requestLayout()
|
||||||
|
}
|
||||||
|
|
||||||
|
binding.layoutLiveReservation.tvAllView.setOnClickListener {}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressLint("NotifyDataSetChanged")
|
||||||
|
private fun setupEvent() {
|
||||||
|
val imageSliderLp = binding.eventBannerSlider.layoutParams
|
||||||
|
imageSliderLp.width = screenWidth
|
||||||
|
imageSliderLp.height = (screenWidth * 300) / 1000
|
||||||
|
binding.eventBannerSlider.layoutParams = imageSliderLp
|
||||||
|
|
||||||
|
binding.eventBannerSlider.apply {
|
||||||
|
adapter = EventBannerAdapter(requireContext()) {} as BaseBannerAdapter<Any>
|
||||||
|
setLifecycleRegistry(lifecycle)
|
||||||
|
setScrollDuration(800)
|
||||||
|
}.create()
|
||||||
|
|
||||||
|
binding.eventBannerSlider
|
||||||
|
.setIndicatorView(binding.indicator)
|
||||||
|
.setIndicatorStyle(IndicatorStyle.ROUND_RECT)
|
||||||
|
.setIndicatorSlideMode(IndicatorSlideMode.SMOOTH)
|
||||||
|
.setIndicatorVisibility(View.GONE)
|
||||||
|
.setIndicatorSliderColor(
|
||||||
|
ContextCompat.getColor(requireContext(), R.color.color_909090),
|
||||||
|
ContextCompat.getColor(requireContext(), R.color.color_9970ff)
|
||||||
|
)
|
||||||
|
.setIndicatorSliderWidth(4f.dpToPx().toInt(), 10f.dpToPx().toInt())
|
||||||
|
.setIndicatorHeight(4f.dpToPx().toInt())
|
||||||
|
|
||||||
|
viewModel.eventLiveData.observe(viewLifecycleOwner) {
|
||||||
|
if (it.isNotEmpty()) {
|
||||||
|
binding.eventBannerSlider.visibility = View.VISIBLE
|
||||||
|
binding.eventBannerSlider.refreshData(it)
|
||||||
|
} else {
|
||||||
|
binding.eventBannerSlider.visibility = View.GONE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
package kr.co.vividnext.sodalive.live
|
||||||
|
|
||||||
|
import io.reactivex.rxjava3.core.Flowable
|
||||||
|
import kr.co.vividnext.sodalive.common.ApiResponse
|
||||||
|
import kr.co.vividnext.sodalive.live.room.LiveRoomStatus
|
||||||
|
import java.util.TimeZone
|
||||||
|
|
||||||
|
class LiveRepository(private val api: LiveApi) {
|
||||||
|
fun roomList(
|
||||||
|
dateString: String? = null,
|
||||||
|
status: LiveRoomStatus,
|
||||||
|
page: Int,
|
||||||
|
size: Int,
|
||||||
|
token: String
|
||||||
|
): Flowable<ApiResponse<List<GetRoomListResponse>>> {
|
||||||
|
return api.roomList(
|
||||||
|
timezone = TimeZone.getDefault().id,
|
||||||
|
dateString = dateString,
|
||||||
|
status = status,
|
||||||
|
page = page - 1,
|
||||||
|
size = size,
|
||||||
|
authHeader = token
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
package kr.co.vividnext.sodalive.live
|
||||||
|
|
||||||
|
import com.google.gson.annotations.SerializedName
|
||||||
|
import kr.co.vividnext.sodalive.common.ApiResponse
|
||||||
|
import kr.co.vividnext.sodalive.live.recommend.GetRecommendLiveResponse
|
||||||
|
import kr.co.vividnext.sodalive.settings.event.GetEventResponse
|
||||||
|
|
||||||
|
data class LiveSummary(
|
||||||
|
@SerializedName("liveNow") val liveNow: ApiResponse<List<GetRoomListResponse>>,
|
||||||
|
@SerializedName("liveReservation") val liveReservation: ApiResponse<List<GetRoomListResponse>>,
|
||||||
|
@SerializedName("event") val event: ApiResponse<GetEventResponse>,
|
||||||
|
@SerializedName("recommendLive") val recommendLive: ApiResponse<List<GetRecommendLiveResponse>>,
|
||||||
|
)
|
|
@ -0,0 +1,241 @@
|
||||||
|
package kr.co.vividnext.sodalive.live
|
||||||
|
|
||||||
|
import androidx.lifecycle.LiveData
|
||||||
|
import androidx.lifecycle.MutableLiveData
|
||||||
|
import com.orhanobut.logger.Logger
|
||||||
|
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
|
||||||
|
import io.reactivex.rxjava3.core.Flowable
|
||||||
|
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.live.recommend.GetRecommendLiveResponse
|
||||||
|
import kr.co.vividnext.sodalive.live.recommend.LiveRecommendRepository
|
||||||
|
import kr.co.vividnext.sodalive.live.recommend_channel.GetRecommendChannelResponse
|
||||||
|
import kr.co.vividnext.sodalive.live.room.LiveRoomStatus
|
||||||
|
import kr.co.vividnext.sodalive.settings.event.EventItem
|
||||||
|
import kr.co.vividnext.sodalive.settings.event.EventRepository
|
||||||
|
|
||||||
|
class LiveViewModel(
|
||||||
|
private val repository: LiveRepository,
|
||||||
|
private val eventRepository: EventRepository,
|
||||||
|
private val liveRecommendRepository: LiveRecommendRepository
|
||||||
|
) : BaseViewModel() {
|
||||||
|
private var _isLoading = MutableLiveData(false)
|
||||||
|
val isLoading: LiveData<Boolean>
|
||||||
|
get() = _isLoading
|
||||||
|
|
||||||
|
private val _toastLiveData = MutableLiveData<String?>()
|
||||||
|
val toastLiveData: LiveData<String?>
|
||||||
|
get() = _toastLiveData
|
||||||
|
|
||||||
|
private val _recommendLiveData = MutableLiveData<List<GetRecommendLiveResponse>>()
|
||||||
|
val recommendLiveData: LiveData<List<GetRecommendLiveResponse>>
|
||||||
|
get() = _recommendLiveData
|
||||||
|
|
||||||
|
private val _isFollowedCreatorLive = MutableLiveData(
|
||||||
|
SharedPreferenceManager.isFollowedCreatorLive
|
||||||
|
)
|
||||||
|
val isFollowedCreatorLive: LiveData<Boolean>
|
||||||
|
get() = _isFollowedCreatorLive
|
||||||
|
|
||||||
|
private val _recommendChannelLiveData = MutableLiveData<List<GetRecommendChannelResponse>>()
|
||||||
|
val recommendChannelLiveData: LiveData<List<GetRecommendChannelResponse>>
|
||||||
|
get() = _recommendChannelLiveData
|
||||||
|
|
||||||
|
private val _liveNowLiveData = MutableLiveData<List<GetRoomListResponse>>()
|
||||||
|
val liveNowLiveData: LiveData<List<GetRoomListResponse>>
|
||||||
|
get() = _liveNowLiveData
|
||||||
|
|
||||||
|
private val _liveReservationLiveData = MutableLiveData<List<GetRoomListResponse>>()
|
||||||
|
val liveReservationLiveData: LiveData<List<GetRoomListResponse>>
|
||||||
|
get() = _liveReservationLiveData
|
||||||
|
|
||||||
|
private val _eventLiveData = MutableLiveData<List<EventItem>>()
|
||||||
|
val eventLiveData: LiveData<List<EventItem>>
|
||||||
|
get() = _eventLiveData
|
||||||
|
|
||||||
|
var page = 1
|
||||||
|
var isLast = false
|
||||||
|
private val pageSize = 10
|
||||||
|
|
||||||
|
fun toggleIsFollowedCreatorLive() {
|
||||||
|
val isOn = !_isFollowedCreatorLive.value!!
|
||||||
|
SharedPreferenceManager.isFollowedCreatorLive = isOn
|
||||||
|
_isFollowedCreatorLive.value = isOn
|
||||||
|
if (_isFollowedCreatorLive.value!!) {
|
||||||
|
getFollowedChannelList()
|
||||||
|
} else {
|
||||||
|
getRecommendChannelList()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getFollowedChannelList() {
|
||||||
|
compositeDisposable.add(
|
||||||
|
liveRecommendRepository.getFollowingChannelList(
|
||||||
|
token = "Bearer ${SharedPreferenceManager.token}"
|
||||||
|
)
|
||||||
|
.subscribeOn(Schedulers.io())
|
||||||
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
|
.subscribe(
|
||||||
|
{
|
||||||
|
if (it.success && it.data != null) {
|
||||||
|
_recommendChannelLiveData.postValue(it.data!!)
|
||||||
|
} else {
|
||||||
|
if (it.message != null) {
|
||||||
|
_toastLiveData.postValue(it.message)
|
||||||
|
} else {
|
||||||
|
_toastLiveData.postValue(
|
||||||
|
"알 수 없는 오류가 발생했습니다. 다시 시도해 주세요."
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
_isLoading.value = false
|
||||||
|
it.message?.let { message -> Logger.e(message) }
|
||||||
|
_toastLiveData.postValue("알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.")
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getRecommendChannelList() {
|
||||||
|
compositeDisposable.add(
|
||||||
|
liveRecommendRepository.getRecommendChannelList(
|
||||||
|
token = "Bearer ${SharedPreferenceManager.token}"
|
||||||
|
)
|
||||||
|
.subscribeOn(Schedulers.io())
|
||||||
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
|
.subscribe(
|
||||||
|
{
|
||||||
|
if (it.success && it.data != null) {
|
||||||
|
_recommendChannelLiveData.postValue(it.data!!)
|
||||||
|
} else {
|
||||||
|
if (it.message != null) {
|
||||||
|
_toastLiveData.postValue(it.message)
|
||||||
|
} else {
|
||||||
|
_toastLiveData.postValue(
|
||||||
|
"알 수 없는 오류가 발생했습니다. 다시 시도해 주세요."
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
_isLoading.value = false
|
||||||
|
it.message?.let { message -> Logger.e(message) }
|
||||||
|
_toastLiveData.postValue("알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.")
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getSummary() {
|
||||||
|
if (!_isLoading.value!!) {
|
||||||
|
if (_isFollowedCreatorLive.value!!) {
|
||||||
|
getFollowedChannelList()
|
||||||
|
} else {
|
||||||
|
getRecommendChannelList()
|
||||||
|
}
|
||||||
|
|
||||||
|
val liveNow = repository.roomList(
|
||||||
|
status = LiveRoomStatus.NOW,
|
||||||
|
page = 1,
|
||||||
|
size = pageSize,
|
||||||
|
token = "Bearer ${SharedPreferenceManager.token}"
|
||||||
|
)
|
||||||
|
|
||||||
|
val liveReservation = repository.roomList(
|
||||||
|
status = LiveRoomStatus.RESERVATION,
|
||||||
|
page = 1,
|
||||||
|
size = pageSize,
|
||||||
|
token = "Bearer ${SharedPreferenceManager.token}"
|
||||||
|
)
|
||||||
|
|
||||||
|
val event = eventRepository.getEvents(
|
||||||
|
0,
|
||||||
|
5,
|
||||||
|
token = "Bearer ${SharedPreferenceManager.token}"
|
||||||
|
)
|
||||||
|
|
||||||
|
val recommendLive = liveRecommendRepository.getRecommendLive(
|
||||||
|
token = "Bearer ${SharedPreferenceManager.token}"
|
||||||
|
)
|
||||||
|
|
||||||
|
_isLoading.postValue(true)
|
||||||
|
|
||||||
|
compositeDisposable.add(
|
||||||
|
Flowable.combineLatest(
|
||||||
|
liveNow,
|
||||||
|
liveReservation,
|
||||||
|
event,
|
||||||
|
recommendLive,
|
||||||
|
) { t1, t2, t3, t4 -> LiveSummary(t1, t2, t3, t4) }
|
||||||
|
.subscribe(
|
||||||
|
{
|
||||||
|
val now = it.liveNow
|
||||||
|
if (now.success && now.data != null) {
|
||||||
|
_liveNowLiveData.postValue(now.data!!)
|
||||||
|
if (now.data.isNotEmpty()) {
|
||||||
|
page += 1
|
||||||
|
} else {
|
||||||
|
isLast = true
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (now.message != null) {
|
||||||
|
_toastLiveData.postValue(now.message)
|
||||||
|
} else {
|
||||||
|
_toastLiveData.postValue(
|
||||||
|
"알 수 없는 오류가 발생했습니다. 다시 시도해 주세요."
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val reservation = it.liveReservation
|
||||||
|
if (reservation.success && reservation.data != null) {
|
||||||
|
_liveReservationLiveData.postValue(reservation.data!!)
|
||||||
|
if (reservation.data.isNotEmpty()) {
|
||||||
|
page += 1
|
||||||
|
} else {
|
||||||
|
isLast = true
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (reservation.message != null) {
|
||||||
|
_toastLiveData.postValue(reservation.message)
|
||||||
|
} else {
|
||||||
|
_toastLiveData.postValue(
|
||||||
|
"알 수 없는 오류가 발생했습니다. 다시 시도해 주세요."
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val eventResponse = it.event
|
||||||
|
if (eventResponse.success && eventResponse.data != null) {
|
||||||
|
val data = eventResponse.data
|
||||||
|
_eventLiveData.postValue(data.eventList)
|
||||||
|
} else {
|
||||||
|
_eventLiveData.postValue(emptyList())
|
||||||
|
}
|
||||||
|
|
||||||
|
val recommendLiveResponse = it.recommendLive
|
||||||
|
if (
|
||||||
|
recommendLiveResponse.success &&
|
||||||
|
recommendLiveResponse.data != null
|
||||||
|
) {
|
||||||
|
val data = recommendLiveResponse.data
|
||||||
|
_recommendLiveData.postValue(data!!)
|
||||||
|
} else {
|
||||||
|
_recommendLiveData.postValue(emptyList())
|
||||||
|
}
|
||||||
|
|
||||||
|
_isLoading.postValue(false)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
_isLoading.postValue(false)
|
||||||
|
it.message?.let { message -> Logger.e(message) }
|
||||||
|
_toastLiveData.postValue("알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.")
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
package kr.co.vividnext.sodalive.live.event_banner
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.widget.ImageView
|
||||||
|
import coil.load
|
||||||
|
import com.zhpan.bannerview.BaseBannerAdapter
|
||||||
|
import com.zhpan.bannerview.BaseViewHolder
|
||||||
|
import kr.co.vividnext.sodalive.R
|
||||||
|
import kr.co.vividnext.sodalive.settings.event.EventItem
|
||||||
|
|
||||||
|
class EventBannerAdapter(
|
||||||
|
private val context: Context,
|
||||||
|
private val itemClick: (EventItem) -> Unit
|
||||||
|
) : BaseBannerAdapter<EventItem>() {
|
||||||
|
|
||||||
|
override fun bindData(
|
||||||
|
holder: BaseViewHolder<EventItem>,
|
||||||
|
data: EventItem,
|
||||||
|
position: Int,
|
||||||
|
pageSize: Int
|
||||||
|
) {
|
||||||
|
val ivThumbnail = holder.findViewById<ImageView>(R.id.iv_thumbnail)
|
||||||
|
ivThumbnail.load(data.thumbnailImageUrl) {
|
||||||
|
crossfade(true)
|
||||||
|
|
||||||
|
val layoutParams = ivThumbnail.layoutParams
|
||||||
|
val screenWidth = context.resources.displayMetrics.widthPixels
|
||||||
|
layoutParams.width = screenWidth
|
||||||
|
layoutParams.height = (screenWidth * 300) / 1000
|
||||||
|
ivThumbnail.layoutParams = layoutParams
|
||||||
|
}
|
||||||
|
ivThumbnail.setOnClickListener { itemClick(data) }
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getLayoutId(viewType: Int): Int {
|
||||||
|
return R.layout.item_event_slider
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,76 @@
|
||||||
|
package kr.co.vividnext.sodalive.live.now
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import coil.load
|
||||||
|
import coil.transform.RoundedCornersTransformation
|
||||||
|
import kr.co.vividnext.sodalive.R
|
||||||
|
import kr.co.vividnext.sodalive.databinding.ItemLiveNowBinding
|
||||||
|
import kr.co.vividnext.sodalive.extensions.dpToPx
|
||||||
|
import kr.co.vividnext.sodalive.live.GetRoomListResponse
|
||||||
|
|
||||||
|
class LiveNowAdapter(
|
||||||
|
private val onClick: (GetRoomListResponse) -> Unit
|
||||||
|
) : RecyclerView.Adapter<LiveNowAdapter.ViewHolder>() {
|
||||||
|
|
||||||
|
var items = mutableListOf<GetRoomListResponse>()
|
||||||
|
|
||||||
|
inner class ViewHolder(
|
||||||
|
private val binding: ItemLiveNowBinding
|
||||||
|
) : RecyclerView.ViewHolder(binding.root) {
|
||||||
|
|
||||||
|
fun bind(item: GetRoomListResponse) {
|
||||||
|
binding.ivCover.load(item.coverImageUrl) {
|
||||||
|
crossfade(true)
|
||||||
|
placeholder(R.drawable.bg_placeholder)
|
||||||
|
transformations(RoundedCornersTransformation(4.7f.dpToPx()))
|
||||||
|
}
|
||||||
|
binding.tvManager.text = item.managerNickname
|
||||||
|
binding.tvNumberOfMembers.text = "${item.numberOfParticipate}"
|
||||||
|
binding.ivLock.visibility = if (item.isPrivateRoom) {
|
||||||
|
View.VISIBLE
|
||||||
|
} else {
|
||||||
|
View.GONE
|
||||||
|
}
|
||||||
|
|
||||||
|
if (item.price > 0) {
|
||||||
|
binding.tvPrice.text = "유료"
|
||||||
|
binding.tvPrice.setBackgroundResource(R.drawable.bg_round_corner_10_881609)
|
||||||
|
} else {
|
||||||
|
binding.tvPrice.text = "무료"
|
||||||
|
binding.tvPrice.setBackgroundResource(R.drawable.bg_round_corner_10_643bc8)
|
||||||
|
}
|
||||||
|
|
||||||
|
binding.iv19.visibility = if (item.isAdult) {
|
||||||
|
View.VISIBLE
|
||||||
|
} else {
|
||||||
|
View.GONE
|
||||||
|
}
|
||||||
|
|
||||||
|
binding.root.setOnClickListener { onClick(item) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ViewHolder(
|
||||||
|
ItemLiveNowBinding.inflate(
|
||||||
|
LayoutInflater.from(parent.context),
|
||||||
|
parent,
|
||||||
|
false
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
||||||
|
holder.bind(items[position])
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getItemCount() = items.count()
|
||||||
|
|
||||||
|
@SuppressLint("NotifyDataSetChanged")
|
||||||
|
fun clear() {
|
||||||
|
items.clear()
|
||||||
|
notifyDataSetChanged()
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
package kr.co.vividnext.sodalive.live.recommend
|
||||||
|
|
||||||
|
import com.google.gson.annotations.SerializedName
|
||||||
|
|
||||||
|
data class GetRecommendLiveResponse(
|
||||||
|
@SerializedName("imageUrl")
|
||||||
|
val imageUrl: String,
|
||||||
|
@SerializedName("creatorId")
|
||||||
|
val creatorId: Long
|
||||||
|
)
|
|
@ -0,0 +1,25 @@
|
||||||
|
package kr.co.vividnext.sodalive.live.recommend
|
||||||
|
|
||||||
|
import io.reactivex.rxjava3.core.Flowable
|
||||||
|
import io.reactivex.rxjava3.core.Single
|
||||||
|
import kr.co.vividnext.sodalive.common.ApiResponse
|
||||||
|
import kr.co.vividnext.sodalive.live.recommend_channel.GetRecommendChannelResponse
|
||||||
|
import retrofit2.http.GET
|
||||||
|
import retrofit2.http.Header
|
||||||
|
|
||||||
|
interface LiveRecommendApi {
|
||||||
|
@GET("/live/recommend")
|
||||||
|
fun getRecommendLive(
|
||||||
|
@Header("Authorization") authHeader: String
|
||||||
|
): Flowable<ApiResponse<List<GetRecommendLiveResponse>>>
|
||||||
|
|
||||||
|
@GET("/live/recommend/channel")
|
||||||
|
fun getRecommendChannelList(
|
||||||
|
@Header("Authorization") authHeader: String
|
||||||
|
): Flowable<ApiResponse<List<GetRecommendChannelResponse>>>
|
||||||
|
|
||||||
|
@GET("/live/following/channel")
|
||||||
|
fun getFollowingChannelList(
|
||||||
|
@Header("Authorization") authHeader: String
|
||||||
|
): Single<ApiResponse<List<GetRecommendChannelResponse>>>
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
package kr.co.vividnext.sodalive.live.recommend
|
||||||
|
|
||||||
|
class LiveRecommendRepository(private val api: LiveRecommendApi) {
|
||||||
|
fun getRecommendLive(token: String) = api.getRecommendLive(authHeader = token)
|
||||||
|
fun getRecommendChannelList(token: String) = api.getRecommendChannelList(authHeader = token)
|
||||||
|
fun getFollowingChannelList(token: String) = api.getFollowingChannelList(authHeader = token)
|
||||||
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
package kr.co.vividnext.sodalive.live.recommend
|
||||||
|
|
||||||
|
import android.widget.FrameLayout
|
||||||
|
import android.widget.ImageView
|
||||||
|
import coil.load
|
||||||
|
import coil.transform.RoundedCornersTransformation
|
||||||
|
import com.zhpan.bannerview.BaseBannerAdapter
|
||||||
|
import com.zhpan.bannerview.BaseViewHolder
|
||||||
|
import kr.co.vividnext.sodalive.R
|
||||||
|
import kr.co.vividnext.sodalive.extensions.dpToPx
|
||||||
|
|
||||||
|
class RecommendLiveAdapter(
|
||||||
|
private val itemWidth: Int,
|
||||||
|
private val itemHeight: Int,
|
||||||
|
private val onClick: (Long) -> Unit
|
||||||
|
) : BaseBannerAdapter<GetRecommendLiveResponse>() {
|
||||||
|
override fun bindData(
|
||||||
|
holder: BaseViewHolder<GetRecommendLiveResponse>,
|
||||||
|
data: GetRecommendLiveResponse,
|
||||||
|
position: Int,
|
||||||
|
pageSize: Int
|
||||||
|
) {
|
||||||
|
val ivRecommendLive = holder.findViewById<ImageView>(R.id.iv_recommend_live)
|
||||||
|
val layoutParams = ivRecommendLive.layoutParams as FrameLayout.LayoutParams
|
||||||
|
|
||||||
|
layoutParams.width = itemWidth
|
||||||
|
layoutParams.height = itemHeight
|
||||||
|
|
||||||
|
ivRecommendLive.load(data.imageUrl) {
|
||||||
|
crossfade(true)
|
||||||
|
placeholder(R.drawable.bg_placeholder)
|
||||||
|
transformations(RoundedCornersTransformation(5.3f.dpToPx()))
|
||||||
|
}
|
||||||
|
ivRecommendLive.layoutParams = layoutParams
|
||||||
|
ivRecommendLive.setOnClickListener { onClick(data.creatorId) }
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getLayoutId(viewType: Int): Int {
|
||||||
|
return R.layout.item_recommend_live
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
package kr.co.vividnext.sodalive.live.recommend_channel
|
||||||
|
|
||||||
|
import com.google.gson.annotations.SerializedName
|
||||||
|
|
||||||
|
data class GetRecommendChannelResponse(
|
||||||
|
@SerializedName("creatorId")
|
||||||
|
val creatorId: Long,
|
||||||
|
@SerializedName("nickname")
|
||||||
|
val nickname: String,
|
||||||
|
@SerializedName("profileImageUrl")
|
||||||
|
val profileImageUrl: String,
|
||||||
|
@SerializedName("isOnAir")
|
||||||
|
val isOnAir: Boolean
|
||||||
|
)
|
|
@ -0,0 +1,142 @@
|
||||||
|
package kr.co.vividnext.sodalive.live.recommend_channel
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import android.widget.FrameLayout
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import coil.load
|
||||||
|
import coil.transform.RoundedCornersTransformation
|
||||||
|
import kr.co.vividnext.sodalive.R
|
||||||
|
import kr.co.vividnext.sodalive.databinding.ItemRecommendChannelBinding
|
||||||
|
import kr.co.vividnext.sodalive.extensions.dpToPx
|
||||||
|
|
||||||
|
class LiveRecommendChannelAdapter(
|
||||||
|
private val onClick: (Long) -> Unit,
|
||||||
|
private val onClickMore: () -> Unit,
|
||||||
|
) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
|
||||||
|
|
||||||
|
var isFollowedCreatorLive = false
|
||||||
|
|
||||||
|
private val items = mutableListOf<GetRecommendChannelResponse>()
|
||||||
|
|
||||||
|
class FooterViewHolder(
|
||||||
|
private val binding: ItemRecommendChannelBinding,
|
||||||
|
private val onClickItem: () -> Unit
|
||||||
|
) : RecyclerView.ViewHolder(binding.root) {
|
||||||
|
fun bind() {
|
||||||
|
binding.ivRecommendChannel.setImageResource(R.drawable.btn_item_more)
|
||||||
|
binding.tvRecommendChannelNickname.text = "더보기"
|
||||||
|
|
||||||
|
val layoutParams = binding.ivRecommendChannel.layoutParams as FrameLayout.LayoutParams
|
||||||
|
layoutParams.width = 60f.dpToPx().toInt()
|
||||||
|
layoutParams.height = 60f.dpToPx().toInt()
|
||||||
|
|
||||||
|
binding.ivRecommendChannel.layoutParams = layoutParams
|
||||||
|
binding.ivRecommendChannelBg.layoutParams = layoutParams
|
||||||
|
|
||||||
|
binding.tvRecommendChannel.visibility = View.GONE
|
||||||
|
binding.ivRecommendChannelBg.visibility = View.GONE
|
||||||
|
binding.root.setOnClickListener { onClickItem() }
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val VIEW_TYPE = 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ViewHolder(
|
||||||
|
private val binding: ItemRecommendChannelBinding,
|
||||||
|
private val onClickItem: (Long) -> Unit
|
||||||
|
) : RecyclerView.ViewHolder(binding.root) {
|
||||||
|
|
||||||
|
fun bind(item: GetRecommendChannelResponse) {
|
||||||
|
binding.ivRecommendChannel.load(item.profileImageUrl) {
|
||||||
|
crossfade(true)
|
||||||
|
placeholder(R.drawable.bg_placeholder)
|
||||||
|
transformations(RoundedCornersTransformation(30f.dpToPx()))
|
||||||
|
}
|
||||||
|
binding.tvRecommendChannelNickname.text = item.nickname
|
||||||
|
|
||||||
|
val layoutParams = binding.ivRecommendChannel.layoutParams as FrameLayout.LayoutParams
|
||||||
|
layoutParams.width = 60f.dpToPx().toInt()
|
||||||
|
layoutParams.height = 60f.dpToPx().toInt()
|
||||||
|
|
||||||
|
binding.ivRecommendChannel.layoutParams = layoutParams
|
||||||
|
binding.ivRecommendChannelBg.layoutParams = layoutParams
|
||||||
|
|
||||||
|
if (item.isOnAir) {
|
||||||
|
binding.tvRecommendChannel.visibility = View.VISIBLE
|
||||||
|
binding.ivRecommendChannelBg.visibility = View.VISIBLE
|
||||||
|
} else {
|
||||||
|
binding.tvRecommendChannel.visibility = View.GONE
|
||||||
|
binding.ivRecommendChannelBg.visibility = View.GONE
|
||||||
|
}
|
||||||
|
|
||||||
|
binding.root.setOnClickListener { onClickItem(item.creatorId) }
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val VIEW_TYPE = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
|
||||||
|
return if (viewType == FooterViewHolder.VIEW_TYPE) {
|
||||||
|
FooterViewHolder(
|
||||||
|
ItemRecommendChannelBinding.inflate(
|
||||||
|
LayoutInflater.from(parent.context),
|
||||||
|
parent,
|
||||||
|
false
|
||||||
|
),
|
||||||
|
onClickItem = onClickMore
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
ViewHolder(
|
||||||
|
ItemRecommendChannelBinding.inflate(
|
||||||
|
LayoutInflater.from(parent.context),
|
||||||
|
parent,
|
||||||
|
false
|
||||||
|
),
|
||||||
|
onClickItem = onClick
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
|
||||||
|
if (holder is FooterViewHolder) {
|
||||||
|
holder.bind()
|
||||||
|
} else {
|
||||||
|
(holder as ViewHolder).bind(items[position])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getItemCount(): Int {
|
||||||
|
return if (isFollowedCreatorLive) {
|
||||||
|
items.size + 1
|
||||||
|
} else {
|
||||||
|
items.size
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getItemViewType(position: Int): Int {
|
||||||
|
return if (position == items.size) {
|
||||||
|
FooterViewHolder.VIEW_TYPE
|
||||||
|
} else {
|
||||||
|
ViewHolder.VIEW_TYPE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressLint("NotifyDataSetChanged")
|
||||||
|
fun clear() {
|
||||||
|
items.clear()
|
||||||
|
notifyDataSetChanged()
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressLint("NotifyDataSetChanged")
|
||||||
|
fun addItems(items: List<GetRecommendChannelResponse>) {
|
||||||
|
this.items.addAll(items)
|
||||||
|
notifyDataSetChanged()
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,146 @@
|
||||||
|
package kr.co.vividnext.sodalive.live.reservation
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import coil.load
|
||||||
|
import coil.transform.RoundedCornersTransformation
|
||||||
|
import kr.co.vividnext.sodalive.R
|
||||||
|
import kr.co.vividnext.sodalive.common.SharedPreferenceManager
|
||||||
|
import kr.co.vividnext.sodalive.databinding.ItemLiveReservationBinding
|
||||||
|
import kr.co.vividnext.sodalive.databinding.ItemMyLiveReservationBinding
|
||||||
|
import kr.co.vividnext.sodalive.extensions.dpToPx
|
||||||
|
import kr.co.vividnext.sodalive.extensions.moneyFormat
|
||||||
|
import kr.co.vividnext.sodalive.live.GetRoomListResponse
|
||||||
|
|
||||||
|
class LiveReservationAdapter(
|
||||||
|
private val isMain: Boolean = false,
|
||||||
|
private val onClick: (GetRoomListResponse) -> Unit
|
||||||
|
) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
|
||||||
|
var items = mutableListOf<GetRoomListResponse>()
|
||||||
|
|
||||||
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
|
||||||
|
return if (viewType == 1) {
|
||||||
|
MyLiveViewHolder(
|
||||||
|
ItemMyLiveReservationBinding.inflate(
|
||||||
|
LayoutInflater.from(parent.context),
|
||||||
|
parent,
|
||||||
|
false
|
||||||
|
)
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
ViewHolder(
|
||||||
|
ItemLiveReservationBinding.inflate(
|
||||||
|
LayoutInflater.from(parent.context),
|
||||||
|
parent,
|
||||||
|
false
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
|
||||||
|
val item = items[position]
|
||||||
|
if (isMyLive(item)) {
|
||||||
|
(holder as MyLiveViewHolder).bind(item, position)
|
||||||
|
} else {
|
||||||
|
(holder as ViewHolder).bind(item)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getItemCount() = items.count()
|
||||||
|
|
||||||
|
override fun getItemViewType(position: Int): Int {
|
||||||
|
return if (isMyLive(items[position])) {
|
||||||
|
1
|
||||||
|
} else {
|
||||||
|
0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun isMyLive(item: GetRoomListResponse) =
|
||||||
|
item.managerId == SharedPreferenceManager.userId && isMain
|
||||||
|
|
||||||
|
@SuppressLint("NotifyDataSetChanged")
|
||||||
|
fun clear() {
|
||||||
|
items.clear()
|
||||||
|
notifyDataSetChanged()
|
||||||
|
}
|
||||||
|
|
||||||
|
inner class ViewHolder(
|
||||||
|
private val binding: ItemLiveReservationBinding
|
||||||
|
) : RecyclerView.ViewHolder(binding.root) {
|
||||||
|
|
||||||
|
fun bind(item: GetRoomListResponse) {
|
||||||
|
binding.ivCover.load(item.coverImageUrl) {
|
||||||
|
crossfade(true)
|
||||||
|
placeholder(R.drawable.bg_placeholder)
|
||||||
|
transformations(RoundedCornersTransformation(4.7f.dpToPx()))
|
||||||
|
}
|
||||||
|
binding.tvDate.text = item.beginDateTime
|
||||||
|
binding.tvNickname.text = item.managerNickname
|
||||||
|
binding.tvTitle.text = item.title
|
||||||
|
binding.root.setOnClickListener { onClick(item) }
|
||||||
|
binding.ivLock.visibility = if (item.isPrivateRoom) {
|
||||||
|
View.VISIBLE
|
||||||
|
} else {
|
||||||
|
View.GONE
|
||||||
|
}
|
||||||
|
|
||||||
|
if (item.isReservation) {
|
||||||
|
binding.tvPrice.visibility = View.GONE
|
||||||
|
binding.tvCompleteReservation.visibility = View.VISIBLE
|
||||||
|
} else {
|
||||||
|
binding.tvPrice.visibility = View.VISIBLE
|
||||||
|
binding.tvCompleteReservation.visibility = View.GONE
|
||||||
|
|
||||||
|
binding.tvPrice.text = if (item.price <= 0) {
|
||||||
|
"무료"
|
||||||
|
} else {
|
||||||
|
"${item.price.moneyFormat()}코인"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
binding.iv19.visibility = if (item.isAdult) {
|
||||||
|
View.VISIBLE
|
||||||
|
} else {
|
||||||
|
View.GONE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inner class MyLiveViewHolder(
|
||||||
|
private val binding: ItemMyLiveReservationBinding
|
||||||
|
) : RecyclerView.ViewHolder(binding.root) {
|
||||||
|
fun bind(item: GetRoomListResponse, position: Int) {
|
||||||
|
binding.tvMyLive.visibility = if (position == 0) {
|
||||||
|
View.VISIBLE
|
||||||
|
} else {
|
||||||
|
View.GONE
|
||||||
|
}
|
||||||
|
binding.ivCover.load(item.coverImageUrl) {
|
||||||
|
crossfade(true)
|
||||||
|
placeholder(R.drawable.bg_placeholder)
|
||||||
|
transformations(RoundedCornersTransformation(4f.dpToPx()))
|
||||||
|
}
|
||||||
|
binding.tvDate.text = item.beginDateTime
|
||||||
|
binding.tvNickname.text = item.managerNickname
|
||||||
|
binding.tvTitle.text = item.title
|
||||||
|
binding.root.setOnClickListener { onClick(item) }
|
||||||
|
|
||||||
|
binding.ivLock.visibility = if (item.isPrivateRoom) {
|
||||||
|
View.VISIBLE
|
||||||
|
} else {
|
||||||
|
View.GONE
|
||||||
|
}
|
||||||
|
|
||||||
|
binding.iv19.visibility = if (item.isAdult) {
|
||||||
|
View.VISIBLE
|
||||||
|
} else {
|
||||||
|
View.GONE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
package kr.co.vividnext.sodalive.live.room
|
||||||
|
|
||||||
|
import com.google.gson.annotations.SerializedName
|
||||||
|
|
||||||
|
enum class LiveRoomStatus {
|
||||||
|
@SerializedName("NOW") NOW,
|
||||||
|
@SerializedName("RESERVATION") RESERVATION
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
package kr.co.vividnext.sodalive.settings.event
|
||||||
|
|
||||||
|
import io.reactivex.rxjava3.core.Flowable
|
||||||
|
import io.reactivex.rxjava3.core.Single
|
||||||
|
import kr.co.vividnext.sodalive.common.ApiResponse
|
||||||
|
import retrofit2.http.GET
|
||||||
|
import retrofit2.http.Header
|
||||||
|
import retrofit2.http.Query
|
||||||
|
|
||||||
|
interface EventApi {
|
||||||
|
@GET("/event")
|
||||||
|
fun getEvents(
|
||||||
|
@Query("page") page: Int,
|
||||||
|
@Query("size") size: Int,
|
||||||
|
@Header("Authorization") authHeader: String
|
||||||
|
): Flowable<ApiResponse<GetEventResponse>>
|
||||||
|
|
||||||
|
@GET("/event/popup")
|
||||||
|
fun getEventPopup(@Header("Authorization") authHeader: String): Single<ApiResponse<EventItem>>
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
package kr.co.vividnext.sodalive.settings.event
|
||||||
|
|
||||||
|
class EventRepository(private val api: EventApi) {
|
||||||
|
fun getEvents(
|
||||||
|
page: Int,
|
||||||
|
size: Int,
|
||||||
|
token: String
|
||||||
|
) = api.getEvents(page, size, authHeader = token)
|
||||||
|
|
||||||
|
fun getEventPopup(token: String) = api.getEventPopup(authHeader = token)
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
package kr.co.vividnext.sodalive.settings.event
|
||||||
|
|
||||||
|
import android.os.Parcelable
|
||||||
|
import com.google.gson.annotations.SerializedName
|
||||||
|
import kotlinx.parcelize.Parcelize
|
||||||
|
|
||||||
|
data class GetEventResponse(
|
||||||
|
@SerializedName("totalCount") val totalCount: Int,
|
||||||
|
@SerializedName("eventList") val eventList: List<EventItem>
|
||||||
|
)
|
||||||
|
|
||||||
|
@Parcelize
|
||||||
|
data class EventItem(
|
||||||
|
@SerializedName("id") val id: Long,
|
||||||
|
@SerializedName("thumbnailImageUrl") val thumbnailImageUrl: String,
|
||||||
|
@SerializedName("detailImageUrl") val detailImageUrl: String? = null,
|
||||||
|
@SerializedName("popupImageUrl") val popupImageUrl: String? = null,
|
||||||
|
@SerializedName("link") val link: String? = null
|
||||||
|
) : Parcelable
|
After Width: | Height: | Size: 2.2 KiB |
After Width: | Height: | Size: 5.1 KiB |
After Width: | Height: | Size: 3.0 KiB |
After Width: | Height: | Size: 362 B |
After Width: | Height: | Size: 824 B |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 3.8 KiB |
After Width: | Height: | Size: 551 B |
After Width: | Height: | Size: 101 KiB |
|
@ -0,0 +1,8 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<solid android:color="@color/color_533d89" />
|
||||||
|
<corners android:radius="10dp" />
|
||||||
|
<stroke
|
||||||
|
android:width="1dp"
|
||||||
|
android:color="@color/color_533d89" />
|
||||||
|
</shape>
|
|
@ -0,0 +1,8 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<solid android:color="@color/color_643bc8" />
|
||||||
|
<corners android:radius="10dp" />
|
||||||
|
<stroke
|
||||||
|
android:width="1dp"
|
||||||
|
android:color="@color/color_643bc8" />
|
||||||
|
</shape>
|
|
@ -0,0 +1,8 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<solid android:color="@color/color_881609" />
|
||||||
|
<corners android:radius="10dp" />
|
||||||
|
<stroke
|
||||||
|
android:width="1dp"
|
||||||
|
android:color="@color/color_881609" />
|
||||||
|
</shape>
|
|
@ -0,0 +1,8 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<solid android:color="@android:color/transparent" />
|
||||||
|
<corners android:radius="33.3dp" />
|
||||||
|
<stroke
|
||||||
|
android:width="3dp"
|
||||||
|
android:color="@color/color_9970ff" />
|
||||||
|
</shape>
|
|
@ -0,0 +1,8 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<solid android:color="@color/color_2b2635" />
|
||||||
|
<corners android:radius="4.7dp" />
|
||||||
|
<stroke
|
||||||
|
android:width="1dp"
|
||||||
|
android:color="@color/color_2b2635" />
|
||||||
|
</shape>
|
|
@ -0,0 +1,8 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<solid android:color="@color/color_9970ff" />
|
||||||
|
<corners android:radius="4.7dp" />
|
||||||
|
<stroke
|
||||||
|
android:width="1dp"
|
||||||
|
android:color="@color/color_9970ff" />
|
||||||
|
</shape>
|
|
@ -0,0 +1,10 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<shape
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:shape="rectangle">
|
||||||
|
<gradient
|
||||||
|
android:type="linear"
|
||||||
|
android:startColor="#cc000000"
|
||||||
|
android:endColor="#19000000"
|
||||||
|
android:angle="90" />
|
||||||
|
</shape>
|
|
@ -0,0 +1,170 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="108dp"
|
||||||
|
android:height="108dp"
|
||||||
|
android:viewportWidth="108"
|
||||||
|
android:viewportHeight="108">
|
||||||
|
<path
|
||||||
|
android:fillColor="#3DDC84"
|
||||||
|
android:pathData="M0,0h108v108h-108z" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M9,0L9,108"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M19,0L19,108"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M29,0L29,108"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M39,0L39,108"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M49,0L49,108"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M59,0L59,108"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M69,0L69,108"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M79,0L79,108"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M89,0L89,108"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M99,0L99,108"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,9L108,9"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,19L108,19"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,29L108,29"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,39L108,39"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,49L108,49"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,59L108,59"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,69L108,69"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,79L108,79"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,89L108,89"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,99L108,99"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M19,29L89,29"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M19,39L89,39"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M19,49L89,49"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M19,59L89,59"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M19,69L89,69"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M19,79L89,79"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M29,19L29,89"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M39,19L39,89"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M49,19L49,89"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M59,19L59,89"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M69,19L69,89"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M79,19L79,89"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
</vector>
|
|
@ -4,13 +4,83 @@
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
<TextView
|
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
||||||
|
android:id="@+id/swipe_refresh_layout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
<androidx.core.widget.NestedScrollView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<include
|
||||||
|
android:id="@+id/layout_recommend_live"
|
||||||
|
layout="@layout/layout_recommend_live"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginHorizontal="13.3dp"
|
||||||
|
android:layout_marginTop="13.3dp" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/iv_how_to_use"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="21.3dp"
|
||||||
|
android:contentDescription="@null"
|
||||||
|
android:src="@drawable/img_how_to_use" />
|
||||||
|
|
||||||
|
<include
|
||||||
|
android:id="@+id/layout_recommend_channel"
|
||||||
|
layout="@layout/layout_live_recommend_channel"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginHorizontal="13.3dp"
|
||||||
|
android:layout_marginTop="40dp" />
|
||||||
|
|
||||||
|
<include
|
||||||
|
android:id="@+id/layout_live_now"
|
||||||
|
layout="@layout/layout_live_now"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="40dp" />
|
||||||
|
|
||||||
|
<com.zhpan.bannerview.BannerViewPager
|
||||||
|
android:id="@+id/event_banner_slider"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="40dp" />
|
||||||
|
|
||||||
|
<com.zhpan.indicator.IndicatorView
|
||||||
|
android:id="@+id/indicator"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:layout_marginTop="6.7dp" />
|
||||||
|
|
||||||
|
<include
|
||||||
|
android:id="@+id/layout_live_reservation"
|
||||||
|
layout="@layout/layout_live_reservation"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="40dp" />
|
||||||
|
</LinearLayout>
|
||||||
|
</androidx.core.widget.NestedScrollView>
|
||||||
|
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/iv_make_room"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginEnd="16.7dp"
|
||||||
|
android:layout_marginBottom="16.7dp"
|
||||||
|
android:contentDescription="@null"
|
||||||
|
android:src="@drawable/btn_make_live"
|
||||||
|
android:visibility="gone"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent" />
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
android:text="라이브"
|
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/iv_thumbnail"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:contentDescription="@null"
|
||||||
|
android:scaleType="centerCrop" />
|
||||||
|
|
||||||
|
</FrameLayout>
|
|
@ -0,0 +1,97 @@
|
||||||
|
<?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"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="133.3dp"
|
||||||
|
android:layout_height="176.7dp"
|
||||||
|
android:background="@color/black">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/iv_cover"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:contentDescription="@null"
|
||||||
|
android:scaleType="centerCrop"
|
||||||
|
tools:src="@drawable/ic_launcher_background" />
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
android:background="@drawable/gradient_live_room_item"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tv_price"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="3.3dp"
|
||||||
|
android:layout_marginTop="3.3dp"
|
||||||
|
android:fontFamily="@font/gmarket_sans_medium"
|
||||||
|
android:paddingHorizontal="7.3dp"
|
||||||
|
android:paddingVertical="4dp"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:textSize="12sp"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
tools:background="@drawable/bg_round_corner_10_881609"
|
||||||
|
tools:text="유료" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/iv_19"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="3.3dp"
|
||||||
|
android:layout_marginEnd="3.3dp"
|
||||||
|
android:contentDescription="@null"
|
||||||
|
android:src="@drawable/ic_19"
|
||||||
|
android:visibility="gone"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/iv_lock"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="3.3dp"
|
||||||
|
android:layout_marginEnd="3.3dp"
|
||||||
|
android:contentDescription="@null"
|
||||||
|
android:src="@drawable/ic_lock"
|
||||||
|
android:visibility="gone"
|
||||||
|
app:layout_constraintEnd_toStartOf="@+id/iv_19"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tv_number_of_members"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="6.7dp"
|
||||||
|
android:layout_marginBottom="6.7dp"
|
||||||
|
android:gravity="center_vertical|start"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:textSize="13.3sp"
|
||||||
|
app:drawableStartCompat="@drawable/ic_avatar"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toStartOf="@+id/tv_manager"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
tools:text="12" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tv_manager"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginEnd="6.7dp"
|
||||||
|
android:layout_marginBottom="6.7dp"
|
||||||
|
android:ellipsize="end"
|
||||||
|
android:ems="4"
|
||||||
|
android:gravity="end"
|
||||||
|
android:maxLines="1"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:textSize="13.3sp"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
tools:text="자입니다sss" />
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -0,0 +1,127 @@
|
||||||
|
<?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"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="131dp"
|
||||||
|
tools:background="@color/black">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/iv_cover"
|
||||||
|
android:layout_width="80dp"
|
||||||
|
android:layout_height="116.7dp"
|
||||||
|
android:contentDescription="@null"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/iv_19"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="3.3dp"
|
||||||
|
android:layout_marginTop="3.3dp"
|
||||||
|
android:contentDescription="@null"
|
||||||
|
android:src="@drawable/ic_19"
|
||||||
|
android:visibility="gone"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/ll_room_info"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="20dp"
|
||||||
|
android:layout_marginEnd="13.3dp"
|
||||||
|
android:orientation="vertical"
|
||||||
|
app:layout_constraintEnd_toStartOf="@+id/iv_lock"
|
||||||
|
app:layout_constraintStart_toEndOf="@+id/iv_cover"
|
||||||
|
app:layout_constraintTop_toTopOf="@+id/iv_cover"
|
||||||
|
app:layout_goneMarginEnd="20dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tv_date"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:fontFamily="@font/gmarket_sans_medium"
|
||||||
|
android:textColor="@color/color_ffd300"
|
||||||
|
android:textSize="9.3sp"
|
||||||
|
tools:ignore="SmallSp"
|
||||||
|
tools:text="2021.06.20 SUN 10:00 PM" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tv_nickname"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="10dp"
|
||||||
|
android:fontFamily="@font/gmarket_sans_medium"
|
||||||
|
android:textColor="@color/color_bbbbbb"
|
||||||
|
android:textSize="11.3sp"
|
||||||
|
tools:text="사냥꾼 1004" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tv_title"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="10dp"
|
||||||
|
android:ellipsize="end"
|
||||||
|
android:fontFamily="@font/gmarket_sans_medium"
|
||||||
|
android:maxLines="2"
|
||||||
|
android:textColor="@color/color_e2e2e2"
|
||||||
|
android:textSize="15.3sp"
|
||||||
|
tools:text="여자들이 좋아하는 남자 스타일은?" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/iv_lock"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginEnd="13.3dp"
|
||||||
|
android:contentDescription="@null"
|
||||||
|
android:src="@drawable/ic_lock"
|
||||||
|
android:visibility="gone"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="@+id/iv_cover" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/ll_price"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginHorizontal="20dp"
|
||||||
|
android:gravity="start|center_vertical"
|
||||||
|
app:layout_constraintBottom_toBottomOf="@+id/iv_cover"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toEndOf="@+id/iv_cover">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tv_price"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:fontFamily="@font/gmarket_sans_medium"
|
||||||
|
android:textColor="@color/color_7fe2e2e2"
|
||||||
|
android:textSize="12sp"
|
||||||
|
tools:text="300코인" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tv_complete_reservation"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="@drawable/bg_round_corner_10_533d89"
|
||||||
|
android:fontFamily="@font/gmarket_sans_medium"
|
||||||
|
android:paddingHorizontal="7.5dp"
|
||||||
|
android:paddingVertical="4.3dp"
|
||||||
|
android:text="예약완료"
|
||||||
|
android:textColor="@color/color_d2d2d2"
|
||||||
|
android:textSize="11.3sp"
|
||||||
|
android:visibility="gone" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:id="@+id/divider"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="1dp"
|
||||||
|
android:background="@color/color_88909090"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent" />
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -0,0 +1,113 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
tools:background="@color/black">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tv_my_live"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginBottom="8dp"
|
||||||
|
android:drawablePadding="8dp"
|
||||||
|
android:fontFamily="@font/gmarket_sans_bold"
|
||||||
|
android:text="내가 개설한 라이브"
|
||||||
|
android:textColor="@color/color_9970ff"
|
||||||
|
android:textSize="16sp"
|
||||||
|
app:drawableStartCompat="@drawable/ic_mic_colored" />
|
||||||
|
|
||||||
|
<RelativeLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="@drawable/bg_round_corner_8_transparent_9970ff"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:padding="1dp">
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:id="@+id/ll_cover"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/iv_cover"
|
||||||
|
android:layout_width="80dp"
|
||||||
|
android:layout_height="116.7dp"
|
||||||
|
android:contentDescription="@null"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/iv_19"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="3.3dp"
|
||||||
|
android:layout_marginTop="3.3dp"
|
||||||
|
android:contentDescription="@null"
|
||||||
|
android:src="@drawable/ic_19"
|
||||||
|
android:visibility="gone" />
|
||||||
|
</FrameLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_centerVertical="true"
|
||||||
|
android:layout_marginStart="30dp"
|
||||||
|
android:layout_toStartOf="@+id/iv_lock"
|
||||||
|
android:layout_toEndOf="@+id/ll_cover"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tv_date"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:fontFamily="@font/gmarket_sans_medium"
|
||||||
|
android:textColor="@color/color_ffd300"
|
||||||
|
android:textSize="9.3sp"
|
||||||
|
tools:ignore="SmallSp"
|
||||||
|
tools:text="2021.06.20 SUN 10:00 PM" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tv_nickname"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="10dp"
|
||||||
|
android:layout_marginBottom="4dp"
|
||||||
|
android:fontFamily="@font/gmarket_sans_medium"
|
||||||
|
android:textColor="@color/color_bbbbbb"
|
||||||
|
android:textSize="11.3sp"
|
||||||
|
tools:text="사냥꾼 1004" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tv_title"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:ellipsize="end"
|
||||||
|
android:fontFamily="@font/gmarket_sans_medium"
|
||||||
|
android:maxLines="2"
|
||||||
|
android:textColor="@color/color_e2e2e2"
|
||||||
|
android:textSize="15.3sp"
|
||||||
|
tools:text="여자들이 좋아하는 남자 스타일은?" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/iv_lock"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_alignParentEnd="true"
|
||||||
|
android:layout_marginTop="13.3dp"
|
||||||
|
android:layout_marginEnd="13.3dp"
|
||||||
|
android:contentDescription="@null"
|
||||||
|
android:src="@drawable/ic_lock"
|
||||||
|
android:visibility="gone" />
|
||||||
|
</RelativeLayout>
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:id="@+id/divider"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="1dp"
|
||||||
|
android:layout_marginTop="13dp"
|
||||||
|
android:background="@color/color_88909090" />
|
||||||
|
</LinearLayout>
|
|
@ -0,0 +1,53 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="60dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:gravity="center"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:layout_width="60dp"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/iv_recommend_channel"
|
||||||
|
android:layout_width="60dp"
|
||||||
|
android:layout_height="60dp"
|
||||||
|
android:contentDescription="@null" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/iv_recommend_channel_bg"
|
||||||
|
android:layout_width="60dp"
|
||||||
|
android:layout_height="60dp"
|
||||||
|
android:contentDescription="@null"
|
||||||
|
android:src="@drawable/bg_round_corner_33_3_transparent_9970ff" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tv_recommend_channel"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="bottom|center_horizontal"
|
||||||
|
android:background="@drawable/bg_round_corner_6_7_9970ff"
|
||||||
|
android:fontFamily="@font/gmarket_sans_bold"
|
||||||
|
android:paddingHorizontal="5.7dp"
|
||||||
|
android:paddingVertical="2.7dp"
|
||||||
|
android:text="LIVE"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:textSize="8.7sp"
|
||||||
|
tools:ignore="SmallSp" />
|
||||||
|
</FrameLayout>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tv_recommend_channel_nickname"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="11.3dp"
|
||||||
|
android:ellipsize="end"
|
||||||
|
android:fontFamily="@font/gmarket_sans_medium"
|
||||||
|
android:lines="1"
|
||||||
|
android:textColor="@color/color_bbbbbb"
|
||||||
|
android:textSize="11.3sp"
|
||||||
|
tools:text="검은사신" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
|
@ -0,0 +1,13 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/iv_recommend_live"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:contentDescription="@null"
|
||||||
|
android:scaleType="centerCrop" />
|
||||||
|
|
||||||
|
</FrameLayout>
|
|
@ -0,0 +1,100 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<RelativeLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:paddingHorizontal="13.3dp">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:fontFamily="@font/gmarket_sans_bold"
|
||||||
|
android:text="지금 "
|
||||||
|
android:textColor="@color/color_eeeeee"
|
||||||
|
android:textSize="18.3sp" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:fontFamily="@font/gmarket_sans_bold"
|
||||||
|
android:text="라이브중"
|
||||||
|
android:textColor="@color/color_ff5c49"
|
||||||
|
android:textSize="18.3sp" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tv_all_view"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_alignParentEnd="true"
|
||||||
|
android:layout_centerVertical="true"
|
||||||
|
android:fontFamily="@font/gmarket_sans_light"
|
||||||
|
android:text="전체보기"
|
||||||
|
android:textColor="@color/color_bbbbbb"
|
||||||
|
android:textSize="11.3sp" />
|
||||||
|
</RelativeLayout>
|
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/rv_suda_now"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="28.3dp"
|
||||||
|
android:visibility="gone" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/ll_no_items"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginHorizontal="13.3dp"
|
||||||
|
android:layout_marginTop="28.3dp"
|
||||||
|
android:background="@drawable/bg_round_corner_4_7_2b2635"
|
||||||
|
android:gravity="center"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:paddingVertical="16.7dp"
|
||||||
|
android:visibility="gone">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:contentDescription="@null"
|
||||||
|
android:src="@drawable/ic_no_item" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginVertical="10dp"
|
||||||
|
android:fontFamily="@font/gmarket_sans_medium"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="🙀지금 참여가능한 라이브가 없습니다.\n직접 라이브를 만들어 보세요!"
|
||||||
|
android:textColor="@color/color_bbbbbb"
|
||||||
|
android:textSize="10.7sp"
|
||||||
|
tools:ignore="SmallSp" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tv_make_room"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="@drawable/bg_round_corner_4_7_9970ff"
|
||||||
|
android:drawablePadding="8.3dp"
|
||||||
|
android:fontFamily="@font/gmarket_sans_bold"
|
||||||
|
android:gravity="center"
|
||||||
|
android:paddingHorizontal="51.7dp"
|
||||||
|
android:paddingVertical="8.3dp"
|
||||||
|
android:text="라이브 만들기"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:textSize="13.3sp"
|
||||||
|
app:drawableStartCompat="@drawable/ic_plus_no_bg" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
</LinearLayout>
|
|
@ -0,0 +1,88 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<RelativeLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/ll_title_1"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:visibility="visible"
|
||||||
|
android:layout_centerVertical="true"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tv_title1"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:fontFamily="@font/gmarket_sans_bold"
|
||||||
|
android:text="추천 "
|
||||||
|
android:textColor="@color/color_eeeeee"
|
||||||
|
android:textSize="18.3sp" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:fontFamily="@font/gmarket_sans_bold"
|
||||||
|
android:text="채널"
|
||||||
|
android:textColor="@color/color_9970ff"
|
||||||
|
android:textSize="18.3sp" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/ll_title_2"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:visibility="gone"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_centerVertical="true"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:fontFamily="@font/gmarket_sans_bold"
|
||||||
|
android:text="팔로잉 "
|
||||||
|
android:textColor="@color/color_eeeeee"
|
||||||
|
android:textSize="18.3sp" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:fontFamily="@font/gmarket_sans_bold"
|
||||||
|
android:text="채널"
|
||||||
|
android:textColor="@color/color_9970ff"
|
||||||
|
android:textSize="18.3sp" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_centerVertical="true"
|
||||||
|
android:layout_marginEnd="6.7dp"
|
||||||
|
android:layout_toStartOf="@+id/iv_switch"
|
||||||
|
android:fontFamily="@font/gmarket_sans_medium"
|
||||||
|
android:text="팔로잉 채널"
|
||||||
|
android:textColor="@color/color_777777"
|
||||||
|
android:textSize="13.3sp" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/iv_switch"
|
||||||
|
android:layout_width="33.3dp"
|
||||||
|
android:layout_height="20dp"
|
||||||
|
android:layout_alignParentEnd="true"
|
||||||
|
android:layout_centerVertical="true"
|
||||||
|
android:contentDescription="@null"
|
||||||
|
android:src="@drawable/btn_toggle_off_big" />
|
||||||
|
</RelativeLayout>
|
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/rv_recommend_channel"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="21.3dp" />
|
||||||
|
</LinearLayout>
|
|
@ -0,0 +1,101 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<RelativeLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:paddingHorizontal="13.3dp">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:fontFamily="@font/gmarket_sans_bold"
|
||||||
|
android:text="지금 "
|
||||||
|
android:textColor="@color/color_eeeeee"
|
||||||
|
android:textSize="18.3sp" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:fontFamily="@font/gmarket_sans_bold"
|
||||||
|
android:text="예약중"
|
||||||
|
android:textColor="@color/color_9970ff"
|
||||||
|
android:textSize="18.3sp" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tv_all_view"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_alignParentEnd="true"
|
||||||
|
android:layout_centerVertical="true"
|
||||||
|
android:fontFamily="@font/gmarket_sans_light"
|
||||||
|
android:text="전체보기"
|
||||||
|
android:textColor="@color/color_bbbbbb"
|
||||||
|
android:textSize="11.3sp" />
|
||||||
|
</RelativeLayout>
|
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/rv_suda_reservation"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="28.3dp"
|
||||||
|
android:nestedScrollingEnabled="false"
|
||||||
|
android:visibility="gone" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/ll_no_items"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginHorizontal="13.3dp"
|
||||||
|
android:layout_marginVertical="28.3dp"
|
||||||
|
android:background="@drawable/bg_round_corner_4_7_2b2635"
|
||||||
|
android:gravity="center"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:paddingVertical="16.7dp"
|
||||||
|
android:visibility="gone">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:contentDescription="@null"
|
||||||
|
android:src="@drawable/ic_no_item" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginVertical="10dp"
|
||||||
|
android:fontFamily="@font/gmarket_sans_medium"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="지금 예약중인 라이브가 없습니다.\n직접 라이브를 만들어 보세요!"
|
||||||
|
android:textColor="@color/color_bbbbbb"
|
||||||
|
android:textSize="10.7sp"
|
||||||
|
tools:ignore="SmallSp" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tv_make_room"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="@drawable/bg_round_corner_4_7_9970ff"
|
||||||
|
android:drawablePadding="8.3dp"
|
||||||
|
android:fontFamily="@font/gmarket_sans_bold"
|
||||||
|
android:gravity="center"
|
||||||
|
android:paddingHorizontal="51.7dp"
|
||||||
|
android:paddingVertical="8.3dp"
|
||||||
|
android:text="라이브 만들기"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:textSize="13.3sp"
|
||||||
|
app:drawableStartCompat="@drawable/ic_plus_no_bg" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
</LinearLayout>
|
|
@ -0,0 +1,41 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:fontFamily="@font/gmarket_sans_bold"
|
||||||
|
android:text="추천 "
|
||||||
|
android:textColor="@color/color_ff5c49"
|
||||||
|
android:textSize="18.3sp" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:fontFamily="@font/gmarket_sans_bold"
|
||||||
|
android:text="라이브"
|
||||||
|
android:textColor="@color/color_eeeeee"
|
||||||
|
android:textSize="18.3sp" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<com.zhpan.bannerview.BannerViewPager
|
||||||
|
android:id="@+id/pager"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="26.7dp" />
|
||||||
|
|
||||||
|
<com.zhpan.indicator.IndicatorView
|
||||||
|
android:id="@+id/indicator2"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:layout_marginTop="6.7dp" />
|
||||||
|
</LinearLayout>
|
|
@ -13,8 +13,17 @@
|
||||||
<color name="color_a0e2ff">#A0E2FF</color>
|
<color name="color_a0e2ff">#A0E2FF</color>
|
||||||
<color name="color_ecfaff">#ECFAFF</color>
|
<color name="color_ecfaff">#ECFAFF</color>
|
||||||
<color name="color_111111">#111111</color>
|
<color name="color_111111">#111111</color>
|
||||||
|
<color name="color_ff5c49">#FF5C49</color>
|
||||||
|
<color name="color_2b2635">#2b2635</color>
|
||||||
|
<color name="color_ffd300">#FFD300</color>
|
||||||
|
<color name="color_e2e2e2">#E2E2E2</color>
|
||||||
|
<color name="color_d2d2d2">#D2D2D2</color>
|
||||||
|
<color name="color_533d89">#533D89</color>
|
||||||
|
<color name="color_643bc8">#643BC8</color>
|
||||||
|
<color name="color_881609">#881609</color>
|
||||||
|
|
||||||
<color name="color_b3909090">#B3909090</color>
|
<color name="color_b3909090">#B3909090</color>
|
||||||
<color name="color_88909090">#88909090</color>
|
<color name="color_88909090">#88909090</color>
|
||||||
<color name="color_339970ff">#339970FF</color>
|
<color name="color_339970ff">#339970FF</color>
|
||||||
|
<color name="color_7fe2e2e2">#7FE2E2E2</color>
|
||||||
</resources>
|
</resources>
|
||||||
|
|