喷气背包中的状态持有者组成

Viv*_*odi 4 android kotlin android-architecture-components android-jetpack android-jetpack-compose

我正在State学习jetpack compose。我发现国家持有者是真相的来源。所以创建了我的一些数据,如果我在这里做错了,你们可以指导我吗?

PairViewModel.kt

class PairViewModel : ViewModel() {

    var isBluetoothEnabled = mutableStateOf(false)
        private set

    fun onBluetoothEnable(value: Boolean) {
        isBluetoothEnabled.value = value
    }
}
Run Code Online (Sandbox Code Playgroud)

配对屏幕.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()
}
Run Code Online (Sandbox Code Playgroud)

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

z.g*_*g.y 6

我会尽力在这里,我明白你来自哪里,有一个很难验证它是否是“尚未”的正确方法的代码,无论你像在 中审查了多少源材料github,有时引用只是不'还不存在吧?

对于State起重/搬运,最好遵循社区的原则。所以我处理的方式State Hoisting就是思考它purpose

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

remember {...}
Run Code Online (Sandbox Code Playgroud)

如果它涉及多个逻辑和值,那么State

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

@Composable 
fun rememberPersonState(person: Person) = remember(key1= person) {
       PersonState(person)
}
Run Code Online (Sandbox Code Playgroud)

如果它涉及存储库、网络调用、持久性是需求的主要部分的用例ViewModel,那么lifecyle您必须注意这一点。ViewModel

class PersonScreenViewModel {
     /..RepositoryStateFlows../
     /..Data structural updates../
}
Run Code Online (Sandbox Code Playgroud)

到目前为止,这种心态和方法在决定如何提升我的states.

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

我将拥有您的蓝牙用例,我将其实现为Composable实用程序函数并返回 a ,State我可以在其中定义 a 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
}
Run Code Online (Sandbox Code Playgroud)

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

 AnimatedVisibility(visible = true)
Run Code Online (Sandbox Code Playgroud)