Muchos desarrolladores se han onActivityResult
quejado durante mucho tiempo: la necesidad de definir resultCode
y requestCode
utilizar engorrosos y propensos a errores. Ahora el KTX recién lanzado ActivityResultContract
puede resolver mucho los problemas anteriores
Uso básico
antes de
onActivityResult
Escritura tradicional
class MainActivity : AppCompatActivity() {
companion object {
private const val REQUEST_CODE = 1234
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
button_open.setOnClickListener {
startActivityForResult(
SecondActivity.createIntent(this),
REQUEST_CODE
)
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
Log.d("MainActivity", "requestCode: $requestCode, resultCode: $resultCode, data: $data")
}
}
SecondActivity debe ser requerido antes de terminarsetResult
setResult(Activity.RESULT_OK, intent)
finish()
Después
Introducir gradle
implementation "androidx.activity:activity-ktx:$latest_vsersion"
or
implementation "androidx.fragment:fragment-ktx:$latest_vsersion"
class MainActivity : AppCompatActivity() {
private val launcher: ActivityResultLauncher<Intent> =
registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
activityResult ->
Log.d("MainActivity", activityResult.toString())
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
button_open.setOnClickListener {
launcher.launch(SecondActivity.createIntent(this))
}
}
}
Elimina la molesta resultCode
suma requestCode
, el código es más elegante
Otras escenas
Vea cómo usar ActivityResultContract en varios escenarios comunes:
Seleccionar un documento
Abra el administrador de archivos, seleccione la imagen y regrese uri
, primero mire la implementación basada en onActivityResult:
class MainActivity : AppCompatActivity() {
companion object {
private const val REQUEST_CODE_CHOOSER = 1234
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
button_get_content.setOnClickListener {
startActivityForResult(
Intent(Intent.ACTION_GET_CONTENT).apply {
addCategory(Intent.CATEGORY_OPENABLE)
type = "image/*"
},
REQUEST_CODE_CHOOSER
)
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == REQUEST_CODE_CHOOSER && resultCode == Activity.RESULT_OK) {
Log.d("MainActivity", "uri: ${
data?.data}")
}
}
}
Después de la implementación basada en ActivityResultContracts:
class MainActivity : AppCompatActivity() {
private val launcher = registerForActivityResult(ActivityResultContracts.GetContent()) {
uri ->
Log.d("MainActivity", "uri: $uri")
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
button_get_content.setOnClickListener {
launcher.launch("image/*")
}
}
}
ActivityResultContracts.GetContent
Es uno de varios contratos preestablecidos por el sistema: por
supuesto, además de los preestablecidos anteriores Contracts
, también puede ActivityResultContracts
personalizar sus propios contratos heredando
Solicitud de permiso
El proceso de requestPermission y startActivityForResult es similar:
//权限请求
ActivityCompat.requestPermissions(this, arrayOf(WRITE_EXTERNAL_STORAGE), REQUEST_CODE)
//返回结果
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<out String>,
grantResults: IntArray
) {
if (requestCode == REQUEST_CODE) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this, "result: granted", Toast.LENGTH_LONG).show()
}
return
}
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
}
Implementación basada en ActivityResultContract:
// 设置回调
private val launcher = registerForActivityResult(RequestPermission()) {
if (it) {
Toast.makeText(this, "result: granted", Toast.LENGTH_LONG).show()
}
}
// 请求权限
launcher.launch(WRITE_EXTERNAL_STORAGE)
Principio de realización
El principio de ActivityResultContract es relativamente simple, los estudiantes interesados pueden referirse a la comprensión profunda de ActivityResultContracts