sound 选择器 RV赋值

This commit is contained in:
renhaoting 2025-10-29 14:53:48 +08:00
parent 64fdf6f4ac
commit 293405c8d1
7 changed files with 88 additions and 40 deletions

View File

@ -6,10 +6,6 @@ import kotlinx.parcelize.Parcelize
@Parcelize @Parcelize
data class ChatSound( data class ChatSound(
/**
* code
*/
val code: String,
/** /**
* id * id
@ -34,7 +30,7 @@ data class ChatSound(
/** /**
* actor 性别 * actor 性别
*/ */
var isMale: Boolean, val isMale: Boolean,
/** /**
* 当前用户是否解锁 false:未解锁true:解锁 * 当前用户是否解锁 false:未解锁true:解锁
@ -50,7 +46,6 @@ data class ChatSound(
* 解锁类型 MEMBER:会员 HEARTBEAT_LEVEL:心动等级 * 解锁类型 MEMBER:会员 HEARTBEAT_LEVEL:心动等级
*/ */
val unlockType: String? = null, val unlockType: String? = null,
var isDefault: Boolean,
var select: Boolean = false var select: Boolean = false
) : Parcelable { ) : Parcelable {
companion object { companion object {

View File

@ -9,6 +9,7 @@ import android.widget.LinearLayout
import androidx.core.graphics.toColorInt import androidx.core.graphics.toColorInt
import com.remax.visualnovel.R import com.remax.visualnovel.R
import com.remax.visualnovel.databinding.LayoutChatMenuViewBinding import com.remax.visualnovel.databinding.LayoutChatMenuViewBinding
import com.remax.visualnovel.entity.response.ChatSound
import com.remax.visualnovel.ui.chat.ui.expandableSelector.SelectorItem import com.remax.visualnovel.ui.chat.ui.expandableSelector.SelectorItem
class ChatSettingView @JvmOverloads constructor( class ChatSettingView @JvmOverloads constructor(
@ -25,11 +26,12 @@ class ChatSettingView @JvmOverloads constructor(
} }
initAiModelList() initAiModelSelectorView()
initSoundSelectorView()
} }
fun initAiModelList() { fun initAiModelSelectorView() {
val items = listOf( val items = listOf(
SelectorItem( SelectorItem(
name = "Max-0618", name = "Max-0618",
@ -63,9 +65,51 @@ class ChatSettingView @JvmOverloads constructor(
mBinding.aiModelSelector.setTitleIcon(R.mipmap.setting_ai_model) mBinding.aiModelSelector.setTitleIcon(R.mipmap.setting_ai_model)
mBinding.aiModelSelector.setItems(items) mBinding.aiModelSelector.setItems(items)
mBinding.aiModelSelector.selectItem(0) mBinding.aiModelSelector.selectItem(0)
//mBinding.aiModelSelector.setTitleText(R.string.xxxx) }
fun initSoundSelectorView() {
val items = listOf(
ChatSound(
id = 1L,
name = "Sound-1",
description = "This is description for sound-1",
isMale = true,
imgUrl = "aa"
),
ChatSound(
id = 2L,
name = "Sound-2",
description = "This is description for sound-2",
isMale = true,
imgUrl = "aa"
),
ChatSound(
id = 3L,
name = "Sound-3",
description = "This is description for sound-3",
isMale = true,
imgUrl = "aa"
),
ChatSound(
id = 4L,
name = "Sound-4",
description = "This is description for sound-4",
isMale = true,
imgUrl = "aa"
),
ChatSound(
id = 5L,
name = "Sound-5",
description = "This is description for sound-5",
isMale = true,
imgUrl = "aa"
)
)
mBinding.soundActorSelector.setItems(items)
} }

View File

@ -5,13 +5,18 @@ import android.animation.AnimatorListenerAdapter
import android.animation.ObjectAnimator import android.animation.ObjectAnimator
import android.animation.ValueAnimator import android.animation.ValueAnimator
import android.content.Context import android.content.Context
import android.graphics.drawable.GradientDrawable
import android.util.AttributeSet import android.util.AttributeSet
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.ViewGroup import android.view.View
import android.view.animation.AccelerateDecelerateInterpolator import android.view.animation.AccelerateDecelerateInterpolator
import android.widget.LinearLayout import android.widget.LinearLayout
import android.widget.TextView
import com.remax.visualnovel.R import com.remax.visualnovel.R
import com.remax.visualnovel.databinding.LayoutExpandSoundSelectViewBinding import com.remax.visualnovel.databinding.LayoutExpandSelectViewBinding
import com.remax.visualnovel.databinding.LayoutSettingSoundSubViewBinding
import com.remax.visualnovel.entity.response.ChatSound
import com.remax.visualnovel.utils.spannablex.utils.dp
class ExpandSoundSelectView @JvmOverloads constructor( class ExpandSoundSelectView @JvmOverloads constructor(
@ -19,8 +24,8 @@ class ExpandSoundSelectView @JvmOverloads constructor(
attrs: AttributeSet? = null, attrs: AttributeSet? = null,
defStyleAttr: Int = 0 defStyleAttr: Int = 0
) : LinearLayout(context, attrs, defStyleAttr) { ) : LinearLayout(context, attrs, defStyleAttr) {
private lateinit var mBinding: LayoutExpandSelectViewBinding
private lateinit var mBinding: LayoutExpandSoundSelectViewBinding private lateinit var mExpandView : ExpandSoundSubView
private var isExpanded = false private var isExpanded = false
private var animationDuration = 300 private var animationDuration = 300
@ -31,19 +36,13 @@ class ExpandSoundSelectView @JvmOverloads constructor(
} }
private fun initView(context: Context, attrs: AttributeSet?) { private fun initView(context: Context, attrs: AttributeSet?) {
mBinding = LayoutExpandSoundSelectViewBinding.inflate(LayoutInflater.from(context)) mBinding = LayoutExpandSelectViewBinding.inflate(LayoutInflater.from(context), this, true)
setupAttributes(attrs)
setupClickListeners()
}
private fun setupAttributes(attrs: AttributeSet?) { mExpandView = ExpandSoundSubView(context)
attrs?.let { mBinding.itemsContainer.addView(mExpandView, LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT))
val typedArray = context.obtainStyledAttributes(it, R.styleable.ExpandableSelector) setTitleText(R.string.title_sound_actor)
val title = typedArray.getString(R.styleable.ExpandableSelector_titleText) setTitleIcon(R.mipmap.setting_sound_icon)
title?.let { mBinding.titleText.text = it } setupClickListeners()
animationDuration = typedArray.getInt(R.styleable.ExpandableSelector_animationDuration, 300)
typedArray.recycle()
}
} }
private fun setupClickListeners() { private fun setupClickListeners() {
@ -59,6 +58,10 @@ class ExpandSoundSelectView @JvmOverloads constructor(
mBinding.titleText.text = context.resources.getString(titleRes) mBinding.titleText.text = context.resources.getString(titleRes)
} }
fun setItems(newItems: List<ChatSound>) {
mExpandView.setItems(newItems)
}
fun toggle() { fun toggle() {
if (isExpanded) collapse() else expand() if (isExpanded) collapse() else expand()
@ -68,7 +71,7 @@ class ExpandSoundSelectView @JvmOverloads constructor(
if (isExpanded) return if (isExpanded) return
isExpanded = true isExpanded = true
mBinding.itemsContainer.visibility = VISIBLE mBinding.itemsContainer.visibility = View.VISIBLE
animateArrow(0f, 90f) animateArrow(0f, 90f)
// param height anim // param height anim
val animator = ValueAnimator.ofInt(0, getItemsHeight()) val animator = ValueAnimator.ofInt(0, getItemsHeight())
@ -101,7 +104,7 @@ class ExpandSoundSelectView @JvmOverloads constructor(
} }
animator.addListener(object : AnimatorListenerAdapter() { animator.addListener(object : AnimatorListenerAdapter() {
override fun onAnimationEnd(animation: Animator) { override fun onAnimationEnd(animation: Animator) {
mBinding.itemsContainer.visibility = GONE mBinding.itemsContainer.visibility = View.GONE
} }
}) })
animator.start() animator.start()
@ -134,11 +137,4 @@ class ExpandSoundSelectView @JvmOverloads constructor(
interface OnItemSelectedListener { interface OnItemSelectedListener {
fun onItemSelected(position: Int, item: SelectorItem) fun onItemSelected(position: Int, item: SelectorItem)
} }
/* new added */
fun setCustomExpandView(expandView: ViewGroup) {
mBinding.itemsContainer.addView(expandView)
}
} }

View File

@ -9,11 +9,14 @@ import com.drake.brv.annotaion.DividerOrientation
import com.drake.brv.utils.bindingAdapter import com.drake.brv.utils.bindingAdapter
import com.drake.brv.utils.divider import com.drake.brv.utils.divider
import com.drake.brv.utils.grid import com.drake.brv.utils.grid
import com.drake.brv.utils.linear
import com.drake.brv.utils.models
import com.drake.brv.utils.setup import com.drake.brv.utils.setup
import com.remax.visualnovel.R import com.remax.visualnovel.R
import com.remax.visualnovel.databinding.LayoutItemSettingSoundBinding import com.remax.visualnovel.databinding.LayoutItemSettingSoundBinding
import com.remax.visualnovel.databinding.LayoutSettingSoundSubViewBinding import com.remax.visualnovel.databinding.LayoutSettingSoundSubViewBinding
import com.remax.visualnovel.entity.response.ChatSound import com.remax.visualnovel.entity.response.ChatSound
import com.remax.visualnovel.extension.glide.load
import com.remax.visualnovel.widget.uitoken.changeBackground import com.remax.visualnovel.widget.uitoken.changeBackground
import com.remax.visualnovel.widget.uitoken.view.UITokenLinearLayout import com.remax.visualnovel.widget.uitoken.view.UITokenLinearLayout
@ -22,11 +25,12 @@ class ExpandSoundSubView @JvmOverloads constructor(
attrs: AttributeSet? = null, attrs: AttributeSet? = null,
defStyleAttr: Int = 0 defStyleAttr: Int = 0
) : LinearLayout(context, attrs, defStyleAttr) { ) : LinearLayout(context, attrs, defStyleAttr) {
private lateinit var items: List<ChatSound>
private var mBinding: LayoutSettingSoundSubViewBinding private var mBinding: LayoutSettingSoundSubViewBinding
init { init {
mBinding = LayoutSettingSoundSubViewBinding.inflate(LayoutInflater.from(context)) mBinding = LayoutSettingSoundSubViewBinding.inflate(LayoutInflater.from(context), this, true)
with(mBinding) { with(mBinding) {
initRadioGroup(radioGroup) initRadioGroup(radioGroup)
initRv(itemsRv) initRv(itemsRv)
@ -46,7 +50,7 @@ class ExpandSoundSubView @JvmOverloads constructor(
} }
private fun initRv(itemsRv: RecyclerView) { private fun initRv(itemsRv: RecyclerView) {
itemsRv.grid(2) itemsRv.linear(VERTICAL)
.divider { .divider {
setDivider(16, true) setDivider(16, true)
orientation = DividerOrientation.VERTICAL orientation = DividerOrientation.VERTICAL
@ -73,7 +77,7 @@ class ExpandSoundSubView @JvmOverloads constructor(
val item = getModel<ChatSound>() val item = getModel<ChatSound>()
with(getBinding<LayoutItemSettingSoundBinding>()) { with(getBinding<LayoutItemSettingSoundBinding>()) {
if (!item.imgUrl.isNullOrEmpty()) { if (!item.imgUrl.isNullOrEmpty()) {
userAvatar.setImageResource(R.mipmap.sex_man_big) userAvatar.load(item.imgUrl)
} else { } else {
userAvatar.setImageResource(if (item.isMale) R.mipmap.ic_gender_male else R.mipmap.ic_gender_female) userAvatar.setImageResource(if (item.isMale) R.mipmap.ic_gender_male else R.mipmap.ic_gender_female)
} }
@ -87,5 +91,10 @@ class ExpandSoundSubView @JvmOverloads constructor(
} }
} }
fun setItems(newItems: List<ChatSound>) {
items = newItems
mBinding.itemsRv.models = items
}
} }

View File

@ -18,7 +18,8 @@
android:id="@+id/icon" android:id="@+id/icon"
android:layout_width="24dp" android:layout_width="24dp"
android:layout_height="24dp" android:layout_height="24dp"
android:layout_centerVertical="true" /> android:layout_centerVertical="true"
android:src="@mipmap/setting_sound_play"/>
<com.remax.visualnovel.widget.uitoken.view.UITokenTextView <com.remax.visualnovel.widget.uitoken.view.UITokenTextView
android:id="@+id/titleText" android:id="@+id/titleText"
@ -29,7 +30,9 @@
android:layout_marginStart="12dp" android:layout_marginStart="12dp"
android:textSize="16sp" android:textSize="16sp"
android:textColor="#333333" android:textColor="#333333"
android:textStyle="normal"/> android:textStyle="normal"
android:text="@string/title_sound_actor"
/>
<com.remax.visualnovel.widget.uitoken.view.UITokenImageView <com.remax.visualnovel.widget.uitoken.view.UITokenImageView
android:id="@+id/arrow" android:id="@+id/arrow"
@ -47,7 +50,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical" android:orientation="vertical"
android:layout_marginTop="@dimen/dp_2" android:layout_marginTop="@dimen/dp_2"
android:visibility="visible"> android:visibility="gone">
<com.remax.visualnovel.ui.chat.ui.expandableSelector.ExpandSoundSubView <com.remax.visualnovel.ui.chat.ui.expandableSelector.ExpandSoundSubView
android:id="@+id/sound_sub_view" android:id="@+id/sound_sub_view"
android:layout_width="match_parent" android:layout_width="match_parent"

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@ -480,5 +480,6 @@
<string name="play_dialogue_only">Play dialogue only</string> <string name="play_dialogue_only">Play dialogue only</string>
<string name="setting_max_response_num">Maximum number of response tokens</string> <string name="setting_max_response_num">Maximum number of response tokens</string>
<string name="font_size">Font Size</string> <string name="font_size">Font Size</string>
<string name="title_sound_actor">Voice actor</string>
</resources> </resources>