ccd*_*ccd 8 android android-jetpack-compose
有没有办法在撰写功能中获取当前活动?
@Composable
fun CameraPreviewScreen() {
val context = ContextAmbient.current
if (ActivityCompat.checkSelfPermission(
context,
Manifest.permission.CAMERA
) != PackageManager.PERMISSION_GRANTED
) {
ActivityCompat.requestPermissions(
this, MainActivity.REQUIRED_PERMISSIONS, MainActivity.REQUEST_CODE_PERMISSIONS // get activity for `this`
)
return
}
}
Run Code Online (Sandbox Code Playgroud)
Jef*_*set 47
虽然之前的答案(即ContextWrapper-aware)确实是正确的,但我想提供一种更惯用的复制粘贴实现。
fun Context.getActivity(): ComponentActivity? = when (this) {
is ComponentActivity -> this
is ContextWrapper -> baseContext.getActivity()
else -> null
}
Run Code Online (Sandbox Code Playgroud)
由于ContextWrappers 不可能相互缠绕很多次,因此递归在这里就可以了。
Abd*_*oui 45
您可以从转换上下文的可组合项中获取活动(我还没有发现上下文不是活动的情况)。然而,吉姆提到过,这样做并不是一个好的做法。
val activity = LocalContext.current as Activity
Run Code Online (Sandbox Code Playgroud)
就我个人而言,当我只是在玩一些需要活动的代码(权限是一个很好的例子)时,我会使用它,但是一旦我让它工作,我只需将其移动到活动并使用参数/回调。
编辑:正如评论中提到的,在生产代码中使用它可能很危险,因为它可能会崩溃,因为 current 是上下文包装器,我的建议主要用于测试代码。
Raj*_*tty 24
获取上下文
val context = LocalContext.current
Run Code Online (Sandbox Code Playgroud)
然后使用上下文获取活动。创建一个扩展函数,并使用您的上下文调用此扩展函数,例如context.getActivity()。
fun Context.getActivity(): AppCompatActivity? {
var currentContext = this
while (currentContext is ContextWrapper) {
if (currentContext is AppCompatActivity) {
return currentContext
}
currentContext = currentContext.baseContext
}
return null
}
Run Code Online (Sandbox Code Playgroud)
小智 13
internal fun Context.findActivity(): Activity {
var context = this
while (context is ContextWrapper) {
if (context is Activity) return context
context = context.baseContext
}
throw IllegalStateException("Permissions should be called in the context of an Activity")
}
Run Code Online (Sandbox Code Playgroud)
@Composable
fun composableFunc(){
val context = LocalContext.current
val activity = context.findActivity()
}
Run Code Online (Sandbox Code Playgroud)
Ji *_*bin 10
您可以通过Context创建.ActivityLocalActivity
val LocalActivity = staticCompositionLocalOf<ComponentActivity> {
noLocalProvidedFor("LocalActivity")
}
private fun noLocalProvidedFor(name: String): Nothing {
error("CompositionLocal $name not present")
}
Run Code Online (Sandbox Code Playgroud)
用法:
CompositionLocalProvider(LocalActivity provides this) {
val activity = LocalActivity.current
// your content
}
Run Code Online (Sandbox Code Playgroud)
小智 5
此扩展函数允许您指定想要获取的活动:
inline fun <reified Activity : ComponentActivity> Context.getActivity(): Activity? {
return when (this) {
is Activity -> this
else -> {
var context = this
while (context is ContextWrapper) {
context = context.baseContext
if (context is Activity) return context
}
null
}
}
}
Run Code Online (Sandbox Code Playgroud)
例子:
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent { HomeScreen() }
}
}
@Composable
fun HomeScreen() {
val activity = LocalContext.current.getActivity<MainActivity>()
}
Run Code Online (Sandbox Code Playgroud)
小智 1
从可组合函数中获取活动被认为是一种不好的做法,因为您的可组合项不应与应用程序的其余部分紧密耦合。除此之外,紧密耦合会阻止您对可组合项进行单元测试,并且通常会使重用变得更加困难。
查看您的代码,您似乎正在从可组合项中请求权限。同样,这不是您想要在可组合项中执行的操作,因为可组合函数可以像每帧一样频繁地运行,这意味着您将在每帧中继续调用该函数。
相反,请在活动中设置相机权限,并(通过参数)传递可组合项渲染像素所需的任何信息。
| 归档时间: |
|
| 查看次数: |
2249 次 |
| 最近记录: |