繁体   English   中英

State 喷气背包支架

[英]State Holder in jetpack compose

我在State学习 Jetpack Compose。 我发现State holders 作为真实来源 所以创建了我的一些数据,如果我在这里做错了,你们能指导我吗?

PairViewModel.kt

class PairViewModel : ViewModel() {

    var isBluetoothEnabled = mutableStateOf(false)
        private set

    fun onBluetoothEnable(value: Boolean) {
        isBluetoothEnabled.value = value
    }
}

PairScreen.kt

class PairScreenState(context: Context, viewModel: PairViewModel) {

    private val bluetoothManager: BluetoothManager = context.getSystemService(BluetoothManager::class.java)
    private val bluetoothAdapter: BluetoothAdapter by lazy {
        bluetoothManager.adapter
    }

    init {
        viewModel.onBluetoothEnable(bluetoothAdapter.isEnabled)
    }

    fun checkBluetoothStatus(bluetoothStatus: MutableState<Boolean>): BroadcastReceiver {
        return object : BroadcastReceiver() {
            override fun onReceive(context: Context?, intent: Intent?) {
                if (intent?.action == BluetoothAdapter.ACTION_STATE_CHANGED) {
                    when (intent.getIntExtra(
                        BluetoothAdapter.EXTRA_STATE,
                        BluetoothAdapter.ERROR
                    )) {
                        BluetoothAdapter.STATE_OFF -> {
                            bluetoothStatus.value = false
                        }
                        BluetoothAdapter.STATE_ON -> {
                            bluetoothStatus.value = true
                        }
                    }
                }
            }
        }
    }

}

@Composable
fun rememberPairScreenState(
    context: Context,
    viewModel: PairViewModel
) = remember {
    PairScreenState(context, viewModel)
}

@Composable
fun PairContent(
    context: Context = LocalContext.current,
    viewModel: PairViewModel = getViewModel(),
    rememberPairScreenState: PairScreenState = rememberPairScreenState(context, viewModel),
) {
    AnimatedVisibility(visible = true) {
        AppBarScaffold() {
            Column(
                modifier = Modifier
                    
                    .fillMaxSize()
                    .verticalScroll(rememberScrollState())
            ) {
                rememberPairScreenState.checkBluetoothStatus(viewModel.isBluetoothEnabled).apply {
                    context.registerReceiver(this, IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED))
                }
                if (viewModel.isBluetoothEnabled.value) {
                    println(">> Enable >>>")
                } else {
                    println(">> Disable >>>")
                }
            }
        }
    }
}

@Preview(showBackground = true)
@Composable
fun PairContentPreview() {
    PairContent()
}

我以蓝牙为例来了解我的用例中的 state holder。 如果您发现我的代码有任何问题,请指导我。 谢谢

我会在这里尽力而为,我知道你来自哪里,有一个代码很难验证它是否是正确的做事方式,不管你像github github查看了多少源材料,有时参考只是不还存在

对于State吊装/处理,遵循来自社区的原则是好的。 所以我处理State Hoisting的方式,是在考虑它的purpose

因此,如果它只是需要在@Composable中本地化的东西

remember {...}

如果它处理多个逻辑和值, State class

class PersonState(val personParam: Person) {
        .....
}

@Composable 
fun rememberPersonState(person: Person) = remember(key1= person) {
       PersonState(person)
}

如果它处理存储库、.network 调用、持久性是需求的主要部分的用例、 ViewModellifecyle是您必须注意的事情。 ViewModel

class PersonScreenViewModel {
     /..RepositoryStateFlows../
     /..Data structural updates../
}

到目前为止,这种心态和方法在决定如何提升states时对我有所帮助。

至于你的PairScreenState ,考虑这个用例解决方案来自这篇文章Detect if Soft Keyboard is Open or Close ,你可以在其中检测键盘是否打开

我将拥有您的蓝牙用例,我将在其中将其实现为Composable实用程序 function 并返回一个State ,我可以在其中定义DisposableEffect ,尽管这段代码不起作用,但我想您会明白我的意思。

enum class BlueTooth {
    ON, OFF
}

@Composable
fun BlueToothAsState(): State<BlueTooth> {
    val blueToothState = remember { mutableStateOf(BlueTooth.OFF) }
    DisposableEffect(view) {
        var mReceiver : BroadcastReceiver? = object : BroadcastReceiver()  {
                /.../
                when (intent.getIntExtra(BluetoothAdapter.EXTRA_STATE,  BluetoothAdapter.ERROR)) {
                        BluetoothAdapter.STATE_OFF -> {
                            blueToothState = BlueTooth.OFF
                        }
                        BluetoothAdapter.STATE_ON -> {
                            blueToothState = BlueTooth.ON
                        }
                    }
                }
           }
        onDispose {
            mReceiver = null
        }
    }

    return blueToothState
}

至于代码的其他部分,如果它总是设置为true ,我认为你不需要它

 AnimatedVisibility(visible = true)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM