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 {
with(mBinding) {
maxResponseNumView.setEventListener(object: MaxNumView.IEventListener {
override fun onValueChanged(value: Int) {
// TODO -save new value
}
})
}
initAiModelSelectorView()

View File

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

View File

@ -12,13 +12,17 @@ class MaxNumView @JvmOverloads constructor(
defStyleAttr: Int = 0
) : LinearLayout(context, attrs, defStyleAttr) {
companion object {
private var GAP = 100
}
private val mFixedValueList = intArrayOf(200, 400, 600, 1200, 2400)
private var mCurIndex: Int = mFixedValueList.size / 2
private var mCurValue = mFixedValueList[mCurIndex]
private var mBinding: LayoutMaxNumViewBinding
private var mEventListener: IEventListener? = null
private var mCurNum = 2500
interface IEventListener {
fun onValueChanged(value: Int)
}
init {
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() {
with (mBinding) {
ivLeftIcon.setOnClickListener {
mCurNum -= GAP
tvCenter.text = mCurNum.toString()
mCurIndex = mCurIndex.takeUnless { it > 0 }?.minus(1) ?: mCurIndex
mCurValue = mFixedValueList[mCurIndex]
tvCenter.text = mCurValue.toString()
mEventListener?.onValueChanged(mCurValue)
}
ivRightIcon.setOnClickListener {
mCurNum += GAP
tvCenter.text = mCurNum.toString()
mCurIndex = mCurIndex.takeUnless { it < mFixedValueList.size }?.plus(1) ?: mCurIndex
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) {
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.utils.ResUtil
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(
context: Context,
@ -33,19 +36,37 @@ class ExpandSoundSubView @JvmOverloads constructor(
interface IEventListener {
fun onSoundSelected(sound: ChatSound)
fun onFilterChanged(filterType: Int)
}
init {
mBinding = LayoutSettingSoundSubViewBinding.inflate(LayoutInflater.from(context), this, true)
with(mBinding) {
initRadioGroup(radioGroup)
initRadioGroup()
initRv(itemsRv)
}
}
private fun initRadioGroup(radioGroup: UITokenLinearLayout) {
// TODO("Not yet implemented")
private fun initRadioGroup() {
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) {
@ -91,7 +112,7 @@ class ExpandSoundSubView @JvmOverloads constructor(
}
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.text = item.description
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">
<item>
<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" />
</shape>
</item>
@ -10,7 +10,7 @@
<item>
<shape android:shape="oval">
<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>
</item>
</layer-list>

View File

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

View File

@ -7,7 +7,6 @@
android:orientation="vertical">
<com.remax.visualnovel.widget.uitoken.view.UITokenLinearLayout
android:id="@+id/radio_group"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
@ -17,42 +16,24 @@
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
android:id="@+id/radio_group"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<RadioButton
android:id="@+id/radio_all"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/all"
android:button="@drawable/radio_button_selector"
android:paddingHorizontal="@dimen/dp_5"
android:textColor="@color/white"
android:checked="true"
/>
<RadioButton
android:id="@+id/radio_male"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/male"
@ -64,6 +45,7 @@
android:textColor="@color/white" />
<RadioButton
android:id="@+id/radio_female"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/female"