Skip to content

Commit 09eb244

Browse files
committed
增加基础的设置页面
1 parent 801cefd commit 09eb244

File tree

16 files changed

+978
-3
lines changed

16 files changed

+978
-3
lines changed

app/src/main/AndroidManifest.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,11 @@
174174
android:exported="false"
175175
android:label="@string/title_mobile_activity_user_space"
176176
android:theme="@style/Theme.BVMobile" />
177+
<activity
178+
android:name=".mobile.activities.SettingsActivity"
179+
android:exported="false"
180+
android:label="@string/title_mobile_activity_settings"
181+
android:theme="@style/Theme.BVMobile" />
177182
</application>
178183

179184
</manifest>
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
package dev.aaa1115910.bv.mobile.activities
2+
3+
import android.os.Bundle
4+
import androidx.activity.ComponentActivity
5+
import androidx.activity.compose.setContent
6+
import androidx.compose.foundation.layout.Column
7+
import androidx.compose.foundation.layout.fillMaxSize
8+
import androidx.compose.foundation.layout.padding
9+
import androidx.compose.material3.ExperimentalMaterial3Api
10+
import androidx.compose.material3.LargeTopAppBar
11+
import androidx.compose.material3.Scaffold
12+
import androidx.compose.material3.Text
13+
import androidx.compose.runtime.Composable
14+
import androidx.compose.ui.Modifier
15+
import dev.aaa1115910.bv.mobile.component.preferences.SwitchPreferenceItem
16+
import dev.aaa1115910.bv.mobile.screen.settings.SettingsScreen
17+
import dev.aaa1115910.bv.mobile.theme.BVMobileTheme
18+
import dev.aaa1115910.bv.util.PrefKeys
19+
import dev.aaa1115910.bv.util.Prefs
20+
21+
class SettingsActivity : ComponentActivity() {
22+
override fun onCreate(savedInstanceState: Bundle?) {
23+
super.onCreate(savedInstanceState)
24+
setContent {
25+
BVMobileTheme {
26+
SettingsScreen()
27+
}
28+
}
29+
}
30+
}
31+
32+
@OptIn(ExperimentalMaterial3Api::class)
33+
@Composable
34+
fun SettingsScreen1() {
35+
Scaffold(
36+
topBar = {
37+
LargeTopAppBar(title = {
38+
Text(text = "Settings")
39+
})
40+
}
41+
) { innerPadding ->
42+
Column(
43+
modifier = Modifier
44+
.padding(innerPadding)
45+
.fillMaxSize()
46+
) {
47+
Text(text = "Settings")
48+
SwitchPreferenceItem(title = "UseOld", prefReq = PrefKeys.prefShowFpsRequest)
49+
SwitchPreferenceItem(
50+
title = "UseOld",
51+
summary = "sssssss",
52+
prefReq = PrefKeys.prefShowFpsRequest,
53+
enabled = false
54+
)
55+
Text(text = "${Prefs.showFps}")
56+
}
57+
}
58+
}
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
package dev.aaa1115910.bv.mobile.component
2+
3+
import androidx.compose.material3.MaterialTheme
4+
import androidx.compose.material3.Surface
5+
import androidx.compose.material3.Text
6+
import androidx.compose.material3.adaptive.AnimatedPane
7+
import androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi
8+
import androidx.compose.material3.adaptive.ListDetailPaneScaffold
9+
import androidx.compose.material3.adaptive.ListDetailPaneScaffoldRole
10+
import androidx.compose.material3.adaptive.rememberListDetailPaneScaffoldNavigator
11+
import androidx.compose.runtime.Composable
12+
import androidx.compose.ui.Modifier
13+
import androidx.compose.ui.tooling.preview.Preview
14+
import androidx.compose.ui.unit.dp
15+
import dev.aaa1115910.bv.mobile.theme.BVMobileTheme
16+
17+
@OptIn(ExperimentalMaterial3AdaptiveApi::class)
18+
@Preview
19+
@Composable
20+
fun ListDetailPaneScaffoldSample() {
21+
BVMobileTheme {
22+
val scaffoldNavigator = rememberListDetailPaneScaffoldNavigator()
23+
ListDetailPaneScaffold(
24+
scaffoldState = scaffoldNavigator.scaffoldState,
25+
listPane = {
26+
AnimatedPane(
27+
modifier = Modifier.preferredWidth(200.dp),
28+
) {
29+
Surface(
30+
color = MaterialTheme.colorScheme.secondary,
31+
onClick = {
32+
scaffoldNavigator.navigateTo(ListDetailPaneScaffoldRole.Detail)
33+
}
34+
) {
35+
Text("List")
36+
}
37+
}
38+
},
39+
) {
40+
AnimatedPane(modifier = Modifier) {
41+
Surface(
42+
color = MaterialTheme.colorScheme.primary,
43+
onClick = {
44+
scaffoldNavigator.navigateBack()
45+
}
46+
) {
47+
Text("Details")
48+
}
49+
}
50+
}
51+
}
52+
53+
}
54+
55+
56+
@Preview
57+
@Composable
58+
private fun SettingPre() {
59+
BVMobileTheme {
60+
Surface {
61+
Settings()
62+
}
63+
}
64+
}
65+
66+
@OptIn(ExperimentalMaterial3AdaptiveApi::class)
67+
@Composable
68+
fun Settings() {
69+
val scaffoldNavigator = rememberListDetailPaneScaffoldNavigator()
70+
ListDetailPaneScaffold(
71+
scaffoldState = scaffoldNavigator.scaffoldState,
72+
listPane = {
73+
AnimatedPane(
74+
modifier = Modifier.preferredWidth(200.dp),
75+
) {
76+
Surface(
77+
color = MaterialTheme.colorScheme.secondary,
78+
onClick = {
79+
scaffoldNavigator.navigateTo(ListDetailPaneScaffoldRole.Detail)
80+
}
81+
) {
82+
Text("List")
83+
}
84+
}
85+
},
86+
) {
87+
AnimatedPane(modifier = Modifier) {
88+
Surface(
89+
color = MaterialTheme.colorScheme.primary,
90+
onClick = {
91+
scaffoldNavigator.navigateBack()
92+
}
93+
) {
94+
Text("Details")
95+
}
96+
}
97+
}
98+
}
Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
package dev.aaa1115910.bv.mobile.component.preferences
2+
3+
import androidx.compose.foundation.clickable
4+
import androidx.compose.foundation.layout.fillMaxWidth
5+
import androidx.compose.foundation.layout.heightIn
6+
import androidx.compose.foundation.lazy.LazyColumn
7+
import androidx.compose.foundation.lazy.items
8+
import androidx.compose.material3.AlertDialog
9+
import androidx.compose.material3.ListItem
10+
import androidx.compose.material3.RadioButton
11+
import androidx.compose.material3.Text
12+
import androidx.compose.runtime.Composable
13+
import androidx.compose.runtime.collectAsState
14+
import androidx.compose.runtime.getValue
15+
import androidx.compose.runtime.mutableStateOf
16+
import androidx.compose.runtime.remember
17+
import androidx.compose.runtime.rememberCoroutineScope
18+
import androidx.compose.runtime.setValue
19+
import androidx.compose.ui.Modifier
20+
import androidx.compose.ui.platform.LocalContext
21+
import androidx.compose.ui.unit.dp
22+
import de.schnettler.datastore.manager.DataStoreManager
23+
import de.schnettler.datastore.manager.PreferenceRequest
24+
import dev.aaa1115910.bv.dataStore
25+
import kotlinx.coroutines.Dispatchers
26+
import kotlinx.coroutines.launch
27+
28+
@Composable
29+
fun <T> RadioPreferenceItem(
30+
modifier: Modifier = Modifier,
31+
title: String,
32+
summary: String? = null,
33+
leadingContent: @Composable (() -> Unit)? = null,
34+
enabled: Boolean = true,
35+
singleLineTitle: Boolean = false,
36+
singleLineSummary: Boolean = false,
37+
onSelectedChange: (T) -> Unit,
38+
items: Map<T, String>,
39+
selectedValue: T
40+
) {
41+
var showRadioDialog by remember { mutableStateOf(false) }
42+
43+
TextPreferenceItem(
44+
modifier = modifier,
45+
title = title,
46+
summary = summary,
47+
leadingContent = leadingContent,
48+
enabled = enabled,
49+
singleLineTitle = singleLineTitle,
50+
singleLineSummary = singleLineSummary,
51+
onClick = { showRadioDialog = true }
52+
)
53+
54+
RadioListDialog(
55+
show = showRadioDialog,
56+
onHideDialog = { showRadioDialog = false },
57+
values = items,
58+
selectedValue = selectedValue,
59+
onSelectValue = { onSelectedChange(it) }
60+
)
61+
}
62+
63+
@Composable
64+
fun <T> RadioPreferenceItem(
65+
modifier: Modifier = Modifier,
66+
title: String,
67+
summary: String? = null,
68+
leadingContent: @Composable (() -> Unit)? = null,
69+
enabled: Boolean = true,
70+
singleLineTitle: Boolean = false,
71+
singleLineSummary: Boolean = false,
72+
items: Map<T, String>,
73+
prefReq: PreferenceRequest<T>
74+
) {
75+
val dataStoreManager = DataStoreManager(LocalContext.current.dataStore)
76+
val prefs by dataStoreManager.preferenceFlow.collectAsState(initial = null)
77+
val scope = rememberCoroutineScope()
78+
79+
RadioPreferenceItem(
80+
modifier = modifier,
81+
title = title,
82+
summary = summary,
83+
leadingContent = leadingContent,
84+
enabled = enabled,
85+
singleLineTitle = singleLineTitle,
86+
singleLineSummary = singleLineSummary,
87+
onSelectedChange = { newValue ->
88+
println("set ${prefReq.key} to $newValue")
89+
scope.launch(Dispatchers.IO) {
90+
dataStoreManager.editPreference(prefReq.key, newValue)
91+
}
92+
},
93+
items = items,
94+
selectedValue = prefs.getOrDefault(prefReq)
95+
)
96+
}
97+
98+
@Composable
99+
private fun <T> RadioListDialog(
100+
modifier: Modifier = Modifier,
101+
show: Boolean,
102+
onHideDialog: () -> Unit,
103+
values: Map<T, String>,
104+
selectedValue: T,
105+
onSelectValue: (T) -> Unit,
106+
) {
107+
if (show) {
108+
AlertDialog(
109+
modifier = modifier,
110+
onDismissRequest = onHideDialog,
111+
confirmButton = { },
112+
text = {
113+
LazyColumn(
114+
modifier = Modifier.heightIn(max = 300.dp)
115+
) {
116+
items(values.toList()) { (value, name) ->
117+
RadioListItem(
118+
text = name,
119+
onClick = {
120+
onSelectValue(value)
121+
onHideDialog()
122+
},
123+
selected = value == selectedValue
124+
)
125+
}
126+
}
127+
}
128+
)
129+
}
130+
}
131+
132+
@Composable
133+
fun RadioListItem(
134+
modifier: Modifier = Modifier,
135+
text: String,
136+
onClick: (() -> Unit),
137+
selected: Boolean,
138+
) {
139+
ListItem(
140+
modifier = modifier
141+
.fillMaxWidth()
142+
.clickable { onClick() },
143+
headlineContent = { Text(text = text) },
144+
leadingContent = {
145+
RadioButton(
146+
selected = selected,
147+
onClick = onClick
148+
)
149+
}
150+
)
151+
}

0 commit comments

Comments
 (0)