add ble sort
This commit is contained in:
parent
7652ccc135
commit
b915659217
|
|
@ -7,14 +7,14 @@ plugins {
|
||||||
|
|
||||||
android {
|
android {
|
||||||
namespace 'llc.arma.ble'
|
namespace 'llc.arma.ble'
|
||||||
compileSdk 33
|
compileSdk 34
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
applicationId "llc.arma.ble"
|
applicationId "llc.arma.ble"
|
||||||
minSdk 26
|
minSdk 26
|
||||||
targetSdk 33
|
targetSdk 34
|
||||||
versionCode 15
|
versionCode 17
|
||||||
versionName "1.2.15"
|
versionName "1.2.17"
|
||||||
|
|
||||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||||
vectorDrawables {
|
vectorDrawables {
|
||||||
|
|
@ -23,6 +23,10 @@ android {
|
||||||
}
|
}
|
||||||
|
|
||||||
buildTypes {
|
buildTypes {
|
||||||
|
debug {
|
||||||
|
minifyEnabled false
|
||||||
|
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
||||||
|
}
|
||||||
release {
|
release {
|
||||||
minifyEnabled false
|
minifyEnabled false
|
||||||
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
||||||
|
|
@ -59,6 +63,7 @@ dependencies {
|
||||||
|
|
||||||
implementation 'androidx.core:core-ktx:1.10.1'
|
implementation 'androidx.core:core-ktx:1.10.1'
|
||||||
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.6.1'
|
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.6.1'
|
||||||
|
implementation 'androidx.lifecycle:lifecycle-runtime-compose:2.7.0-alpha01'
|
||||||
implementation 'androidx.activity:activity-compose:1.7.2'
|
implementation 'androidx.activity:activity-compose:1.7.2'
|
||||||
implementation "androidx.compose.ui:ui:1.5.0-beta01"
|
implementation "androidx.compose.ui:ui:1.5.0-beta01"
|
||||||
implementation "androidx.compose.ui:ui-tooling-preview:1.5.0-beta01"
|
implementation "androidx.compose.ui:ui-tooling-preview:1.5.0-beta01"
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,15 @@
|
||||||
package llc.arma.ble.app.ui
|
package llc.arma.ble.app.ui
|
||||||
|
|
||||||
import android.Manifest
|
import android.Manifest
|
||||||
import android.content.BroadcastReceiver
|
import android.annotation.SuppressLint
|
||||||
|
import android.app.Activity
|
||||||
|
import android.bluetooth.BluetoothAdapter
|
||||||
|
import android.bluetooth.BluetoothManager
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.content.IntentFilter
|
import android.content.pm.PackageManager
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.util.Log
|
|
||||||
import android.view.KeyEvent
|
|
||||||
import androidx.activity.ComponentActivity
|
import androidx.activity.ComponentActivity
|
||||||
import androidx.activity.compose.BackHandler
|
import androidx.activity.compose.BackHandler
|
||||||
import androidx.activity.compose.setContent
|
import androidx.activity.compose.setContent
|
||||||
|
|
@ -24,10 +25,16 @@ import androidx.compose.material3.Surface
|
||||||
import androidx.compose.runtime.*
|
import androidx.compose.runtime.*
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.platform.LocalContext
|
||||||
|
import androidx.compose.ui.platform.LocalLifecycleOwner
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.app.ActivityCompat
|
||||||
|
import androidx.core.app.ActivityCompat.startActivityForResult
|
||||||
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
|
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
|
||||||
import androidx.core.view.WindowCompat
|
import androidx.core.view.WindowCompat
|
||||||
|
import androidx.lifecycle.Lifecycle
|
||||||
|
import androidx.lifecycle.LifecycleEventObserver
|
||||||
|
import androidx.lifecycle.LifecycleOwner
|
||||||
import com.google.accompanist.permissions.ExperimentalPermissionsApi
|
import com.google.accompanist.permissions.ExperimentalPermissionsApi
|
||||||
import com.google.accompanist.permissions.rememberMultiplePermissionsState
|
import com.google.accompanist.permissions.rememberMultiplePermissionsState
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
|
|
@ -37,13 +44,17 @@ import llc.arma.ble.app.ui.common.LocalBottomDialogState
|
||||||
import llc.arma.ble.app.ui.screen.main.MainScreen
|
import llc.arma.ble.app.ui.screen.main.MainScreen
|
||||||
import llc.arma.ble.app.ui.theme.BleTheme
|
import llc.arma.ble.app.ui.theme.BleTheme
|
||||||
|
|
||||||
|
|
||||||
@AndroidEntryPoint
|
@AndroidEntryPoint
|
||||||
class MainActivity : ComponentActivity() {
|
class MainActivity : ComponentActivity() {
|
||||||
|
|
||||||
|
@SuppressLint("MissingPermission")
|
||||||
@OptIn(ExperimentalPermissionsApi::class, ExperimentalMaterialApi::class)
|
@OptIn(ExperimentalPermissionsApi::class, ExperimentalMaterialApi::class)
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
|
||||||
|
val mBluetoothAdapter = (getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager).adapter
|
||||||
|
|
||||||
WindowCompat.setDecorFitsSystemWindows(window, false)
|
WindowCompat.setDecorFitsSystemWindows(window, false)
|
||||||
|
|
||||||
installSplashScreen()
|
installSplashScreen()
|
||||||
|
|
@ -168,9 +179,32 @@ class MainActivity : ComponentActivity() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var bleEnabled by remember {
|
||||||
|
mutableStateOf(mBluetoothAdapter.isEnabled)
|
||||||
|
}
|
||||||
|
|
||||||
|
val lifecycleOwner = LocalLifecycleOwner.current
|
||||||
|
val lifecycleState by lifecycleOwner.lifecycle.currentStateFlow.collectAsState()
|
||||||
|
|
||||||
|
LaunchedEffect(lifecycleState){
|
||||||
|
bleEnabled = mBluetoothAdapter.isEnabled
|
||||||
|
}
|
||||||
|
|
||||||
if (multiplePermissionsState.allPermissionsGranted) {
|
if (multiplePermissionsState.allPermissionsGranted) {
|
||||||
|
|
||||||
MainScreen()
|
if(bleEnabled) {
|
||||||
|
|
||||||
|
MainScreen()
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
val context = LocalContext.current
|
||||||
|
|
||||||
|
LaunchedEffect(mBluetoothAdapter.isEnabled){
|
||||||
|
val intent = Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE)
|
||||||
|
(context as Activity).startActivityForResult(intent, 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
|
@ -183,7 +217,9 @@ class MainActivity : ComponentActivity() {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
)
|
)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -192,4 +228,22 @@ class MainActivity : ComponentActivity() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun OnLifecycleEvent(onEvent: (owner: LifecycleOwner, event: Lifecycle.Event) -> Unit) {
|
||||||
|
val eventHandler = rememberUpdatedState(onEvent)
|
||||||
|
val lifecycleOwner = rememberUpdatedState(LocalLifecycleOwner.current)
|
||||||
|
|
||||||
|
DisposableEffect(lifecycleOwner.value) {
|
||||||
|
val lifecycle = lifecycleOwner.value.lifecycle
|
||||||
|
val observer = LifecycleEventObserver { owner, event ->
|
||||||
|
eventHandler.value(owner, event)
|
||||||
|
}
|
||||||
|
|
||||||
|
lifecycle.addObserver(observer)
|
||||||
|
onDispose {
|
||||||
|
lifecycle.removeObserver(observer)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -41,6 +41,14 @@ class BleListContract {
|
||||||
val type: BleInfo.Type?
|
val type: BleInfo.Type?
|
||||||
) : Event()
|
) : Event()
|
||||||
|
|
||||||
|
data class OnSortFieldChanged(
|
||||||
|
val field: State.Filter.Field
|
||||||
|
) : Event()
|
||||||
|
|
||||||
|
data class OnSortOrderChanged(
|
||||||
|
val order: State.Filter.Order
|
||||||
|
) : Event()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
data class State(
|
data class State(
|
||||||
|
|
@ -50,12 +58,24 @@ class BleListContract {
|
||||||
) : ViewState {
|
) : ViewState {
|
||||||
|
|
||||||
data class Filter(
|
data class Filter(
|
||||||
|
val sortField: Field = Field.Name,
|
||||||
|
val sortOrder: Order = Order.Asc,
|
||||||
val name: String = "",
|
val name: String = "",
|
||||||
val mac: String = "",
|
val mac: String = "",
|
||||||
val battery: ClosedFloatingPointRange<Float> = (0f)..(100f),
|
val battery: ClosedFloatingPointRange<Float> = (0f)..(100f),
|
||||||
val rssi: ClosedFloatingPointRange<Float> = (-100f)..(-10f),
|
val rssi: ClosedFloatingPointRange<Float> = (-100f)..(-10f),
|
||||||
val bleType: BleInfo.Type? = null
|
val bleType: BleInfo.Type? = null
|
||||||
)
|
){
|
||||||
|
|
||||||
|
enum class Field {
|
||||||
|
Name, Mac, Distance, Dbm, Battery
|
||||||
|
}
|
||||||
|
|
||||||
|
enum class Order {
|
||||||
|
Asc, Desc
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -128,6 +128,21 @@ fun BleListScreen(
|
||||||
it.serial.contains(state.filter.mac) &&
|
it.serial.contains(state.filter.mac) &&
|
||||||
state.filter.rssi.contains(it.rssi?.toFloat() ?: Float.MIN_VALUE) &&
|
state.filter.rssi.contains(it.rssi?.toFloat() ?: Float.MIN_VALUE) &&
|
||||||
state.filter.battery.contains(it.batteryLevel.toFloat())
|
state.filter.battery.contains(it.batteryLevel.toFloat())
|
||||||
|
}.let {
|
||||||
|
when(state.filter.sortField){
|
||||||
|
BleListContract.State.Filter.Field.Name -> it.sortedBy { it.name }
|
||||||
|
BleListContract.State.Filter.Field.Mac -> it.sortedBy { it.serial }
|
||||||
|
BleListContract.State.Filter.Field.Distance -> it.sortedBy { 10.0.pow((it.tx.toDouble() - (it.rssi?.toDouble() ?: 0.0) - 74) / 20).toFloat() }
|
||||||
|
BleListContract.State.Filter.Field.Dbm -> it.sortedBy { it.rssi ?: 0 }
|
||||||
|
BleListContract.State.Filter.Field.Battery -> it.sortedBy { it.batteryLevel }
|
||||||
|
}
|
||||||
|
}.let {
|
||||||
|
|
||||||
|
when(state.filter.sortOrder){
|
||||||
|
BleListContract.State.Filter.Order.Asc -> it
|
||||||
|
BleListContract.State.Filter.Order.Desc -> it.reversed()
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(filteredData.isEmpty()){
|
if(filteredData.isEmpty()){
|
||||||
|
|
@ -165,7 +180,7 @@ fun BleListScreen(
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
items(items = filteredData.sortedBy { it.name }.reversed()) {
|
items(items = filteredData) {
|
||||||
|
|
||||||
BleItem(
|
BleItem(
|
||||||
ble = it,
|
ble = it,
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,7 @@ class BleListViewModel @Inject constructor(
|
||||||
|
|
||||||
}.launchIn(viewModelScope)
|
}.launchIn(viewModelScope)
|
||||||
|
|
||||||
delay(6_000)
|
delay(30_000)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -68,6 +68,8 @@ class BleListViewModel @Inject constructor(
|
||||||
is BleListContract.Event.OnShowFilter -> reduce(viewState.value, event)
|
is BleListContract.Event.OnShowFilter -> reduce(viewState.value, event)
|
||||||
is BleListContract.Event.OnTypeChanged -> reduce(viewState.value, event)
|
is BleListContract.Event.OnTypeChanged -> reduce(viewState.value, event)
|
||||||
is BleListContract.Event.OnBatteryRangeChanged -> reduce(viewState.value, event)
|
is BleListContract.Event.OnBatteryRangeChanged -> reduce(viewState.value, event)
|
||||||
|
is BleListContract.Event.OnSortFieldChanged -> reduce(viewState.value, event)
|
||||||
|
is BleListContract.Event.OnSortOrderChanged -> reduce(viewState.value, event)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -100,6 +102,28 @@ class BleListViewModel @Inject constructor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun reduce(
|
||||||
|
state: BleListContract.State,
|
||||||
|
event: BleListContract.Event.OnSortOrderChanged
|
||||||
|
) {
|
||||||
|
setState {
|
||||||
|
copy(
|
||||||
|
filter = this.filter.copy(sortOrder = event.order)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun reduce(
|
||||||
|
state: BleListContract.State,
|
||||||
|
event: BleListContract.Event.OnSortFieldChanged
|
||||||
|
) {
|
||||||
|
setState {
|
||||||
|
copy(
|
||||||
|
filter = this.filter.copy(sortField = event.field)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun reduce(
|
private fun reduce(
|
||||||
state: BleListContract.State,
|
state: BleListContract.State,
|
||||||
event: BleListContract.Event.OnNameFilterChanged
|
event: BleListContract.Event.OnNameFilterChanged
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,9 @@ import androidx.compose.foundation.layout.fillMaxSize
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.height
|
import androidx.compose.foundation.layout.height
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.rememberScrollState
|
||||||
import androidx.compose.foundation.shape.CircleShape
|
import androidx.compose.foundation.shape.CircleShape
|
||||||
|
import androidx.compose.foundation.verticalScroll
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.rounded.BatteryFull
|
import androidx.compose.material.icons.rounded.BatteryFull
|
||||||
import androidx.compose.material.icons.rounded.Bluetooth
|
import androidx.compose.material.icons.rounded.Bluetooth
|
||||||
|
|
@ -17,6 +19,8 @@ import androidx.compose.material.icons.rounded.Close
|
||||||
import androidx.compose.material.icons.rounded.Search
|
import androidx.compose.material.icons.rounded.Search
|
||||||
import androidx.compose.material.icons.rounded.ShortText
|
import androidx.compose.material.icons.rounded.ShortText
|
||||||
import androidx.compose.material.icons.rounded.SignalCellularAlt
|
import androidx.compose.material.icons.rounded.SignalCellularAlt
|
||||||
|
import androidx.compose.material.icons.rounded.Sort
|
||||||
|
import androidx.compose.material.icons.rounded.SortByAlpha
|
||||||
import androidx.compose.material3.DropdownMenuItem
|
import androidx.compose.material3.DropdownMenuItem
|
||||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
import androidx.compose.material3.ExposedDropdownMenuBox
|
import androidx.compose.material3.ExposedDropdownMenuBox
|
||||||
|
|
@ -39,6 +43,25 @@ import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import llc.arma.ble.domain.model.BleInfo
|
import llc.arma.ble.domain.model.BleInfo
|
||||||
|
|
||||||
|
private val BleListContract.State.Filter.Order.localized: String
|
||||||
|
get() {
|
||||||
|
return when(this){
|
||||||
|
BleListContract.State.Filter.Order.Asc -> "Прямой ↓"
|
||||||
|
BleListContract.State.Filter.Order.Desc -> "Обратный ↑"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private val BleListContract.State.Filter.Field.localized: String
|
||||||
|
get() {
|
||||||
|
return when(this){
|
||||||
|
BleListContract.State.Filter.Field.Name -> "Имя"
|
||||||
|
BleListContract.State.Filter.Field.Mac -> "MAC"
|
||||||
|
BleListContract.State.Filter.Field.Distance -> "Расстояние"
|
||||||
|
BleListContract.State.Filter.Field.Dbm -> "dBm"
|
||||||
|
BleListContract.State.Filter.Field.Battery -> "Заряд"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private val BleInfo.Type?.localized: String
|
private val BleInfo.Type?.localized: String
|
||||||
get() {
|
get() {
|
||||||
return when(this){
|
return when(this){
|
||||||
|
|
@ -69,11 +92,151 @@ fun Filter(
|
||||||
Spacer(modifier = Modifier.height(16.dp))
|
Spacer(modifier = Modifier.height(16.dp))
|
||||||
|
|
||||||
Column(
|
Column(
|
||||||
modifier = Modifier.padding(horizontal = 12.dp)
|
modifier = Modifier
|
||||||
|
.padding(horizontal = 12.dp)
|
||||||
|
.verticalScroll(rememberScrollState())
|
||||||
) {
|
) {
|
||||||
|
|
||||||
Spacer(modifier = Modifier.height(8.dp))
|
Spacer(modifier = Modifier.height(8.dp))
|
||||||
|
|
||||||
|
Row(
|
||||||
|
verticalAlignment = Alignment.CenterVertically
|
||||||
|
) {
|
||||||
|
|
||||||
|
Icon(
|
||||||
|
imageVector = Icons.Rounded.Sort,
|
||||||
|
contentDescription = null,
|
||||||
|
modifier = Modifier.padding(12.dp)
|
||||||
|
)
|
||||||
|
|
||||||
|
var expanded by remember { mutableStateOf(false) }
|
||||||
|
|
||||||
|
ExposedDropdownMenuBox(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(end = 8.dp),
|
||||||
|
expanded = expanded,
|
||||||
|
onExpandedChange = {
|
||||||
|
expanded = it
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
|
||||||
|
OutlinedTextField(
|
||||||
|
modifier = Modifier
|
||||||
|
.menuAnchor()
|
||||||
|
.fillMaxWidth(),
|
||||||
|
readOnly = true,
|
||||||
|
value = filter.sortField.localized,
|
||||||
|
onValueChange = { },
|
||||||
|
label = { Text("Сортировка") },
|
||||||
|
trailingIcon = {
|
||||||
|
ExposedDropdownMenuDefaults.TrailingIcon(
|
||||||
|
expanded = expanded
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
ExposedDropdownMenu(
|
||||||
|
modifier = Modifier
|
||||||
|
.background(MaterialTheme.colorScheme.background)
|
||||||
|
.fillMaxWidth(),
|
||||||
|
expanded = expanded,
|
||||||
|
onDismissRequest = {
|
||||||
|
expanded = false
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
|
||||||
|
BleListContract.State.Filter.Field.values().forEach { selectionOption ->
|
||||||
|
DropdownMenuItem(
|
||||||
|
onClick = {
|
||||||
|
onEvent(
|
||||||
|
BleListContract.Event.OnSortFieldChanged(
|
||||||
|
selectionOption
|
||||||
|
)
|
||||||
|
)
|
||||||
|
expanded = false
|
||||||
|
},
|
||||||
|
text = {
|
||||||
|
Text(text = selectionOption.localized)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Spacer(modifier = Modifier.height(8.dp))
|
||||||
|
|
||||||
|
Row(
|
||||||
|
verticalAlignment = Alignment.CenterVertically
|
||||||
|
) {
|
||||||
|
|
||||||
|
Icon(
|
||||||
|
imageVector = Icons.Rounded.SortByAlpha,
|
||||||
|
contentDescription = null,
|
||||||
|
modifier = Modifier.padding(12.dp)
|
||||||
|
)
|
||||||
|
|
||||||
|
var expanded by remember { mutableStateOf(false) }
|
||||||
|
|
||||||
|
ExposedDropdownMenuBox(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(end = 8.dp),
|
||||||
|
expanded = expanded,
|
||||||
|
onExpandedChange = {
|
||||||
|
expanded = it
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
|
||||||
|
OutlinedTextField(
|
||||||
|
modifier = Modifier
|
||||||
|
.menuAnchor()
|
||||||
|
.fillMaxWidth(),
|
||||||
|
readOnly = true,
|
||||||
|
value = filter.sortOrder.localized,
|
||||||
|
onValueChange = { },
|
||||||
|
label = { Text("Напрвление сортировки") },
|
||||||
|
trailingIcon = {
|
||||||
|
ExposedDropdownMenuDefaults.TrailingIcon(
|
||||||
|
expanded = expanded
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
ExposedDropdownMenu(
|
||||||
|
modifier = Modifier
|
||||||
|
.background(MaterialTheme.colorScheme.background)
|
||||||
|
.fillMaxWidth(),
|
||||||
|
expanded = expanded,
|
||||||
|
onDismissRequest = {
|
||||||
|
expanded = false
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
|
||||||
|
BleListContract.State.Filter.Order.values().forEach { selectionOption ->
|
||||||
|
DropdownMenuItem(
|
||||||
|
onClick = {
|
||||||
|
onEvent(
|
||||||
|
BleListContract.Event.OnSortOrderChanged(
|
||||||
|
selectionOption
|
||||||
|
)
|
||||||
|
)
|
||||||
|
expanded = false
|
||||||
|
},
|
||||||
|
text = {
|
||||||
|
Text(text = selectionOption.localized)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Spacer(modifier = Modifier.height(8.dp))
|
||||||
|
|
||||||
Row(
|
Row(
|
||||||
verticalAlignment = Alignment.CenterVertically
|
verticalAlignment = Alignment.CenterVertically
|
||||||
) {
|
) {
|
||||||
|
|
@ -87,7 +250,9 @@ fun Filter(
|
||||||
var expanded by remember { mutableStateOf(false) }
|
var expanded by remember { mutableStateOf(false) }
|
||||||
|
|
||||||
ExposedDropdownMenuBox(
|
ExposedDropdownMenuBox(
|
||||||
modifier = Modifier.fillMaxWidth().padding(end = 8.dp),
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(end = 8.dp),
|
||||||
expanded = expanded,
|
expanded = expanded,
|
||||||
onExpandedChange = {
|
onExpandedChange = {
|
||||||
expanded = it
|
expanded = it
|
||||||
|
|
@ -95,7 +260,9 @@ fun Filter(
|
||||||
) {
|
) {
|
||||||
|
|
||||||
OutlinedTextField(
|
OutlinedTextField(
|
||||||
modifier = Modifier.menuAnchor().fillMaxWidth(),
|
modifier = Modifier
|
||||||
|
.menuAnchor()
|
||||||
|
.fillMaxWidth(),
|
||||||
readOnly = true,
|
readOnly = true,
|
||||||
value = filter.bleType.localized,
|
value = filter.bleType.localized,
|
||||||
onValueChange = { },
|
onValueChange = { },
|
||||||
|
|
@ -108,7 +275,9 @@ fun Filter(
|
||||||
)
|
)
|
||||||
|
|
||||||
ExposedDropdownMenu(
|
ExposedDropdownMenu(
|
||||||
modifier = Modifier.background(MaterialTheme.colorScheme.background).fillMaxWidth(),
|
modifier = Modifier
|
||||||
|
.background(MaterialTheme.colorScheme.background)
|
||||||
|
.fillMaxWidth(),
|
||||||
expanded = expanded,
|
expanded = expanded,
|
||||||
onDismissRequest = {
|
onDismissRequest = {
|
||||||
expanded = false
|
expanded = false
|
||||||
|
|
@ -137,6 +306,8 @@ fun Filter(
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Spacer(modifier = Modifier.height(8.dp))
|
||||||
|
|
||||||
Row(
|
Row(
|
||||||
verticalAlignment = Alignment.CenterVertically
|
verticalAlignment = Alignment.CenterVertically
|
||||||
){
|
){
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue