ViewPager2适配器分享弹窗返回后item布局扁平化及跳项问题求助
问题解决方案
根因分析
- 分享逻辑未正确配置Uri临时权限,取消分享时系统权限回收触发ViewPager2异常重测量,导致item布局扁平化
- 分享生成的临时图片未做异常回收,IO波动引发ViewPager2滑动状态异常,出现自动切页现象
- 点击事件中直接持有
onBindViewHolder入参position,布局重绘后position错位放大异常表现
修复步骤
1. 修正分享Intent的权限配置
修改share_post的点击事件逻辑,给Intent添加读权限,同时使用FileProvider替代过时的MediaStore.insertImage方式(适配Android 7.0及以上系统要求),代码修改如下:
holder.share_post.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { BitmapDrawable drawable = (BitmapDrawable)holder.image_post.getDrawable(); Bitmap bitmap = drawable.getBitmap(); // 用FileProvider生成合规Uri,避免权限问题 Uri uri = getImageUri(mContext, bitmap); Intent intent = new Intent(Intent.ACTION_SEND); intent.setType("image/jpeg"); intent.putExtra(Intent.EXTRA_STREAM,uri); intent.putExtra(Intent.EXTRA_TEXT, "Playstore Link : put app link in store "); // 给目标应用授予临时Uri读取权限 intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); Intent chooser = Intent.createChooser(intent,"Share2"); ((Activity)mContext).startActivityForResult(chooser, 1001); } }); // 新增Uri生成方法 private Uri getImageUri(Context context, Bitmap bitmap) { File imagesFolder = new File(context.getCacheDir(), "images"); Uri uri = null; try { imagesFolder.mkdirs(); File file = new File(imagesFolder, "shared_image.jpeg"); FileOutputStream stream = new FileOutputStream(file); bitmap.compress(Bitmap.CompressFormat.JPEG, 90, stream); stream.flush(); stream.close(); uri = FileProvider.getUriForFile(context, context.getPackageName() + ".fileprovider", file); } catch (IOException e) { e.printStackTrace(); } return uri; }
在AndroidManifest.xml中配置FileProvider:
<provider android:name="androidx.core.content.FileProvider" android:authorities="${applicationId}.fileprovider" android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths" /> </provider>
新建res/xml/file_paths.xml文件,内容如下:
<?xml version="1.0" encoding="utf-8"?> <paths xmlns:android="http://schemas.android.com/apk/res/android"> <cache-path name="images" path="images/" /> </paths>
2. 统一使用bindingAdapterPosition获取当前item位置
所有点击事件中获取位置的逻辑都替换为holder.getBindingAdapterPosition(),避免重绘后position错位:
// 示例:修改save点击事件中的position获取逻辑 holder.save.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { int currentPos = holder.getBindingAdapterPosition(); if (currentPos == RecyclerView.NO_POSITION) return; if (mContext instanceof SavedPostActivity) { mListener.removePost(post_id,post_image,currentPos); } // 其余原有逻辑保持不变 } });
3. 关闭ViewPager2的异常测量优化
在宿主Activity初始化ViewPager2的时候添加如下配置,避免item布局被压缩:
viewPager2.requestLayout(); viewPager2.getAdapter().stateRestorationPolicy = RecyclerView.Adapter.StateRestorationPolicy.PREVENT_WHEN_EMPTY; viewPager2.setMeasureAllChildren(true);
4. 处理分享返回结果
在宿主Activity重写onActivityResult,分享流程结束后强制当前item重绘修正布局:
@Override protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == 1001) { viewPager2.getAdapter().notifyItemChanged(viewPager2.getCurrentItem()); } }
内容的提问来源于stack exchange,提问作者MonkeyNation
相关产品推荐
相关产品推荐

