feat: 基础功能
This commit is contained in:
parent
699bc11c25
commit
c9a2b78a74
|
|
@ -1,9 +1,9 @@
|
||||||
package com.yuanxuan.rokid
|
package com.yuanxuan.rokid
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.KeyEvent
|
|
||||||
import androidx.activity.addCallback
|
import androidx.activity.addCallback
|
||||||
import androidx.activity.enableEdgeToEdge
|
import androidx.activity.enableEdgeToEdge
|
||||||
|
import androidx.activity.viewModels
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.core.view.ViewCompat
|
import androidx.core.view.ViewCompat
|
||||||
import androidx.core.view.WindowInsetsCompat
|
import androidx.core.view.WindowInsetsCompat
|
||||||
|
|
@ -38,38 +38,44 @@ class MainActivity : AppCompatActivity() {
|
||||||
* 拦截返回键事件,防止返回到桌面
|
* 拦截返回键事件,防止返回到桌面
|
||||||
*/
|
*/
|
||||||
onBackPressedDispatcher.addCallback {
|
onBackPressedDispatcher.addCallback {
|
||||||
if (AppDependencies.deviceServiceManager.instructState.value
|
|
||||||
== DeviceServiceManager.InstructState.WaitingInstructState
|
|
||||||
) {
|
|
||||||
AppDependencies.deviceServiceManager.quitInstructReceived()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// /**
|
||||||
* 触摸板事件
|
// * 触摸板事件
|
||||||
* [KeyEvent.KEYCODE_DPAD_DOWN] 和 [KeyEvent.KEYCODE_DPAD_RIGHT] 同时响应
|
// * [KeyEvent.KEYCODE_DPAD_DOWN] 和 [KeyEvent.KEYCODE_DPAD_RIGHT] 同时响应
|
||||||
* 所以直接消费掉一个
|
// * 所以直接消费掉一个
|
||||||
*/
|
// */
|
||||||
override fun dispatchKeyEvent(event: KeyEvent): Boolean {
|
// override fun dispatchKeyEvent(event: KeyEvent): Boolean {
|
||||||
return if (event.action == KeyEvent.ACTION_DOWN) {
|
// return if (event.action == KeyEvent.ACTION_DOWN) {
|
||||||
when (event.keyCode) {
|
// when (event.keyCode) {
|
||||||
KeyEvent.KEYCODE_DPAD_DOWN -> {
|
// KeyEvent.KEYCODE_DPAD_DOWN -> {
|
||||||
true
|
// true
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
KeyEvent.KEYCODE_DPAD_UP -> {
|
// KeyEvent.KEYCODE_DPAD_UP -> {
|
||||||
true
|
// true
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
else -> super.dispatchKeyEvent(event)
|
// KeyEvent.KEYCODE_DPAD_LEFT -> {
|
||||||
}
|
// viewModel.onKeyEventDispatched(MainViewModel.KeyEvent.DpadLeft)
|
||||||
} else {
|
// true
|
||||||
super.dispatchKeyEvent(event)
|
// }
|
||||||
}
|
//
|
||||||
}
|
// KeyEvent.KEYCODE_DPAD_RIGHT -> {
|
||||||
|
// viewModel.onKeyEventDispatched(MainViewModel.KeyEvent.DpadRight)
|
||||||
|
// true
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// else -> super.dispatchKeyEvent(event)
|
||||||
|
// }
|
||||||
|
// } else {
|
||||||
|
// super.dispatchKeyEvent(event)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
private fun observer() {
|
private fun observer() {
|
||||||
lifecycleScope.launch {
|
lifecycleScope.launch {
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,8 @@ class DeviceServiceManager(val context: Application) : ConnectivityManager.Netwo
|
||||||
* 语音指令等待超时
|
* 语音指令等待超时
|
||||||
*/
|
*/
|
||||||
private const val INSTRUCT_WAITE_TIME = 15000L
|
private const val INSTRUCT_WAITE_TIME = 15000L
|
||||||
|
const val MAX_VOLUME = 15
|
||||||
|
const val MAX_BRIGHTNESS = 15
|
||||||
}
|
}
|
||||||
|
|
||||||
private var instructService: IInstructService? = null
|
private var instructService: IInstructService? = null
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,70 @@
|
||||||
|
package com.yuanxuan.rokid.ui
|
||||||
|
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.view.KeyEvent
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import androidx.fragment.app.Fragment
|
||||||
|
import androidx.fragment.app.viewModels
|
||||||
|
import androidx.lifecycle.lifecycleScope
|
||||||
|
import com.yuanxuan.rokid.R
|
||||||
|
import com.yuanxuan.rokid.databinding.FragmentSettingBinding
|
||||||
|
import com.yuanxuan.rokid.dependencies.AppDependencies
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
|
class BrightnessFragment : Fragment() {
|
||||||
|
|
||||||
|
private lateinit var binding: FragmentSettingBinding
|
||||||
|
private val viewModel by viewModels<SettingViewModel>()
|
||||||
|
|
||||||
|
private val adapter by lazy {
|
||||||
|
SeekBarAdapter()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreateView(
|
||||||
|
inflater: LayoutInflater,
|
||||||
|
container: ViewGroup?,
|
||||||
|
savedInstanceState: Bundle?
|
||||||
|
): View {
|
||||||
|
binding = FragmentSettingBinding.inflate(inflater, container, false)
|
||||||
|
return binding.root
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
binding.title.text = resources.getString(R.string.setting_brightness_title)
|
||||||
|
binding.tip.text = resources.getString(R.string.setting_brightness_tip)
|
||||||
|
|
||||||
|
binding.recyclerView.adapter = adapter
|
||||||
|
|
||||||
|
viewLifecycleOwner.lifecycleScope.launch {
|
||||||
|
viewModel.brightnessFlow.collect { data ->
|
||||||
|
adapter.submitList(data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
binding.root.requestFocus()
|
||||||
|
binding.root.setOnKeyListener { _, _, event ->
|
||||||
|
return@setOnKeyListener if (event.action == KeyEvent.ACTION_UP) {
|
||||||
|
when (event.keyCode) {
|
||||||
|
KeyEvent.KEYCODE_DPAD_RIGHT -> {
|
||||||
|
AppDependencies.deviceServiceManager.brightnessAdd()
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
KeyEvent.KEYCODE_DPAD_LEFT -> {
|
||||||
|
AppDependencies.deviceServiceManager.brightnessSubtract()
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
else -> {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -11,7 +11,6 @@ import androidx.navigation.fragment.findNavController
|
||||||
import com.yuanxuan.rokid.R
|
import com.yuanxuan.rokid.R
|
||||||
import com.yuanxuan.rokid.databinding.FragmentHomeBinding
|
import com.yuanxuan.rokid.databinding.FragmentHomeBinding
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import timber.log.Timber
|
|
||||||
|
|
||||||
class HomeFragment : Fragment() {
|
class HomeFragment : Fragment() {
|
||||||
|
|
||||||
|
|
@ -21,10 +20,9 @@ class HomeFragment : Fragment() {
|
||||||
private val adapter by lazy {
|
private val adapter by lazy {
|
||||||
HomeMenuAdapter { item ->
|
HomeMenuAdapter { item ->
|
||||||
when (item.type) {
|
when (item.type) {
|
||||||
is HomeMenuAdapter.HomeMenuBean.Type.Brightness -> {}
|
is HomeMenuAdapter.HomeMenuBean.Type.Brightness -> findNavController().navigate(R.id.home_to_brightness)
|
||||||
is HomeMenuAdapter.HomeMenuBean.Type.Sn ->
|
is HomeMenuAdapter.HomeMenuBean.Type.Sn -> findNavController().navigate(R.id.home_to_sn)
|
||||||
findNavController().navigate(R.id.home_to_sn)
|
is HomeMenuAdapter.HomeMenuBean.Type.Volume -> findNavController().navigate(R.id.home_to_volume)
|
||||||
is HomeMenuAdapter.HomeMenuBean.Type.Volume -> {}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -47,7 +45,6 @@ class HomeFragment : Fragment() {
|
||||||
|
|
||||||
lifecycleScope.launch {
|
lifecycleScope.launch {
|
||||||
viewModel.homeMenuBeans.collect {
|
viewModel.homeMenuBeans.collect {
|
||||||
Timber.d(it.toString())
|
|
||||||
adapter.submitList(it)
|
adapter.submitList(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ package com.yuanxuan.rokid.ui
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.annotation.DrawableRes
|
import androidx.annotation.DrawableRes
|
||||||
|
import androidx.annotation.StringRes
|
||||||
import androidx.recyclerview.widget.DiffUtil
|
import androidx.recyclerview.widget.DiffUtil
|
||||||
import androidx.recyclerview.widget.ListAdapter
|
import androidx.recyclerview.widget.ListAdapter
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
|
@ -49,10 +50,11 @@ class HomeMenuAdapter(val itemClick: (HomeMenuBean) -> Unit) :
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun bindTitle(holder: ViewHolder, item: HomeMenuBean) {
|
private fun bindTitle(holder: ViewHolder, item: HomeMenuBean) {
|
||||||
|
val title = holder.binding.root.context.getString(item.title)
|
||||||
val displayTitle = when (val type = item.type) {
|
val displayTitle = when (val type = item.type) {
|
||||||
is HomeMenuBean.Type.Sn -> item.title
|
is HomeMenuBean.Type.Sn -> title
|
||||||
is HomeMenuBean.Type.Brightness,
|
is HomeMenuBean.Type.Brightness,
|
||||||
is HomeMenuBean.Type.Volume -> "${item.title}: ${type.value}"
|
is HomeMenuBean.Type.Volume -> "${title}: ${type.value}"
|
||||||
}
|
}
|
||||||
holder.binding.title.text = displayTitle
|
holder.binding.title.text = displayTitle
|
||||||
}
|
}
|
||||||
|
|
@ -68,7 +70,7 @@ class HomeMenuAdapter(val itemClick: (HomeMenuBean) -> Unit) :
|
||||||
}
|
}
|
||||||
|
|
||||||
data class HomeMenuBean(
|
data class HomeMenuBean(
|
||||||
val title: String,
|
@param:StringRes val title: Int,
|
||||||
@param:DrawableRes val icon: Int,
|
@param:DrawableRes val icon: Int,
|
||||||
val type: Type,
|
val type: Type,
|
||||||
) {
|
) {
|
||||||
|
|
@ -83,6 +85,9 @@ class HomeMenuAdapter(val itemClick: (HomeMenuBean) -> Unit) :
|
||||||
|
|
||||||
class DiffCallback : DiffUtil.ItemCallback<HomeMenuBean>() {
|
class DiffCallback : DiffUtil.ItemCallback<HomeMenuBean>() {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 其实没有必要 因为只有一个变化 直接返回一个payload就行了 不需要计算
|
||||||
|
*/
|
||||||
companion object {
|
companion object {
|
||||||
const val FLAG_TYPE_VALUE_CHANGED = 1
|
const val FLAG_TYPE_VALUE_CHANGED = 1
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,69 +4,36 @@ import androidx.lifecycle.ViewModel
|
||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
import com.yuanxuan.rokid.R
|
import com.yuanxuan.rokid.R
|
||||||
import com.yuanxuan.rokid.dependencies.AppDependencies
|
import com.yuanxuan.rokid.dependencies.AppDependencies
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.SharingStarted
|
||||||
import kotlinx.coroutines.flow.asStateFlow
|
import kotlinx.coroutines.flow.combine
|
||||||
import kotlinx.coroutines.flow.update
|
import kotlinx.coroutines.flow.shareIn
|
||||||
import kotlinx.coroutines.launch
|
|
||||||
|
|
||||||
class HomeViewModel : ViewModel() {
|
class HomeViewModel : ViewModel() {
|
||||||
|
val homeMenuBeans =
|
||||||
private val _homeMenuBeans = MutableStateFlow(
|
combine(
|
||||||
listOf(
|
AppDependencies.deviceServiceManager.brightness,
|
||||||
HomeMenuAdapter.HomeMenuBean(
|
AppDependencies.deviceServiceManager.volume,
|
||||||
title = "音量",
|
) { brightness, volume ->
|
||||||
icon = R.drawable.icon_battery_100,
|
listOf(
|
||||||
type = HomeMenuAdapter.HomeMenuBean.Type.Volume("0"),
|
HomeMenuAdapter.HomeMenuBean(
|
||||||
),
|
title = R.string.home_item_volume,
|
||||||
HomeMenuAdapter.HomeMenuBean(
|
icon = R.drawable.icon_battery_100,
|
||||||
title = "亮度",
|
type = HomeMenuAdapter.HomeMenuBean.Type.Volume("$volume"),
|
||||||
icon = R.drawable.icon_battery_100,
|
),
|
||||||
type = HomeMenuAdapter.HomeMenuBean.Type.Brightness("0"),
|
HomeMenuAdapter.HomeMenuBean(
|
||||||
),
|
title = R.string.home_item_brightness,
|
||||||
HomeMenuAdapter.HomeMenuBean(
|
icon = R.drawable.icon_battery_100,
|
||||||
title = "SN",
|
type = HomeMenuAdapter.HomeMenuBean.Type.Brightness("$brightness"),
|
||||||
icon = R.drawable.icon_battery_100,
|
),
|
||||||
type = HomeMenuAdapter.HomeMenuBean.Type.Sn("0"),
|
HomeMenuAdapter.HomeMenuBean(
|
||||||
),
|
title = R.string.home_item_sn,
|
||||||
|
icon = R.drawable.icon_battery_100,
|
||||||
|
type = HomeMenuAdapter.HomeMenuBean.Type.Sn("0"), // 这里用不上 随便填一个
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}.shareIn(
|
||||||
|
scope = viewModelScope,
|
||||||
|
started = SharingStarted.Eagerly,
|
||||||
|
replay = 1
|
||||||
)
|
)
|
||||||
)
|
|
||||||
val homeMenuBeans = _homeMenuBeans.asStateFlow()
|
|
||||||
|
|
||||||
init {
|
|
||||||
viewModelScope.launch {
|
|
||||||
AppDependencies.deviceServiceManager.brightness.collect { brightness ->
|
|
||||||
_homeMenuBeans.update { oldBeans ->
|
|
||||||
oldBeans.map { data ->
|
|
||||||
when (data.type) {
|
|
||||||
is HomeMenuAdapter.HomeMenuBean.Type.Brightness -> data.copy(
|
|
||||||
type = data.type.copy(
|
|
||||||
value = "$brightness"
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
else -> data
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
viewModelScope.launch {
|
|
||||||
AppDependencies.deviceServiceManager.volume.collect { volume ->
|
|
||||||
_homeMenuBeans.update { oldBeans ->
|
|
||||||
oldBeans.map { data ->
|
|
||||||
when (data.type) {
|
|
||||||
is HomeMenuAdapter.HomeMenuBean.Type.Volume -> data.copy(
|
|
||||||
type = data.type.copy(
|
|
||||||
value = "$volume"
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
else -> data
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,67 @@
|
||||||
|
package com.yuanxuan.rokid.ui
|
||||||
|
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import androidx.recyclerview.widget.DiffUtil
|
||||||
|
import androidx.recyclerview.widget.ListAdapter
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import com.yuanxuan.rokid.databinding.ItemSeekBarBinding
|
||||||
|
|
||||||
|
class SeekBarAdapter :
|
||||||
|
ListAdapter<SeekBarAdapter.SeekBarBean, SeekBarAdapter.ViewHolder>(DiffCallback()) {
|
||||||
|
override fun onCreateViewHolder(
|
||||||
|
parent: ViewGroup,
|
||||||
|
viewType: Int
|
||||||
|
): ViewHolder {
|
||||||
|
val binding = ItemSeekBarBinding.inflate(LayoutInflater.from(parent.context), parent, false)
|
||||||
|
return ViewHolder(binding)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onBindViewHolder(
|
||||||
|
holder: ViewHolder,
|
||||||
|
position: Int
|
||||||
|
) {
|
||||||
|
bindSeekBar(item = getItem(position), holder = holder)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onBindViewHolder(holder: ViewHolder, position: Int, payloads: List<Any?>) {
|
||||||
|
if (payloads.isEmpty()) {
|
||||||
|
super.onBindViewHolder(holder, position, payloads)
|
||||||
|
} else {
|
||||||
|
bindSeekBar(item = getItem(position), holder = holder)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun bindSeekBar(item: SeekBarBean, holder: ViewHolder) {
|
||||||
|
holder.binding.root.isEnabled = item.checked
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class ViewHolder(val binding: ItemSeekBarBinding) : RecyclerView.ViewHolder(binding.root)
|
||||||
|
|
||||||
|
|
||||||
|
data class SeekBarBean(
|
||||||
|
val value: Int,
|
||||||
|
val checked: Boolean,
|
||||||
|
)
|
||||||
|
|
||||||
|
class DiffCallback : DiffUtil.ItemCallback<SeekBarBean>() {
|
||||||
|
override fun areItemsTheSame(
|
||||||
|
oldItem: SeekBarBean,
|
||||||
|
newItem: SeekBarBean
|
||||||
|
): Boolean {
|
||||||
|
return oldItem.value == newItem.value
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun areContentsTheSame(
|
||||||
|
oldItem: SeekBarBean,
|
||||||
|
newItem: SeekBarBean
|
||||||
|
): Boolean {
|
||||||
|
return oldItem == newItem
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getChangePayload(oldItem: SeekBarBean, newItem: SeekBarBean): Any {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
package com.yuanxuan.rokid.ui
|
|
||||||
|
|
||||||
import androidx.fragment.app.Fragment
|
|
||||||
|
|
||||||
class SettingFragment: Fragment() {
|
|
||||||
}
|
|
||||||
|
|
@ -0,0 +1,50 @@
|
||||||
|
package com.yuanxuan.rokid.ui
|
||||||
|
|
||||||
|
import androidx.lifecycle.ViewModel
|
||||||
|
import androidx.lifecycle.viewModelScope
|
||||||
|
import com.yuanxuan.rokid.dependencies.AppDependencies
|
||||||
|
import com.yuanxuan.rokid.device.DeviceServiceManager
|
||||||
|
import kotlinx.coroutines.flow.SharedFlow
|
||||||
|
import kotlinx.coroutines.flow.SharingStarted
|
||||||
|
import kotlinx.coroutines.flow.map
|
||||||
|
import kotlinx.coroutines.flow.shareIn
|
||||||
|
|
||||||
|
class SettingViewModel : ViewModel() {
|
||||||
|
|
||||||
|
val volumeFlow: SharedFlow<List<SeekBarAdapter.SeekBarBean>> =
|
||||||
|
AppDependencies.deviceServiceManager.volume.map { volume ->
|
||||||
|
buildList {
|
||||||
|
(1..DeviceServiceManager.MAX_VOLUME).map { i ->
|
||||||
|
add(
|
||||||
|
SeekBarAdapter.SeekBarBean(
|
||||||
|
value = i,
|
||||||
|
checked = i <= volume
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}.shareIn(
|
||||||
|
scope = viewModelScope,
|
||||||
|
started = SharingStarted.Eagerly,
|
||||||
|
replay = 1
|
||||||
|
)
|
||||||
|
|
||||||
|
val brightnessFlow: SharedFlow<List<SeekBarAdapter.SeekBarBean>> =
|
||||||
|
AppDependencies.deviceServiceManager.brightness.map { volume ->
|
||||||
|
buildList {
|
||||||
|
(1..DeviceServiceManager.MAX_BRIGHTNESS).map { i ->
|
||||||
|
add(
|
||||||
|
SeekBarAdapter.SeekBarBean(
|
||||||
|
value = i,
|
||||||
|
checked = i <= volume
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}.shareIn(
|
||||||
|
scope = viewModelScope,
|
||||||
|
started = SharingStarted.Eagerly,
|
||||||
|
replay = 1
|
||||||
|
)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,70 @@
|
||||||
|
package com.yuanxuan.rokid.ui
|
||||||
|
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.view.KeyEvent
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import androidx.fragment.app.Fragment
|
||||||
|
import androidx.fragment.app.viewModels
|
||||||
|
import androidx.lifecycle.lifecycleScope
|
||||||
|
import com.yuanxuan.rokid.R
|
||||||
|
import com.yuanxuan.rokid.databinding.FragmentSettingBinding
|
||||||
|
import com.yuanxuan.rokid.dependencies.AppDependencies
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
|
class VolumeFragment : Fragment() {
|
||||||
|
|
||||||
|
private lateinit var binding: FragmentSettingBinding
|
||||||
|
private val viewModel by viewModels<SettingViewModel>()
|
||||||
|
|
||||||
|
private val adapter by lazy {
|
||||||
|
SeekBarAdapter()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreateView(
|
||||||
|
inflater: LayoutInflater,
|
||||||
|
container: ViewGroup?,
|
||||||
|
savedInstanceState: Bundle?
|
||||||
|
): View {
|
||||||
|
binding = FragmentSettingBinding.inflate(inflater, container, false)
|
||||||
|
return binding.root
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
binding.title.text = resources.getString(R.string.setting_volume_title)
|
||||||
|
binding.tip.text = resources.getString(R.string.setting_volume_tip)
|
||||||
|
|
||||||
|
binding.recyclerView.adapter = adapter
|
||||||
|
|
||||||
|
viewLifecycleOwner.lifecycleScope.launch {
|
||||||
|
viewModel.volumeFlow.collect { data ->
|
||||||
|
adapter.submitList(data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
binding.root.requestFocus()
|
||||||
|
binding.root.setOnKeyListener { _, _, event ->
|
||||||
|
return@setOnKeyListener if (event.action == KeyEvent.ACTION_DOWN) {
|
||||||
|
when (event.keyCode) {
|
||||||
|
KeyEvent.KEYCODE_DPAD_RIGHT -> {
|
||||||
|
AppDependencies.deviceServiceManager.volumeAdd()
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
KeyEvent.KEYCODE_DPAD_LEFT -> {
|
||||||
|
AppDependencies.deviceServiceManager.volumeSubtract()
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
else -> {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
<corners android:radius="10.dp" />
|
<corners android:radius="10dp" />
|
||||||
<stroke
|
<stroke
|
||||||
android:width="1.dp"
|
android:width="1dp"
|
||||||
android:color="@color/white" />
|
android:color="@color/white" />
|
||||||
</shape>
|
</shape>
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item android:state_enabled="false">
|
||||||
|
<shape android:shape="rectangle">
|
||||||
|
<corners android:radius="3dp" />
|
||||||
|
<solid android:color="@color/white_50" />
|
||||||
|
</shape>
|
||||||
|
</item>
|
||||||
|
<item android:state_enabled="true">
|
||||||
|
<shape android:shape="rectangle">
|
||||||
|
<corners android:radius="3dp" />
|
||||||
|
<solid android:color="@color/white" />
|
||||||
|
</shape>
|
||||||
|
</item>
|
||||||
|
</selector>
|
||||||
|
|
@ -29,7 +29,7 @@
|
||||||
android:id="@+id/wifi_iv"
|
android:id="@+id/wifi_iv"
|
||||||
android:layout_width="@dimen/status_bar_icon_size"
|
android:layout_width="@dimen/status_bar_icon_size"
|
||||||
android:layout_height="@dimen/status_bar_icon_size"
|
android:layout_height="@dimen/status_bar_icon_size"
|
||||||
android:layout_marginEnd="5.dp"
|
android:layout_marginEnd="5dp"
|
||||||
android:src="@drawable/wifi_level_list"
|
android:src="@drawable/wifi_level_list"
|
||||||
android:tint="@color/white"
|
android:tint="@color/white"
|
||||||
app:layout_constraintBottom_toBottomOf="@id/battery_level"
|
app:layout_constraintBottom_toBottomOf="@id/battery_level"
|
||||||
|
|
@ -40,7 +40,7 @@
|
||||||
android:id="@+id/battery_level_iv"
|
android:id="@+id/battery_level_iv"
|
||||||
android:layout_width="@dimen/status_bar_icon_size"
|
android:layout_width="@dimen/status_bar_icon_size"
|
||||||
android:layout_height="@dimen/status_bar_icon_size"
|
android:layout_height="@dimen/status_bar_icon_size"
|
||||||
android:layout_marginEnd="5.dp"
|
android:layout_marginEnd="5dp"
|
||||||
android:src="@drawable/battery_level_list"
|
android:src="@drawable/battery_level_list"
|
||||||
android:tint="@color/white"
|
android:tint="@color/white"
|
||||||
app:layout_constraintBottom_toBottomOf="@id/battery_level"
|
app:layout_constraintBottom_toBottomOf="@id/battery_level"
|
||||||
|
|
@ -57,8 +57,8 @@
|
||||||
|
|
||||||
<com.airbnb.lottie.LottieAnimationView
|
<com.airbnb.lottie.LottieAnimationView
|
||||||
android:id="@+id/lottie_voice_input"
|
android:id="@+id/lottie_voice_input"
|
||||||
android:layout_width="200.dp"
|
android:layout_width="200dp"
|
||||||
android:layout_height="100.dp"
|
android:layout_height="100dp"
|
||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
app:layout_constraintBottom_toTopOf="@id/bottom"
|
app:layout_constraintBottom_toTopOf="@id/bottom"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
|
@ -70,7 +70,7 @@
|
||||||
<Space
|
<Space
|
||||||
android:id="@+id/bottom"
|
android:id="@+id/bottom"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="0.dp"
|
android:layout_height="0dp"
|
||||||
app:layout_constraintBottom_toBottomOf="parent" />
|
app:layout_constraintBottom_toBottomOf="parent" />
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
@ -8,12 +8,13 @@
|
||||||
<androidx.leanback.widget.HorizontalGridView
|
<androidx.leanback.widget.HorizontalGridView
|
||||||
android:id="@+id/recycler_view"
|
android:id="@+id/recycler_view"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="85.dp"
|
android:layout_height="85dp"
|
||||||
android:clipToPadding="false"
|
android:clipToPadding="false"
|
||||||
android:paddingStart="10.dp"
|
android:paddingStart="10dp"
|
||||||
android:paddingTop="10.dp"
|
android:paddingTop="10dp"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
tools:ignore="RtlSymmetry"
|
||||||
tools:listitem="@layout/item_home" />
|
tools:listitem="@layout/item_home" />
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
@ -1,13 +1,47 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent"
|
||||||
|
android:focusable="true"
|
||||||
|
android:descendantFocusability="blocksDescendants">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
|
android:id="@+id/tip"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="setting"
|
android:layout_marginBottom="50dp"
|
||||||
|
android:textColor="@color/white"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
tools:text="@string/setting_volume_tip" />
|
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/recycler_view"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:paddingStart="5dp"
|
||||||
|
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
tools:ignore="RtlSymmetry"
|
||||||
|
tools:itemCount="15"
|
||||||
|
tools:listitem="@layout/item_seek_bar" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/title"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginBottom="70dp"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
app:layout_constraintBottom_toTopOf="@id/recycler_view"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
tools:text="@string/setting_volume_title" />
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
@ -3,32 +3,18 @@
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:focusable="true"
|
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
<Button
|
<TextView
|
||||||
android:id="@+id/sn"
|
android:id="@+id/sn"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:focusedByDefault="true"
|
|
||||||
android:nextFocusLeft="@id/sn2"
|
|
||||||
android:stateListAnimator="@animator/focus_animator"
|
|
||||||
android:textColor="@color/white"
|
android:textColor="@color/white"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
tools:text="askjdhkjashdkjhsad" />
|
tools:text="askjdhkjashdkjhsad" />
|
||||||
|
|
||||||
<Button
|
|
||||||
android:id="@+id/sn2"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:stateListAnimator="@animator/focus_animator"
|
|
||||||
android:textColor="@color/white"
|
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
|
||||||
app:layout_constraintBottom_toTopOf="@id/sn"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
tools:text="askjdhkjashdkjhsad" />
|
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
@ -3,11 +3,11 @@
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:id="@+id/parent"
|
android:id="@+id/parent"
|
||||||
android:layout_width="50.dp"
|
android:layout_width="50dp"
|
||||||
android:layout_height="75.dp"
|
android:layout_height="75dp"
|
||||||
android:layout_marginEnd="10.dp"
|
android:layout_marginEnd="10dp"
|
||||||
|
android:soundEffectsEnabled="false"
|
||||||
android:background="@drawable/bg_home_menu"
|
android:background="@drawable/bg_home_menu"
|
||||||
android:focusable="true"
|
|
||||||
android:stateListAnimator="@animator/focus_animator">
|
android:stateListAnimator="@animator/focus_animator">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
|
|
@ -15,7 +15,7 @@
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:textColor="#ffffff"
|
android:textColor="#ffffff"
|
||||||
android:textSize="10.sp"
|
android:textSize="10sp"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="15dp"
|
||||||
|
android:layout_height="10dp"
|
||||||
|
android:layout_marginEnd="5dp"
|
||||||
|
android:background="@drawable/bg_seek_bar" />
|
||||||
|
|
||||||
|
|
@ -13,12 +13,24 @@
|
||||||
<action
|
<action
|
||||||
android:id="@+id/home_to_sn"
|
android:id="@+id/home_to_sn"
|
||||||
app:destination="@id/sn_fragment" />
|
app:destination="@id/sn_fragment" />
|
||||||
|
<action
|
||||||
|
android:id="@+id/home_to_volume"
|
||||||
|
app:destination="@id/volume_fragment" />
|
||||||
|
<action
|
||||||
|
android:id="@+id/home_to_brightness"
|
||||||
|
app:destination="@id/brightness_fragment" />
|
||||||
</fragment>
|
</fragment>
|
||||||
|
|
||||||
<fragment
|
<fragment
|
||||||
android:id="@+id/setting_fragment"
|
android:id="@+id/volume_fragment"
|
||||||
android:name="com.yuanxuan.rokid.ui.SettingFragment"
|
android:name="com.yuanxuan.rokid.ui.VolumeFragment"
|
||||||
android:label="setting"
|
android:label="volume"
|
||||||
|
tools:layout="@layout/fragment_setting" />
|
||||||
|
|
||||||
|
<fragment
|
||||||
|
android:id="@+id/brightness_fragment"
|
||||||
|
android:name="com.yuanxuan.rokid.ui.BrightnessFragment"
|
||||||
|
android:label="brightness"
|
||||||
tools:layout="@layout/fragment_setting" />
|
tools:layout="@layout/fragment_setting" />
|
||||||
|
|
||||||
<fragment
|
<fragment
|
||||||
|
|
|
||||||
|
|
@ -2,4 +2,5 @@
|
||||||
<resources>
|
<resources>
|
||||||
<color name="black">#FF000000</color>
|
<color name="black">#FF000000</color>
|
||||||
<color name="white">#FFFFFFFF</color>
|
<color name="white">#FFFFFFFF</color>
|
||||||
|
<color name="white_50">#50FFFFFF</color>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources>
|
<resources>
|
||||||
<dimen name="status_bar_text_size">12.sp</dimen>
|
<dimen name="status_bar_text_size">12sp</dimen>
|
||||||
<dimen name="status_bar_icon_size">16.dp</dimen>
|
<dimen name="status_bar_icon_size">16dp</dimen>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
@ -1,4 +1,11 @@
|
||||||
<resources>
|
<resources>
|
||||||
<string name="app_name">Rokid</string>
|
<string name="app_name">Rokid</string>
|
||||||
<string name="home_menu_setting">设置</string>
|
<string name="home_menu_setting">设置</string>
|
||||||
|
<string name="setting_volume_tip">前后划动“触控板”调节音量</string>
|
||||||
|
<string name="setting_brightness_tip">前后划动“触控板”调节亮度</string>
|
||||||
|
<string name="setting_volume_title">音量调节</string>
|
||||||
|
<string name="setting_brightness_title">亮度调节</string>
|
||||||
|
<string name="home_item_volume">音量</string>
|
||||||
|
<string name="home_item_brightness">亮度</string>
|
||||||
|
<string name="home_item_sn">SN</string>
|
||||||
</resources>
|
</resources>
|
||||||
Loading…
Reference in New Issue