This commit is contained in:
renhaoting 2025-10-31 14:52:26 +08:00
parent 64e5dfd17e
commit 8dc7d2072f
8 changed files with 107 additions and 115 deletions

View File

@ -28,7 +28,11 @@ class ChatSettingView @JvmOverloads constructor(
init { init {
with(mBinding) { with(mBinding) {
maxResponseNumView.setEventListener(object: MaxNumView.IEventListener {
override fun onValueChanged(value: Int) {
// TODO -save new value
}
})
} }
initAiModelSelectorView() initAiModelSelectorView()

View File

@ -9,6 +9,7 @@ import android.view.View
import com.remax.visualnovel.R import com.remax.visualnovel.R
import com.remax.visualnovel.utils.ResUtil import com.remax.visualnovel.utils.ResUtil
import com.remax.visualnovel.utils.spannablex.utils.dp import com.remax.visualnovel.utils.spannablex.utils.dp
import androidx.core.content.withStyledAttributes
class LevelSeekBar @JvmOverloads constructor( class LevelSeekBar @JvmOverloads constructor(
@ -41,7 +42,6 @@ class LevelSeekBar @JvmOverloads constructor(
// 画笔 // 画笔
private val trackPaint = Paint(Paint.ANTI_ALIAS_FLAG) private val trackPaint = Paint(Paint.ANTI_ALIAS_FLAG)
private val thumbPaint = Paint(Paint.ANTI_ALIAS_FLAG) private val thumbPaint = Paint(Paint.ANTI_ALIAS_FLAG)
private val thumbBorderPaint = Paint(Paint.ANTI_ALIAS_FLAG)
private val nodePaint = Paint(Paint.ANTI_ALIAS_FLAG) private val nodePaint = Paint(Paint.ANTI_ALIAS_FLAG)
// 监听器 // 监听器
@ -63,42 +63,40 @@ class LevelSeekBar @JvmOverloads constructor(
init { init {
setupAttributes(attrs) setupAttributes(attrs)
setupPaints() setupPaints()
setBackgroundResource(R.color.red_ff3b30)
} }
private fun setupAttributes(attrs: AttributeSet?) { private fun setupAttributes(attrs: AttributeSet?) {
attrs?.let { attrs?.let {
val typedArray = context.obtainStyledAttributes(it, R.styleable.CustomLevelSeekBar) context.withStyledAttributes(it, R.styleable.CustomLevelSeekBar) {
totalLevels = getInt(R.styleable.CustomLevelSeekBar_totalLevels, totalLevels)
totalLevels = typedArray.getInt(R.styleable.CustomLevelSeekBar_totalLevels, totalLevels) currentLevel = getInt(R.styleable.CustomLevelSeekBar_currentLevel, currentLevel)
currentLevel = typedArray.getInt(R.styleable.CustomLevelSeekBar_currentLevel, currentLevel)
.coerceIn(0, totalLevels - 1) .coerceIn(0, totalLevels - 1)
trackColor = typedArray.getColor(R.styleable.CustomLevelSeekBar_trackColor, trackColor) trackColor = getColor(R.styleable.CustomLevelSeekBar_trackColor, trackColor)
activeTrackColor = typedArray.getColor(R.styleable.CustomLevelSeekBar_activeTrackColor, activeTrackColor) activeTrackColor =
thumbColor = typedArray.getColor(R.styleable.CustomLevelSeekBar_thumbColor, thumbColor) getColor(R.styleable.CustomLevelSeekBar_activeTrackColor, activeTrackColor)
thumbBorderColor = typedArray.getColor(R.styleable.CustomLevelSeekBar_thumbBorderColor, thumbBorderColor) thumbColor = getColor(R.styleable.CustomLevelSeekBar_thumbColor, thumbColor)
nodeColor = typedArray.getColor(R.styleable.CustomLevelSeekBar_nodeColor, nodeColor) thumbBorderColor =
activeNodeColor = typedArray.getColor(R.styleable.CustomLevelSeekBar_activeNodeColor, activeNodeColor) getColor(R.styleable.CustomLevelSeekBar_thumbBorderColor, thumbBorderColor)
nodeColor = getColor(R.styleable.CustomLevelSeekBar_nodeColor, nodeColor)
activeNodeColor =
getColor(R.styleable.CustomLevelSeekBar_activeNodeColor, activeNodeColor)
trackHeight = typedArray.getDimension(R.styleable.CustomLevelSeekBar_trackHeight, trackHeight) trackHeight = getDimension(R.styleable.CustomLevelSeekBar_trackHeight, trackHeight)
trackEndRadius = typedArray.getDimension(R.styleable.CustomLevelSeekBar_trackEndRadius, trackEndRadius) trackEndRadius =
thumbRadius = typedArray.getDimension(R.styleable.CustomLevelSeekBar_thumbRadius, thumbRadius) getDimension(R.styleable.CustomLevelSeekBar_trackEndRadius, trackEndRadius)
nodeRadius = typedArray.getDimension(R.styleable.CustomLevelSeekBar_nodeRadius, nodeRadius) thumbRadius = getDimension(R.styleable.CustomLevelSeekBar_thumbRadius, thumbRadius)
nodeRadius = getDimension(R.styleable.CustomLevelSeekBar_nodeRadius, nodeRadius)
typedArray.recycle() }
} }
} }
private fun setupPaints() { private fun setupPaints() {
trackPaint.style = Paint.Style.FILL trackPaint.style = Paint.Style.FILL
thumbBorderPaint.style = Paint.Style.STROKE
//thumbBorderPaint.strokeWidth = 1F.dp.toFloat()
thumbBorderPaint.color = thumbBorderColor
thumbPaint.style = Paint.Style.FILL thumbPaint.style = Paint.Style.FILL
thumbPaint.color = thumbColor thumbPaint.color = thumbColor
nodePaint.style = Paint.Style.FILL nodePaint.style = Paint.Style.FILL
} }
@ -110,12 +108,12 @@ class LevelSeekBar @JvmOverloads constructor(
} }
private fun drawTrack(canvas: Canvas) { private fun drawTrack(canvas: Canvas) {
val centerY = height / 2f + 3 // TODO check y location val centerY = height / 2f
val trackTop = centerY - trackHeight / 2 val trackTop = centerY - trackHeight / 2
val trackBottom = centerY + trackHeight / 2 val trackBottom = centerY + trackHeight / 2
trackPaint.color = trackColor trackPaint.color = trackColor
val trackRect = RectF(0f + thumbRadius/2 + 6, trackTop, width.toFloat() - thumbRadius/2, trackBottom - nodeWidth/2 - 6) val trackRect = RectF(0f + thumbRadius, trackTop, width.toFloat() - thumbRadius, trackBottom)
canvas.drawRoundRect(trackRect, trackEndRadius, trackEndRadius, trackPaint) canvas.drawRoundRect(trackRect, trackEndRadius, trackEndRadius, trackPaint)
} }
@ -140,7 +138,6 @@ class LevelSeekBar @JvmOverloads constructor(
val centerY = height / 2f val centerY = height / 2f
val thumbX = calculatePositionForLevel(currentLevel) val thumbX = calculatePositionForLevel(currentLevel)
canvas.drawCircle(thumbX, centerY, thumbRadius, thumbBorderPaint)
canvas.drawCircle(thumbX, centerY, thumbRadius - 1F.dp.toFloat(), thumbPaint) canvas.drawCircle(thumbX, centerY, thumbRadius - 1F.dp.toFloat(), thumbPaint)
} }

View File

@ -12,13 +12,17 @@ class MaxNumView @JvmOverloads constructor(
defStyleAttr: Int = 0 defStyleAttr: Int = 0
) : LinearLayout(context, attrs, defStyleAttr) { ) : LinearLayout(context, attrs, defStyleAttr) {
companion object { private val mFixedValueList = intArrayOf(200, 400, 600, 1200, 2400)
private var GAP = 100 private var mCurIndex: Int = mFixedValueList.size / 2
} private var mCurValue = mFixedValueList[mCurIndex]
private var mBinding: LayoutMaxNumViewBinding private var mBinding: LayoutMaxNumViewBinding
private var mEventListener: IEventListener? = null
private var mCurNum = 2500
interface IEventListener {
fun onValueChanged(value: Int)
}
init { init {
mBinding = LayoutMaxNumViewBinding.inflate(LayoutInflater.from(context), this, true) mBinding = LayoutMaxNumViewBinding.inflate(LayoutInflater.from(context), this, true)
@ -26,63 +30,31 @@ class MaxNumView @JvmOverloads constructor(
} }
fun setEventListener(listener: IEventListener) {
mEventListener = listener
}
private fun setupClickListeners() { private fun setupClickListeners() {
with (mBinding) { with (mBinding) {
ivLeftIcon.setOnClickListener { ivLeftIcon.setOnClickListener {
mCurNum -= GAP mCurIndex = mCurIndex.takeUnless { it > 0 }?.minus(1) ?: mCurIndex
tvCenter.text = mCurNum.toString() mCurValue = mFixedValueList[mCurIndex]
tvCenter.text = mCurValue.toString()
mEventListener?.onValueChanged(mCurValue)
} }
ivRightIcon.setOnClickListener { ivRightIcon.setOnClickListener {
mCurNum += GAP mCurIndex = mCurIndex.takeUnless { it < mFixedValueList.size }?.plus(1) ?: mCurIndex
tvCenter.text = mCurNum.toString() mCurValue = mFixedValueList[mCurIndex]
} tvCenter.text = mCurValue.toString()
mEventListener?.onValueChanged(mCurValue)
}
}
/*override fun onTouchEvent(event: MotionEvent): Boolean {
when (event.action) {
MotionEvent.ACTION_DOWN -> {
val x = event.x
val y = event.y
if (mBinding..contains(x, y)) {
isLeftPressed = true
startLongPress(false) // 减小
return true
} else if (rightArrowRect.contains(x, y)) {
isRightPressed = true
startLongPress(true) // 增大
return true
}
}
MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
stopLongPress()
}
MotionEvent.ACTION_MOVE -> {
val x = event.x
val y = event.y
// 如果手指移出按钮区域,停止长按
if (!leftArrowRect.contains(x, y) && isLeftPressed) {
stopLongPress()
}
if (!rightArrowRect.contains(x, y) && isRightPressed) {
stopLongPress()
} }
} }
} }
invalidate()
return super.onTouchEvent(event)
}*/
} }

View File

@ -45,6 +45,10 @@ class ExpandSoundSelectView @JvmOverloads constructor(
override fun onSoundSelected(sound: ChatSound) { override fun onSoundSelected(sound: ChatSound) {
setTitleText(sound.name) setTitleText(sound.name)
} }
override fun onFilterChanged(filterType: Int) {
//
}
}) })
} }

View File

@ -18,7 +18,10 @@ import com.remax.visualnovel.entity.response.ChatSound
import com.remax.visualnovel.extension.glide.load import com.remax.visualnovel.extension.glide.load
import com.remax.visualnovel.utils.ResUtil import com.remax.visualnovel.utils.ResUtil
import com.remax.visualnovel.widget.uitoken.setBgColorDirectly import com.remax.visualnovel.widget.uitoken.setBgColorDirectly
import com.remax.visualnovel.widget.uitoken.view.UITokenLinearLayout
private const val FILTER_ALL:Int = 0
private const val FILTER_MALE:Int = 1
private const val FILTER_FEMALE:Int = 2
class ExpandSoundSubView @JvmOverloads constructor( class ExpandSoundSubView @JvmOverloads constructor(
context: Context, context: Context,
@ -33,19 +36,37 @@ class ExpandSoundSubView @JvmOverloads constructor(
interface IEventListener { interface IEventListener {
fun onSoundSelected(sound: ChatSound) fun onSoundSelected(sound: ChatSound)
fun onFilterChanged(filterType: Int)
} }
init { init {
mBinding = LayoutSettingSoundSubViewBinding.inflate(LayoutInflater.from(context), this, true) mBinding = LayoutSettingSoundSubViewBinding.inflate(LayoutInflater.from(context), this, true)
with(mBinding) { with(mBinding) {
initRadioGroup(radioGroup) initRadioGroup()
initRv(itemsRv) initRv(itemsRv)
} }
} }
private fun initRadioGroup(radioGroup: UITokenLinearLayout) { private fun initRadioGroup() {
// TODO("Not yet implemented") with (mBinding) {
radioAll.isChecked = true
radioGroup.setOnCheckedChangeListener { _, checkedId ->
when (checkedId) {
R.id.radio_all -> {
mEventListener.onFilterChanged(FILTER_ALL)
}
R.id.radio_male -> {
mEventListener.onFilterChanged(FILTER_MALE)
}
R.id.radio_female -> {
mEventListener.onFilterChanged(FILTER_FEMALE)
}
}
}
}
} }
fun playActorSound(bubble : ChatSound) { fun playActorSound(bubble : ChatSound) {
@ -91,7 +112,7 @@ class ExpandSoundSubView @JvmOverloads constructor(
} }
tvSoundName.text = item.name tvSoundName.text = item.name
itemRoot.setBgColorDirectly(bgColor = if (item.isMale) R.color.male_bg else R.color.female_bg, radius = ResUtil.getPixelSize(R.dimen.dp_10).toFloat()) itemRoot.setBgColorDirectly(bgColor = ResUtil.getColor(if (item.isMale) R.color.male_bg else R.color.female_bg), radius = ResUtil.getPixelSize(R.dimen.dp_10).toFloat())
tvSoundDescrible.setTextColor(ResUtil.getColor(if (item.isMale) R.color.male_text_color else R.color.female_text_color)) tvSoundDescrible.setTextColor(ResUtil.getColor(if (item.isMale) R.color.male_text_color else R.color.female_text_color))
tvSoundDescrible.text = item.description tvSoundDescrible.text = item.description
ivSelect.setImageResource(if (item.select) R.drawable.sound_item_selected else R.drawable.sound_item_unselected) ivSelect.setImageResource(if (item.select) R.drawable.sound_item_selected else R.drawable.sound_item_unselected)

View File

@ -2,7 +2,7 @@
<layer-list xmlns:android="http://schemas.android.com/apk/res/android"> <layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item> <item>
<shape android:shape="oval"> <shape android:shape="oval">
<solid android:color="@color/black" /> <solid android:color="@color/glo_color_green_90" />
<size android:width="@dimen/dp_13" android:height="@dimen/dp_13" /> <size android:width="@dimen/dp_13" android:height="@dimen/dp_13" />
</shape> </shape>
</item> </item>
@ -10,7 +10,7 @@
<item> <item>
<shape android:shape="oval"> <shape android:shape="oval">
<size android:width="@dimen/dp_13" android:height="@dimen/dp_13" /> <size android:width="@dimen/dp_13" android:height="@dimen/dp_13" />
<stroke android:color="@color/glo_color_green_90" android:width="@dimen/dp_2" /> <stroke android:color="@color/black" android:width="@dimen/dp_2" />
</shape> </shape>
</item> </item>
</layer-list> </layer-list>

View File

@ -11,33 +11,45 @@
android:paddingHorizontal="@dimen/dp_17" android:paddingHorizontal="@dimen/dp_17"
> >
<com.remax.visualnovel.widget.uitoken.view.UITokenImageView <FrameLayout
android:id="@+id/iv_left_icon" android:id="@+id/iv_left_icon"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_toLeftOf="@id/tv_center"
>
<com.remax.visualnovel.widget.uitoken.view.UITokenImageView
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_centerVertical="true" android:layout_centerVertical="true"
android:src="@mipmap/num_setting_left"/> android:src="@mipmap/num_setting_left"/>
</FrameLayout>
<com.remax.visualnovel.widget.uitoken.view.UITokenTextView <com.remax.visualnovel.widget.uitoken.view.UITokenTextView
android:id="@+id/tv_center" android:id="@+id/tv_center"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_toEndOf="@id/iv_left_icon" android:layout_centerInParent="true"
android:layout_toStartOf="@+id/iv_right_icon"
android:layout_centerVertical="true" android:layout_centerVertical="true"
android:textSize="@dimen/sp_14" android:textSize="@dimen/sp_14"
android:textColor="@color/gray6" android:textColor="@color/gray6"
android:gravity="center" android:gravity="center"
android:textStyle="bold" android:textStyle="bold"
android:text="2500" android:text="600"
/> />
<com.remax.visualnovel.widget.uitoken.view.UITokenImageView <FrameLayout
android:id="@+id/iv_right_icon" android:id="@+id/iv_right_icon"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_toRightOf="@id/tv_center"
>
<com.remax.visualnovel.widget.uitoken.view.UITokenImageView
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_alignParentEnd="true" android:layout_gravity="center|right"
android:layout_centerVertical="true"
android:src="@mipmap/num_setting_right"/> android:src="@mipmap/num_setting_right"/>
</FrameLayout>
</com.remax.visualnovel.widget.uitoken.view.UITokenRelativeLayout> </com.remax.visualnovel.widget.uitoken.view.UITokenRelativeLayout>

View File

@ -7,7 +7,6 @@
android:orientation="vertical"> android:orientation="vertical">
<com.remax.visualnovel.widget.uitoken.view.UITokenLinearLayout <com.remax.visualnovel.widget.uitoken.view.UITokenLinearLayout
android:id="@+id/radio_group"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:gravity="center_vertical" android:gravity="center_vertical"
@ -17,42 +16,24 @@
android:padding="@dimen/dp_12" android:padding="@dimen/dp_12"
> >
<!--<com.remax.visualnovel.widget.ui.RadioCheckButton
android:id="@+id/radio_all"
android:layout_width="16dp"
android:layout_height="16dp"
app:radioCheck="true" />
<com.remax.visualnovel.widget.ui.RadioCheckButton
android:id="@+id/radio_male"
android:layout_width="16dp"
android:layout_height="16dp"
android:layout_marginLeft="@dimen/dp_20"
app:radioCheck="true" />
<com.remax.visualnovel.widget.ui.RadioCheckButton
android:id="@+id/radio_female"
android:layout_width="16dp"
android:layout_height="16dp"
android:layout_marginLeft="@dimen/dp_20"
app:radioCheck="true" />-->
<RadioGroup <RadioGroup
android:id="@+id/radio_group"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="horizontal"> android:orientation="horizontal">
<RadioButton <RadioButton
android:id="@+id/radio_all"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/all" android:text="@string/all"
android:button="@drawable/radio_button_selector" android:button="@drawable/radio_button_selector"
android:paddingHorizontal="@dimen/dp_5" android:paddingHorizontal="@dimen/dp_5"
android:textColor="@color/white" android:textColor="@color/white"
android:checked="true"
/> />
<RadioButton <RadioButton
android:id="@+id/radio_male"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/male" android:text="@string/male"
@ -64,6 +45,7 @@
android:textColor="@color/white" /> android:textColor="@color/white" />
<RadioButton <RadioButton
android:id="@+id/radio_female"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/female" android:text="@string/female"