From 6c9ace146de9349dcef4172d0b49045e8e20e915 Mon Sep 17 00:00:00 2001 From: klaus Date: Wed, 16 Oct 2024 15:08:36 +0900 Subject: [PATCH] =?UTF-8?q?=EB=9D=BC=EC=9D=B4=EB=B8=8C=20=EB=B0=A9=20-=20?= =?UTF-8?q?=ED=95=98=ED=8A=B8=20=EC=95=A0=EB=8B=88=EB=A9=94=EC=9D=B4?= =?UTF-8?q?=EC=85=98=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sodalive/live/room/LiveRoomActivity.kt | 124 +- .../main/res/layout/activity_live_room.xml | 1110 ++++++++--------- 2 files changed, 667 insertions(+), 567 deletions(-) diff --git a/app/src/main/java/kr/co/vividnext/sodalive/live/room/LiveRoomActivity.kt b/app/src/main/java/kr/co/vividnext/sodalive/live/room/LiveRoomActivity.kt index ae63523..2986414 100644 --- a/app/src/main/java/kr/co/vividnext/sodalive/live/room/LiveRoomActivity.kt +++ b/app/src/main/java/kr/co/vividnext/sodalive/live/room/LiveRoomActivity.kt @@ -1,5 +1,6 @@ package kr.co.vividnext.sodalive.live.room +import android.animation.ObjectAnimator import android.annotation.SuppressLint import android.app.AlertDialog import android.app.Service @@ -21,8 +22,11 @@ import android.text.method.LinkMovementMethod import android.text.style.ClickableSpan import android.view.LayoutInflater import android.view.View +import android.view.animation.AccelerateDecelerateInterpolator import android.view.inputmethod.EditorInfo import android.view.inputmethod.InputMethodManager +import android.widget.FrameLayout +import android.widget.ImageView import android.widget.TextView import android.widget.Toast import androidx.activity.OnBackPressedCallback @@ -90,6 +94,7 @@ import kr.co.vividnext.sodalive.report.UserReportDialog import kr.co.vividnext.sodalive.settings.notification.MemberRole import org.koin.android.ext.android.inject import java.util.regex.Pattern +import kotlin.random.Random class LiveRoomActivity : BaseActivity(ActivityLiveRoomBinding::inflate) { @@ -257,17 +262,6 @@ class LiveRoomActivity : BaseActivity(ActivityLiveRoomB viewModel.getMemberCan() viewModel.getRoomInfo(roomId) viewModel.getBlockedMemberIdList() - - binding.etChat.setOnFocusChangeListener { view, hasFocus -> - if (isNoChatting && hasFocus) { - Toast.makeText( - applicationContext, - "${remainingNoChattingTime}초 동안 채팅하실 수 없습니다", - Toast.LENGTH_SHORT - ).show() - view.clearFocus() - } - } } override fun onStart() { @@ -449,6 +443,16 @@ class LiveRoomActivity : BaseActivity(ActivityLiveRoomB } ) + binding.etChat.setOnFocusChangeListener { view, hasFocus -> + if (isNoChatting && hasFocus) { + Toast.makeText( + applicationContext, + "${remainingNoChattingTime}초 동안 채팅하실 수 없습니다", + Toast.LENGTH_SHORT + ).show() + view.clearFocus() + } + } binding.tvQuit.setOnClickListener { onClickQuit() } binding.flMicrophoneMute.setOnClickListener { microphoneMute() @@ -522,6 +526,102 @@ class LiveRoomActivity : BaseActivity(ActivityLiveRoomB super.onDestroy() } + private fun secondToMillis(second: Float): Long { + return (second * 1000).toLong() + } + + private fun addHeartAnimation(button: View) { + // 버튼의 위치 + val buttonPosition = IntArray(2) + button.getLocationInWindow(buttonPosition) + + // 하트 이미지뷰 생성 + val heart = ImageView(this).apply { + setImageResource(R.drawable.ic_heart_pink) // 투명한 하트 이미지 + layoutParams = FrameLayout.LayoutParams( + 33.3f.dpToPx().toInt(), + 33.3f.dpToPx().toInt() + ) // 하트 크기 설정 + } + + // 하트의 초기 위치를 버튼의 위치로 설정 + heart.x = (buttonPosition[0] + button.width / 2f - 50) // X축 (가운데 정렬) + heart.y = (buttonPosition[1] - 100).toFloat() // Y축 (버튼 바로 위에 생성) + + binding.flRoot.addView(heart) + + // 하트가 위로 올라가는 애니메이션 + val animateDuration = secondToMillis(2.5f) + val moveUpAnimator = ObjectAnimator.ofFloat( + heart, + "translationY", + heart.y, + heart.y - (screenHeight * 1000 / 2337) + ).apply { + duration = animateDuration + interpolator = AccelerateDecelerateInterpolator() + } + + val isNegativeFirst = Random.nextBoolean() + + // 좌우 이동 범위를 랜덤으로 설정 + val x = 13.3f + val startX = if (isNegativeFirst) (0 - x).dpToPx() else x.dpToPx() + val endX = if (isNegativeFirst) x.dpToPx() else (0 - x).dpToPx() + + val moveAnimator = ObjectAnimator.ofFloat( + heart, + "translationX", + heart.x + startX, + heart.x + endX + ).apply { + duration = secondToMillis(1.5f) + repeatCount = ObjectAnimator.INFINITE + repeatMode = ObjectAnimator.REVERSE + interpolator = AccelerateDecelerateInterpolator() + } + + val scaleXAnimator = ObjectAnimator.ofFloat( + heart, + "scaleX", + 0.5f, + 1.0f + ).apply { + duration = animateDuration + } + + val scaleYAnimator = ObjectAnimator.ofFloat( + heart, + "scaleY", + 0.5f, + 1.0f + ).apply { + duration = animateDuration + } + + // 하트 투명도 애니메이션 + val fadeOutAnimator = ObjectAnimator.ofFloat( + heart, + "alpha", + 1f, + 0f + ).apply { + duration = animateDuration + } + + // 애니메이션 실행 + moveUpAnimator.start() + moveAnimator.start() + fadeOutAnimator.start() + scaleXAnimator.start() + scaleYAnimator.start() + + // 애니메이션이 끝나면 하트 제거 + handler.postDelayed({ + binding.flRoot.removeView(heart) + }, animateDuration) + } + private fun showOptionMenu( context: Context, userId: Long, @@ -997,7 +1097,7 @@ class LiveRoomActivity : BaseActivity(ActivityLiveRoomB private fun initLikeHeartButton(isHost: Boolean) { if (!isHost) { binding.flLikeHeart.visibility = View.VISIBLE - binding.flLikeHeart.setOnClickListener { } + binding.flLikeHeart.setOnClickListener { addHeartAnimation(it) } } else { binding.flLikeHeart.visibility = View.GONE } diff --git a/app/src/main/res/layout/activity_live_room.xml b/app/src/main/res/layout/activity_live_room.xml index 6e828c7..2d1cd97 100644 --- a/app/src/main/res/layout/activity_live_room.xml +++ b/app/src/main/res/layout/activity_live_room.xml @@ -1,555 +1,555 @@ - + android:background="@color/black" + android:keepScreenOn="true"> - - - - - - - - - + + android:scaleType="fitCenter" + app:layout_constraintBottom_toTopOf="@+id/rl_input_chat" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@id/ll_top" /> - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + android:layout_marginBottom="13.3dp" + android:orientation="vertical" + android:visibility="gone" + app:layout_constraintBottom_toTopOf="@+id/rl_input_chat" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@+id/ll_top"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + android:layout_marginTop="16.7dp" + android:paddingHorizontal="13.3dp"> - - - - - - - - + + android:layout_marginStart="6.7dp" + android:layout_toEndOf="@+id/tv_quit" + android:gravity="end" + android:orientation="horizontal"> - + android:layout_marginEnd="8dp" + android:background="@drawable/bg_round_corner_5_3_transparent_bbbbbb" + android:fontFamily="@font/gmarket_sans_medium" + android:gravity="center" + android:paddingHorizontal="8dp" + android:paddingVertical="4.7dp" + android:text="리스너 변경" + android:textColor="@color/color_eeeeee" + android:textSize="12sp" + android:visibility="gone" + tools:ignore="SmallSp" /> - - - - - - + android:layout_marginEnd="8dp" + android:background="@drawable/bg_round_corner_5_3_transparent_bbbbbb" + android:fontFamily="@font/gmarket_sans_medium" + android:gravity="center" + android:paddingHorizontal="8dp" + android:paddingVertical="4.7dp" + android:text="시그 OFF" + android:textColor="@color/color_eeeeee" + android:textSize="12sp" + tools:ignore="SmallSp" /> - + - - + + + - - + android:layout_marginHorizontal="13.3dp" + android:layout_marginTop="12dp"> - - - - - - - - - + android:padding="5.3dp"> - + - + + + + + + + - + android:layout_alignParentEnd="true" + android:layout_centerVertical="true" + android:layout_marginHorizontal="5.3dp" + android:layout_toEndOf="@+id/rl_creator_profile" + android:orientation="vertical"> - + + + + + + + + + + + + + + + + + + + + + + android:text="공지" + android:textColor="@color/color_bbbbbb" + android:textSize="11sp" + tools:ignore="SmallSp" /> - - - - - - + + - + android:background="@drawable/bg_round_corner_5_3_transparent_bbbbbb" + android:gravity="center" + android:paddingHorizontal="8dp" + android:paddingVertical="5.3dp" + tools:ignore="RelativeOverlap"> - + + + + + + android:layout_marginStart="5.3dp" + android:background="@drawable/bg_round_corner_5_3_transparent_bbbbbb" + android:gravity="center" + android:paddingHorizontal="8dp" + android:paddingVertical="5.3dp" + tools:ignore="RelativeOverlap"> + + + + + + + + + + + + - - - + + - - - - - + + + android:orientation="vertical" + android:paddingStart="6.7dp" + android:paddingEnd="13.3dp" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent"> - - - - - - - - - + android:layout_marginBottom="13.3dp" + android:background="@drawable/bg_round_corner_16_7_cc555555" + android:drawablePadding="6.7dp" + android:paddingHorizontal="13.3dp" + android:paddingVertical="8dp" + android:text="새로운 채팅" + android:textColor="@color/color_eeeeee" + android:visibility="gone" + app:drawableStartCompat="@drawable/ic_bottom_white" + app:layout_constraintBottom_toTopOf="@+id/rl_input_chat" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" /> - - + + + + + + + + + +