Fragment中使用Picasso.get()遇参数问题:getActivity()/getContext()无效
解决Fragment中Picasso加载图片的问题
嘿,我来帮你搞定这个Picasso在Fragment里的加载问题!首先得澄清一个关键点:新版Picasso的Picasso.get()方法根本不需要传入任何参数,你之前尝试传getActivity()或者getContext()是混淆了新旧版本的用法啦。
先搞清楚Picasso的版本差异
- 旧版本Picasso(2.5.x及更早):需要用
Picasso.with(Context)来获取实例 - 新版本Picasso(2.71828+):用
Picasso.get()直接获取单例,它会自动使用应用的全局Context,不需要手动传入
那你代码里加载失败的原因大概率不是Picasso获取实例的问题,而是其他细节没处理好,下面一步步给你解决:
1. 先确认依赖是否正确
确保你的build.gradle(Module级别)里引入的是新版Picasso:
implementation 'com.squareup.picasso:picasso:2.71828'
2. 必须处理存储权限
你是加载本地选中的图片,Android 6.0(API 23)及以上需要动态申请读取外部存储权限,这是很多人忽略的点!给你的代码补全权限逻辑:
第一步:修改openFileChooser方法,先检查权限
private void openFileChooser(){ // 检查是否有读取存储的权限 if (ContextCompat.checkSelfPermission(requireContext(), Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { // 没有权限,申请权限 ActivityCompat.requestPermissions(requireActivity(), new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 100); // 自定义请求码 return; } // 有权限,打开文件选择器 Intent intent = new Intent(); intent.setType("image/*"); intent.setAction(Intent.ACTION_GET_CONTENT); startActivityForResult(intent, PICK_IMAGE_REQUEST); }
第二步:处理权限申请结果
在Fragment里重写这个方法:
@Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == 100) { if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { // 用户同意权限,重新打开文件选择器 openFileChooser(); } else { // 用户拒绝权限,给个提示 Toast.makeText(requireContext(), "需要读取存储权限才能选择图片哦", Toast.LENGTH_SHORT).show(); } } }
3. 修正Picasso的加载代码(加调试占位图)
给你的onActivityResult加个错误和加载占位图,方便调试,同时确保逻辑严谨:
@Override public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); // 注意:这里要用Activity.RESULT_OK,避免找不到常量的问题 if (requestCode == PICK_IMAGE_REQUEST && resultCode == Activity.RESULT_OK && data != null && data.getData() != null){ imageUri = data.getData(); // 新版Picasso直接用get(),不需要传Context Picasso.get() .load(imageUri) .placeholder(R.drawable.loading_img) // 加载中显示的占位图(自己添加资源) .error(R.drawable.error_img) // 加载失败显示的占位图 .into(winnerPicture); } }
4. Fragment中获取Context的正确姿势
虽然新版Picasso不需要传Context,但如果以后用旧版或者其他需要Context的场景,推荐用requireContext()而不是getActivity():
requireContext():会返回非空的Context,如果Fragment已经detached会抛出异常,避免空指针getActivity():可能返回null(比如Fragment和Activity解绑时)
额外优化:保存图片Uri避免屏幕旋转丢失
如果用户旋转屏幕,Fragment会重建,之前选中的图片会消失,所以可以在onSaveInstanceState里保存Uri:
@Override public void onSaveInstanceState(@NonNull Bundle outState) { super.onSaveInstanceState(outState); if (imageUri != null) { outState.putString("selected_image_uri", imageUri.toString()); } } // 在onCreateView里恢复Uri @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View view = inflater.inflate(R.layout.manager_eotm, container, false); // 初始化你的控件... uploadWinner = view.findViewById(R.id.boxUpload); month = view.findViewById(R.id.etMonth); winnerPicture = view.findViewById(R.id.ivWinner); progressBar = view.findViewById(R.id.progressBar); ChooseWinner = view.findViewById(R.id.btnChooseWinner); // 恢复之前选中的图片 if (savedInstanceState != null) { String uriStr = savedInstanceState.getString("selected_image_uri"); if (uriStr != null) { imageUri = Uri.parse(uriStr); Picasso.get().load(imageUri).into(winnerPicture); } } return view; }
按照上面的步骤修改后,你的图片应该就能正常加载啦!
内容的提问来源于stack exchange,提问作者Nessan Lenehan
相关产品推荐
相关产品推荐

