feat: 基础功能

This commit is contained in:
yangxisong 2025-11-19 15:58:32 +08:00
parent 699bc11c25
commit c9a2b78a74
22 changed files with 435 additions and 144 deletions

View File

@ -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 {

View File

@ -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

View File

@ -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
}
}
}
}

View File

@ -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)
} }
} }

View File

@ -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
} }

View File

@ -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(
AppDependencies.deviceServiceManager.brightness,
AppDependencies.deviceServiceManager.volume,
) { brightness, volume ->
listOf( listOf(
HomeMenuAdapter.HomeMenuBean( HomeMenuAdapter.HomeMenuBean(
title = "音量", title = R.string.home_item_volume,
icon = R.drawable.icon_battery_100, icon = R.drawable.icon_battery_100,
type = HomeMenuAdapter.HomeMenuBean.Type.Volume("0"), type = HomeMenuAdapter.HomeMenuBean.Type.Volume("$volume"),
), ),
HomeMenuAdapter.HomeMenuBean( HomeMenuAdapter.HomeMenuBean(
title = "亮度", title = R.string.home_item_brightness,
icon = R.drawable.icon_battery_100, icon = R.drawable.icon_battery_100,
type = HomeMenuAdapter.HomeMenuBean.Type.Brightness("0"), type = HomeMenuAdapter.HomeMenuBean.Type.Brightness("$brightness"),
), ),
HomeMenuAdapter.HomeMenuBean( HomeMenuAdapter.HomeMenuBean(
title = "SN", title = R.string.home_item_sn,
icon = R.drawable.icon_battery_100, icon = R.drawable.icon_battery_100,
type = HomeMenuAdapter.HomeMenuBean.Type.Sn("0"), 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
}
}
}
}
}
}
} }

View File

@ -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
}
}
}

View File

@ -1,6 +0,0 @@
package com.yuanxuan.rokid.ui
import androidx.fragment.app.Fragment
class SettingFragment: Fragment() {
}

View File

@ -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
)
}

View File

@ -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
}
}
}
}

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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"

View File

@ -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" />

View File

@ -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

View File

@ -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>

View File

@ -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>

View File

@ -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>