parent
ad5a84c3b8
commit
40335fb7ff
|
@ -3,6 +3,7 @@ package kr.co.vividnext.sodalive.audio_content.playlist.create
|
||||||
import android.app.Service
|
import android.app.Service
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.inputmethod.InputMethodManager
|
import android.view.inputmethod.InputMethodManager
|
||||||
|
import kr.co.vividnext.sodalive.audio_content.playlist.create.add_content.PlaylistAddContentDialogFragment
|
||||||
import kr.co.vividnext.sodalive.base.BaseActivity
|
import kr.co.vividnext.sodalive.base.BaseActivity
|
||||||
import kr.co.vividnext.sodalive.common.LoadingDialog
|
import kr.co.vividnext.sodalive.common.LoadingDialog
|
||||||
import kr.co.vividnext.sodalive.databinding.ActivityAudioContentPlaylistCreateBinding
|
import kr.co.vividnext.sodalive.databinding.ActivityAudioContentPlaylistCreateBinding
|
||||||
|
@ -14,6 +15,10 @@ class AudioContentPlaylistCreateActivity : BaseActivity<ActivityAudioContentPlay
|
||||||
private lateinit var imm: InputMethodManager
|
private lateinit var imm: InputMethodManager
|
||||||
private lateinit var loadingDialog: LoadingDialog
|
private lateinit var loadingDialog: LoadingDialog
|
||||||
|
|
||||||
|
private val addContentDialogFragment: PlaylistAddContentDialogFragment by lazy {
|
||||||
|
PlaylistAddContentDialogFragment()
|
||||||
|
}
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
|
||||||
|
@ -27,5 +32,10 @@ class AudioContentPlaylistCreateActivity : BaseActivity<ActivityAudioContentPlay
|
||||||
binding.tvBack.setOnClickListener { finish() }
|
binding.tvBack.setOnClickListener { finish() }
|
||||||
|
|
||||||
loadingDialog = LoadingDialog(this, layoutInflater)
|
loadingDialog = LoadingDialog(this, layoutInflater)
|
||||||
|
|
||||||
|
binding.tvAddContent.setOnClickListener {
|
||||||
|
if (addContentDialogFragment.isAdded) return@setOnClickListener
|
||||||
|
addContentDialogFragment.show(supportFragmentManager, addContentDialogFragment.tag)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,62 @@
|
||||||
|
package kr.co.vividnext.sodalive.audio_content.playlist.create.add_content
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint
|
||||||
|
import android.content.Context
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import com.bumptech.glide.Glide
|
||||||
|
import com.bumptech.glide.load.resource.bitmap.CenterCrop
|
||||||
|
import com.bumptech.glide.load.resource.bitmap.RoundedCorners
|
||||||
|
import com.bumptech.glide.request.RequestOptions
|
||||||
|
import kr.co.vividnext.sodalive.audio_content.order.GetAudioContentOrderListItem
|
||||||
|
import kr.co.vividnext.sodalive.databinding.ItemPlaylistAddContentBinding
|
||||||
|
import kr.co.vividnext.sodalive.extensions.dpToPx
|
||||||
|
|
||||||
|
class PlaylistAddContentAdapter : RecyclerView.Adapter<PlaylistAddContentAdapter.ViewHolder>() {
|
||||||
|
|
||||||
|
var items = mutableListOf<GetAudioContentOrderListItem>()
|
||||||
|
|
||||||
|
inner class ViewHolder(
|
||||||
|
private val context: Context,
|
||||||
|
private val binding: ItemPlaylistAddContentBinding
|
||||||
|
) : RecyclerView.ViewHolder(binding.root) {
|
||||||
|
fun bind(item: GetAudioContentOrderListItem) {
|
||||||
|
Glide
|
||||||
|
.with(context)
|
||||||
|
.load(item.coverImageUrl)
|
||||||
|
.apply(
|
||||||
|
RequestOptions().transform(
|
||||||
|
CenterCrop(),
|
||||||
|
RoundedCorners(5.3f.dpToPx().toInt())
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.into(binding.ivCover)
|
||||||
|
|
||||||
|
binding.tvTitle.text = item.title
|
||||||
|
binding.tvTheme.text = item.themeStr
|
||||||
|
binding.tvDuration.text = item.duration
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ViewHolder(
|
||||||
|
parent.context,
|
||||||
|
ItemPlaylistAddContentBinding.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,167 @@
|
||||||
|
package kr.co.vividnext.sodalive.audio_content.playlist.create.add_content
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint
|
||||||
|
import android.app.Dialog
|
||||||
|
import android.graphics.Rect
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import android.widget.FrameLayout
|
||||||
|
import android.widget.Toast
|
||||||
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import com.google.android.material.bottomsheet.BottomSheetBehavior
|
||||||
|
import com.google.android.material.bottomsheet.BottomSheetDialog
|
||||||
|
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
|
||||||
|
import kr.co.vividnext.sodalive.audio_content.order.AudioContentOrderListViewModel
|
||||||
|
import kr.co.vividnext.sodalive.audio_content.playlist.create.AudioContentPlaylistCreateActivity
|
||||||
|
import kr.co.vividnext.sodalive.common.LoadingDialog
|
||||||
|
import kr.co.vividnext.sodalive.databinding.FragmentPlaylistAddContentBinding
|
||||||
|
import kr.co.vividnext.sodalive.extensions.dpToPx
|
||||||
|
import org.koin.android.ext.android.inject
|
||||||
|
|
||||||
|
class PlaylistAddContentDialogFragment : BottomSheetDialogFragment() {
|
||||||
|
|
||||||
|
private lateinit var binding: FragmentPlaylistAddContentBinding
|
||||||
|
private lateinit var adapter: PlaylistAddContentAdapter
|
||||||
|
private lateinit var loadingDialog: LoadingDialog
|
||||||
|
|
||||||
|
private val viewModel: AudioContentOrderListViewModel by inject()
|
||||||
|
|
||||||
|
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
||||||
|
val dialog = super.onCreateDialog(savedInstanceState)
|
||||||
|
|
||||||
|
dialog.setOnShowListener { dialogInterface ->
|
||||||
|
val d = dialogInterface as BottomSheetDialog
|
||||||
|
val bottomSheet = d.findViewById<FrameLayout>(
|
||||||
|
com.google.android.material.R.id.design_bottom_sheet
|
||||||
|
)
|
||||||
|
if (bottomSheet != null) {
|
||||||
|
BottomSheetBehavior.from(bottomSheet).state = BottomSheetBehavior.STATE_EXPANDED
|
||||||
|
}
|
||||||
|
bottomSheet?.let {
|
||||||
|
val behavior = BottomSheetBehavior.from(bottomSheet)
|
||||||
|
behavior.state = BottomSheetBehavior.STATE_EXPANDED
|
||||||
|
behavior.skipCollapsed = true
|
||||||
|
|
||||||
|
it.layoutParams.height = ViewGroup.LayoutParams.MATCH_PARENT
|
||||||
|
it.requestLayout()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return dialog
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreateView(
|
||||||
|
inflater: LayoutInflater,
|
||||||
|
container: ViewGroup?,
|
||||||
|
savedInstanceState: Bundle?
|
||||||
|
): View {
|
||||||
|
binding = FragmentPlaylistAddContentBinding.inflate(inflater, container, false)
|
||||||
|
return binding.root
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
|
||||||
|
setupView()
|
||||||
|
bindData()
|
||||||
|
viewModel.getAudioContentOrderList { dismiss() }
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setupView() {
|
||||||
|
binding.tvClose.setOnClickListener { dismiss() }
|
||||||
|
|
||||||
|
loadingDialog = LoadingDialog(requireActivity(), layoutInflater)
|
||||||
|
adapter = PlaylistAddContentAdapter()
|
||||||
|
|
||||||
|
val recyclerView = binding.rvContent
|
||||||
|
recyclerView.layoutManager = LinearLayoutManager(
|
||||||
|
requireContext(),
|
||||||
|
LinearLayoutManager.VERTICAL,
|
||||||
|
false
|
||||||
|
)
|
||||||
|
|
||||||
|
recyclerView.addItemDecoration(object : RecyclerView.ItemDecoration() {
|
||||||
|
override fun getItemOffsets(
|
||||||
|
outRect: Rect,
|
||||||
|
view: View,
|
||||||
|
parent: RecyclerView,
|
||||||
|
state: RecyclerView.State
|
||||||
|
) {
|
||||||
|
super.getItemOffsets(outRect, view, parent, state)
|
||||||
|
|
||||||
|
outRect.left = 13.3f.dpToPx().toInt()
|
||||||
|
outRect.right = 13.3f.dpToPx().toInt()
|
||||||
|
|
||||||
|
when (parent.getChildAdapterPosition(view)) {
|
||||||
|
0 -> {
|
||||||
|
outRect.top = 13.3f.dpToPx().toInt()
|
||||||
|
outRect.bottom = 6.7f.dpToPx().toInt()
|
||||||
|
}
|
||||||
|
|
||||||
|
adapter.itemCount - 1 -> {
|
||||||
|
outRect.top = 6.7f.dpToPx().toInt()
|
||||||
|
outRect.bottom = 13.3f.dpToPx().toInt()
|
||||||
|
}
|
||||||
|
|
||||||
|
else -> {
|
||||||
|
outRect.top = 6.7f.dpToPx().toInt()
|
||||||
|
outRect.bottom = 6.7f.dpToPx().toInt()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
recyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {
|
||||||
|
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
|
||||||
|
super.onScrolled(recyclerView, dx, dy)
|
||||||
|
|
||||||
|
val lastVisibleItemPosition = (recyclerView.layoutManager as LinearLayoutManager?)!!
|
||||||
|
.findLastCompletelyVisibleItemPosition()
|
||||||
|
val itemTotalCount = recyclerView.adapter!!.itemCount - 1
|
||||||
|
|
||||||
|
// 스크롤이 끝에 도달했는지 확인
|
||||||
|
if (!recyclerView.canScrollVertically(1) &&
|
||||||
|
lastVisibleItemPosition == itemTotalCount
|
||||||
|
) {
|
||||||
|
viewModel.getAudioContentOrderList {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
recyclerView.adapter = adapter
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressLint("SetTextI18n", "NotifyDataSetChanged")
|
||||||
|
private fun bindData() {
|
||||||
|
viewModel.toastLiveData.observe(viewLifecycleOwner) {
|
||||||
|
Toast.makeText(requireActivity(), it, Toast.LENGTH_LONG).show()
|
||||||
|
}
|
||||||
|
|
||||||
|
viewModel.isLoading.observe(viewLifecycleOwner) {
|
||||||
|
if (it) {
|
||||||
|
loadingDialog.show(
|
||||||
|
(requireActivity() as AudioContentPlaylistCreateActivity).screenWidth,
|
||||||
|
""
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
loadingDialog.dismiss()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
viewModel.orderList.observe(viewLifecycleOwner) {
|
||||||
|
if (viewModel.page == 2) {
|
||||||
|
adapter.items.clear()
|
||||||
|
}
|
||||||
|
|
||||||
|
adapter.items.addAll(it)
|
||||||
|
adapter.notifyDataSetChanged()
|
||||||
|
}
|
||||||
|
|
||||||
|
viewModel.totalCount.observe(viewLifecycleOwner) {
|
||||||
|
binding.tvContentCount.text = "${it}개"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Binary file not shown.
After Width: | Height: | Size: 631 B |
Binary file not shown.
After Width: | Height: | Size: 962 B |
|
@ -0,0 +1,69 @@
|
||||||
|
<?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="match_parent"
|
||||||
|
android:background="@color/black">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tv_title"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="17dp"
|
||||||
|
android:fontFamily="@font/gmarket_sans_bold"
|
||||||
|
android:text="새로운 콘텐츠 추가"
|
||||||
|
android:textColor="@color/color_eeeeee"
|
||||||
|
android:textSize="18sp"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tv_close"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginEnd="13dp"
|
||||||
|
android:fontFamily="@font/gmarket_sans_medium"
|
||||||
|
android:text="닫기"
|
||||||
|
android:textColor="@color/color_eeeeee"
|
||||||
|
app:layout_constraintBottom_toBottomOf="@+id/tv_title"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="@+id/tv_title" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tv_all"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="13.3dp"
|
||||||
|
android:layout_marginTop="13.3dp"
|
||||||
|
android:fontFamily="@font/gmarket_sans_medium"
|
||||||
|
android:text="전체"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:textSize="14.7sp"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/tv_title" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tv_content_count"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="5.3dp"
|
||||||
|
android:fontFamily="@font/gmarket_sans_medium"
|
||||||
|
android:textColor="@color/color_909090"
|
||||||
|
android:textSize="12sp"
|
||||||
|
app:layout_constraintBottom_toBottomOf="@+id/tv_all"
|
||||||
|
app:layout_constraintStart_toEndOf="@+id/tv_all"
|
||||||
|
app:layout_constraintTop_toTopOf="@+id/tv_all"
|
||||||
|
tools:text="40개" />
|
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/rv_content"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:clipToPadding="false"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/tv_all" />
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -0,0 +1,74 @@
|
||||||
|
<?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="wrap_content">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/iv_cover"
|
||||||
|
android:layout_width="40dp"
|
||||||
|
android:layout_height="40dp"
|
||||||
|
android:contentDescription="@null"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tv_theme"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="13.3dp"
|
||||||
|
android:background="@drawable/bg_round_corner_2_6_28312b"
|
||||||
|
android:fontFamily="@font/gmarket_sans_medium"
|
||||||
|
android:padding="2.6dp"
|
||||||
|
android:textColor="@color/color_3bac6a"
|
||||||
|
android:textSize="10sp"
|
||||||
|
app:layout_constraintStart_toEndOf="@+id/iv_cover"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
tools:ignore="SmallSp"
|
||||||
|
tools:text="커버곡" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tv_duration"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:layout_marginStart="8dp"
|
||||||
|
android:background="@drawable/bg_round_corner_2_6_222222"
|
||||||
|
android:fontFamily="@font/gmarket_sans_medium"
|
||||||
|
android:padding="2.6dp"
|
||||||
|
android:textColor="@color/color_777777"
|
||||||
|
android:textSize="10sp"
|
||||||
|
app:layout_constraintBottom_toBottomOf="@+id/tv_theme"
|
||||||
|
app:layout_constraintStart_toEndOf="@+id/tv_theme"
|
||||||
|
app:layout_constraintTop_toTopOf="@+id/tv_theme"
|
||||||
|
tools:ignore="SmallSp"
|
||||||
|
tools:text="00:30:20" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tv_title"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="13.3dp"
|
||||||
|
android:layout_marginTop="2.6dp"
|
||||||
|
android:layout_marginEnd="40dp"
|
||||||
|
android:ellipsize="end"
|
||||||
|
android:fontFamily="@font/gmarket_sans_medium"
|
||||||
|
android:maxLines="2"
|
||||||
|
android:textColor="@color/color_d2d2d2"
|
||||||
|
android:textSize="12sp"
|
||||||
|
app:layout_constraintEnd_toStartOf="@+id/iv_add"
|
||||||
|
app:layout_constraintStart_toEndOf="@+id/iv_cover"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/tv_theme"
|
||||||
|
tools:text="안녕하세요 오늘은 커버곡을 들려드릴께요....안녕하세요 오늘은 커버곡을 들려드릴께요...." />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/iv_add"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:contentDescription="@null"
|
||||||
|
android:src="@drawable/ic_playlist_add"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
Loading…
Reference in New Issue