如何在其他类中实现并使用registerForActivityResult?
复用ActivityResultLauncher逻辑(类似多按钮OnClickListener)
问题场景
当前把ActivityResultLauncher的注册逻辑写在MainActivity的onCreate()方法中,希望像多按钮共用OnClickListener那样,把这部分选择文件并处理路径的逻辑抽出来,在其他类或多个按钮中复用。
实现方案
1. 定义结果回调接口
先定义一个接口,用来传递选择后的路径结果,让不同调用方可以自定义处理逻辑:
public interface OnPathSelectedListener { void onPathSelected(String path); }
2. 封装Launcher工具类
把注册和启动逻辑抽成独立的工具类,依托Activity的生命周期完成注册,同时暴露回调和启动方法:
import android.app.Activity; import android.content.Intent; import android.net.Uri; import androidx.activity.result.ActivityResult; import androidx.activity.result.ActivityResultLauncher; import androidx.activity.result.contract.ActivityResultContracts; import androidx.appcompat.app.AppCompatActivity; public class FilePickerLauncher { private final ActivityResultLauncher<Intent> launcher; private OnPathSelectedListener pathListener; // 传入Activity完成Launcher注册 public FilePickerLauncher(AppCompatActivity activity) { launcher = activity.registerForActivityResult( new ActivityResultContracts.StartActivityForResult(), result -> { if (result.getResultCode() == Activity.RESULT_OK && result.getData() != null) { Uri uri = result.getData().getData(); if (uri != null) { // 处理路径逻辑和原代码一致 String path = "/" + uri.getPath().substring(uri.getPath().indexOf(":") + 1); // 触发外部回调 if (pathListener != null) { pathListener.onPathSelected(path); } } } } ); } // 设置结果回调 public void setOnPathSelectedListener(OnPathSelectedListener listener) { this.pathListener = listener; } // 对外暴露启动文件选择器的方法 public void launchFilePicker() { Intent pickerIntent = new Intent(Intent.ACTION_GET_CONTENT); pickerIntent.setType("*/*"); // 可根据需求修改文件类型 launcher.launch(pickerIntent); } }
3. 在Activity中复用逻辑
和多按钮共用OnClickListener的逻辑类似,只需初始化一次工具类,不同按钮点击时设置各自的回调并启动选择器:
import android.os.Bundle; import android.widget.Button; import android.widget.Toast; import androidx.appcompat.app.AppCompatActivity; public class MainActivity extends AppCompatActivity { private FilePickerLauncher filePickerLauncher; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 初始化工具类,绑定当前Activity生命周期 filePickerLauncher = new FilePickerLauncher(this); // 第一个按钮复用逻辑 Button btnPickFile1 = findViewById(R.id.btn_pick_file1); btnPickFile1.setOnClickListener(v -> { filePickerLauncher.setOnPathSelectedListener(path -> { Toast.makeText(MainActivity.this, "按钮1选中路径:" + path, Toast.LENGTH_SHORT).show(); // 这里写按钮1对应的业务逻辑 }); filePickerLauncher.launchFilePicker(); }); // 第二个按钮复用逻辑 Button btnPickFile2 = findViewById(R.id.btn_pick_file2); btnPickFile2.setOnClickListener(v -> { filePickerLauncher.setOnPathSelectedListener(path -> { Toast.makeText(MainActivity.this, "按钮2选中路径:" + path, Toast.LENGTH_SHORT).show(); // 这里写按钮2对应的业务逻辑 }); filePickerLauncher.launchFilePicker(); }); } }
注意事项
- 必须依托具备生命周期的组件(Activity/Fragment)注册
ActivityResultLauncher,工具类中传入AppCompatActivity或Fragment即可 - 如果在Fragment中使用,只需把工具类的构造参数换成
Fragment,调用fragment.registerForActivityResult()即可 - 每次启动前设置回调,避免不同按钮的回调相互干扰
内容的提问来源于stack exchange,提问作者Lore
相关产品推荐
相关产品推荐

