在之前的文章中,我们通过动画实现了这个,具体可以查看【Android 动画】动画详解之仿微信查看大图效果(四),这里,我们用过度动画来实现。

什么是共享元素?

它是Android 5.0新加入的一种过度动画,主要用于2个activity之间,可以共享某些控件,实现无缝转场的动画。

如何使用?

1.为共享元素指定统一的 transition name 2.启动 Activity 时带上共享元素参数

效果图

录制的gif 不是很流畅,实际效果还是很流畅的

首先,我们需要一个九宫格,9张图片

        list = new ArrayList<>();list.add("http://img1.imgtn.bdimg.com/it/u=4206294871,879077254&fm=26&gp=0.jpg");list.add("http://img1.imgtn.bdimg.com/it/u=1901690610,3955011377&fm=200&gp=0.jpg");list.add("http://img3.imgtn.bdimg.com/it/u=1546158593,2358526642&fm=200&gp=0.jpg");list.add("http://img0.imgtn.bdimg.com/it/u=3792909229,2321547963&fm=200&gp=0.jpg");list.add("http://img4.imgtn.bdimg.com/it/u=1621655683,865218969&fm=200&gp=0.jpg");list.add("http://img5.imgtn.bdimg.com/it/u=4286838121,1364454560&fm=26&gp=0.jpg");list.add("http://img5.imgtn.bdimg.com/it/u=551944592,1654216059&fm=26&gp=0.jpg");list.add("http://img1.imgtn.bdimg.com/it/u=2550323596,2167297465&fm=200&gp=0.jpg");list.add("http://img4.imgtn.bdimg.com/it/u=952962361,1269259737&fm=26&gp=0.jpg");wxAdapter = new WxAdapter(list);rvWx2.setLayoutManager(new GridLayoutManager(WX2Activity.this, 3));rvWx2.setAdapter(wxAdapter);wxAdapter.bindToRecyclerView(rvWx2);
复制代码

WxAdapter,这里使用的是 BaseRecyclerViewAdapterHelper

    class WxAdapter extends BaseQuickAdapter<String, BaseViewHolder> {public WxAdapter(List<String> list) {super(R.layout.item_wx2, list);}@Overrideprotected void convert(BaseViewHolder helper, String item) {ImageView iv_img = helper.getView(R.id.iv_wx_img);Glide.with(mContext).load(item).apply(new RequestOptions().centerCrop()).into(iv_img);}}
复制代码

item_wx2.xml,请注意这里的指定了transitionName,这个可以自定义,只需和目标view统一即可

<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"android:layout_width="match_parent"android:layout_height="wrap_content"><ImageViewandroid:id="@+id/iv_wx_img"android:layout_width="match_parent"android:transitionName="share"android:layout_height="0dp"app:layout_constraintDimensionRatio="1:1" /></android.support.constraint.ConstraintLayout>
复制代码

当点击图片时,我们需要跳转至查看大图页面

  wxAdapter.setOnItemClickListener(new BaseQuickAdapter.OnItemClickListener() {@Overridepublic void onItemClick(BaseQuickAdapter adapter, View view, int position) {ImageView iv = view.findViewById(R.id.iv_wx_img);if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {share(iv, position);}}});
复制代码

此处的share 需与之前布局保持一致

@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)private void share(View view, int position) {Intent intent = new Intent(WX2Activity.this, Img2Activity.class);intent.putStringArrayListExtra(Img2Activity.IMG_KEY, list);intent.putExtra(Img2Activity.IMG_POSITION, position);Bundle bundle = ActivityOptions.makeSceneTransitionAnimation(this, view, "share").toBundle();startActivity(intent, bundle);}
复制代码

Img2Activity ,这里我们使用RecyclerView+PagerSnapHelper,关于PagerSnapHelper,在之前的文章中,已经说过,这里不再细述。具体可以查看【Android 进阶】仿抖音系列之翻页上下滑切换视频(四)

 private void initView() {imgList = getIntent().getStringArrayListExtra(IMG_KEY);enterPosition = getIntent().getIntExtra(IMG_POSITION, 0);snapHelper = new PagerSnapHelper();snapHelper.attachToRecyclerView(rvPreview);imgAdapter = new ImgAdapter(imgList);rvPreview.setLayoutManager(new LinearLayoutManager(Img2Activity.this, LinearLayoutManager.HORIZONTAL, false));rvPreview.setAdapter(imgAdapter);imgAdapter.bindToRecyclerView(rvPreview);rvPreview.scrollToPosition(enterPosition);
}
复制代码

这里,取出之前传递的值,并初始化 ImgAdapter

    class ImgAdapter extends BaseQuickAdapter<String, BaseViewHolder> {public ImgAdapter(List<String> list) {super(R.layout.item_img, list);}@Overrideprotected void convert(BaseViewHolder helper, String item) {ImageView iv_img = helper.getView(R.id.iv_img);Glide.with(mContext).load(item).into(iv_img);}}
复制代码

item_imgtransitionName 需要与之前保持一致,此处PhotoView支持手势放大,不需要的可以用ImageView代替

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"android:layout_width="match_parent"android:layout_height="match_parent"><com.ch.animdemo.phoneView.PhotoViewandroid:id="@+id/iv_img"android:layout_width="0dp"android:layout_height="0dp"android:transitionName="share"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintLeft_toLeftOf="parent"app:layout_constraintRight_toRightOf="parent"app:layout_constraintTop_toTopOf="parent" /></android.support.constraint.ConstraintLayout>
复制代码

到这里,基本效果已经实现了,不过还有2个坑要填。 1.当我们运行时会发现,会出现Img2Activity出现是小图,而不是我们期望的大图。 这是因为,加载网络图片需要时间,如果过度动画执行太快,图片还没有加载出来,而glide缓存策略是按加载的尺寸+图片路径缓存,由于之前缓存过小图,所以当大图没有加载出来时,会显示小图。 所以我们刚进入界面时,需要延迟过度动画的执行

  // 延迟共享动画的执行postponeEnterTransition();
复制代码

当图片加载完成时,才继续执行过度动画

  //图片加载完成的回调中,启动过渡动画startPostponedEnterTransition();
复制代码

2.当我们滑动大图界面,然后返回时会发现,返回动画依然是进入大图界面的位置,所以我们需要判断,如果滑动过,就需要更新返回时的位置。 修改之前Img2Activityinitview方法如下:

    private void initView() {// 延迟共享动画的执行postponeEnterTransition();imgList = getIntent().getStringArrayListExtra(IMG_KEY);enterPosition = getIntent().getIntExtra(IMG_POSITION, 0);currentPosition = enterPosition;snapHelper = new PagerSnapHelper() {@Overridepublic int findTargetSnapPosition(RecyclerView.LayoutManager layoutManager, int velocityX, int velocityY) {currentPosition = super.findTargetSnapPosition(layoutManager, velocityX, velocityY);return currentPosition;}};snapHelper.attachToRecyclerView(rvPreview);imgAdapter = new ImgAdapter(imgList);rvPreview.setLayoutManager(new LinearLayoutManager(Img2Activity.this, LinearLayoutManager.HORIZONTAL, false));rvPreview.setAdapter(imgAdapter);imgAdapter.bindToRecyclerView(rvPreview);rvPreview.scrollToPosition(enterPosition);}
复制代码

finishAfterTransition重写finishAfterTransition,传递最新的position

@Overridepublic void finishAfterTransition() {Intent intent = new Intent();if (enterPosition == currentPosition) {//没有改变intent.putExtra(IMG_CURRENT_POSITION, -1);} else {intent.putExtra(IMG_CURRENT_POSITION, currentPosition);}setResult(RESULT_OK, intent);super.finishAfterTransition();}
复制代码

然后在WX2Activity中处理

@Overridepublic void onActivityReenter(int resultCode, Intent data) {if (resultCode == RESULT_OK && data != null) {int exitPos = data.getIntExtra(Img2Activity.IMG_CURRENT_POSITION, -1);final View exitView = getExitView(exitPos);if (exitView != null) {ActivityCompat.setExitSharedElementCallback(this, new SharedElementCallback() {@Overridepublic void onMapSharedElements(List<String> names, Map<String, View> sharedElements) {names.clear();sharedElements.clear();names.add(ViewCompat.getTransitionName(exitView));sharedElements.put(Objects.requireNonNull(ViewCompat.getTransitionName(exitView)), exitView);setExitSharedElementCallback(new SharedElementCallback() {});}});}}}private View getExitView(int position) {if (position == -1) {return null;}if (wxAdapter != null) {return wxAdapter.getViewByPosition(position, R.id.iv_wx_img);}return null;}
复制代码

最后献上源码 github

你的认可,是我坚持更新博客的动力,如果觉得有用,就请点个赞,谢谢

【Android视图效果】共享元素实现仿微信查看大图效果相关推荐

  1. android仿微信的activity平滑水平切换动画,Android实现简单底部导航栏 Android仿微信滑动切换效果...

    Android实现简单底部导航栏 Android仿微信滑动切换效果 发布时间:2020-10-09 19:48:00 来源:脚本之家 阅读:96 作者:丶白泽 Android仿微信滑动切换最终实现效果 ...

  2. Android仿微信头像放大效果

    android仿微信头像放大效果,使用Dialog+Gallery 实现 1.  dialog显示时的动画style,动画可以自己根据喜好自己设置,此处动画xml省略 <style name=& ...

  3. php仿微信语音条,html5的audio实现高仿微信语音播放效果

    前言 之前做过一个微信的项目,专家回复可以录音,然后储存成mp3格式,前台可以获取mp3,客户可以在线试听mp3录音效果,今天就简单分享一下这个效果如何实现,及实现思路和方法! 效果图 前台大体呈现效 ...

  4. html5的audio实现高仿微信语音播放效果

    效果图 前台大体呈现效果图如下: 点击就可以播放mp3格式的录音.点击另外一个录音,当前录音停止! 思路 关于播放动画,这个很简单,我们可以用css3的逐帧动画来实现.关于逐帧动画,我之前的文章也写过 ...

  5. 仿微信查看图片、H5的图片轮播插件PhotoSwipe、SuperSlide

    刚好有项目需求,也整理了几款H5的插件 一.PhotoSwipe 仿微信查看图片,两指放大缩小,左右滑动切换上下一张图片. 二.PhotoSwipe的改良版 三.SuperSlider基础版 多种图片 ...

  6. JQuery实现点击缩略图查看大图效果

    点击缩略图查看大图效果,这里存在一个如何获取图片真实大小的问题.在手机端页面,插入的图片大小都是按照图片的原始尺寸在展示的,如果图片太大完全超出手机的屏幕尺寸 ,我们的bootstrap响应式针对图片 ...

  7. Android 天气APP(十三)仿微信弹窗(右上角加号点击弹窗效果)、自定义背景图片、UI优化调整

    上一篇:Android 天气APP(十二)空气质量.UI优化调整 天气预报详情,逐小时预报详情 新版------------------- 一.适配器点击监听 二.页面实现 三.天气预报详情弹窗 四. ...

  8. php仿微信底部菜单,Android实现简单底部导航栏 Android仿微信滑动切换效果

    Android仿微信滑动切换最终实现效果: 大体思路: 1. 主要使用两个自定义View配合实现; 底部图标加文字为一个自定义view,底部导航栏为一个载体,根据需要来添加底部图标; 2. 底部导航栏 ...

  9. android滑动菜单图标,Android实现简单底部导航栏 Android仿微信滑动切换效果

    Android仿微信滑动切换最终实现效果: 大体思路: 1. 主要使用两个自定义View配合实现; 底部图标加文字为一个自定义view,底部导航栏为一个载体,根据需要来添加底部图标; 2. 底部导航栏 ...

最新文章

  1. Git学习记录(一)
  2. BootStrap selectpicker
  3. Spring Boot 一般层级简介
  4. Ubuntu 16.04上安装SkyEye及测试
  5. php 字符串比较txt,PHP读到txt中文字符串比较失败
  6. JAVA对时间的几个处理小方法
  7. 上一家单位离职的原因_员工离职再入职,专项附加扣除该如何变更?
  8. “AI+遥感”产品研究现状
  9. 关于Euler-Poisson积分的几种解法
  10. 使用fiddler代理,手机无法上网
  11. 罗森伯格成功布线五星蕴海建国饭店
  12. presentation健身主题HTML,如何用英文做presentation
  13. git仓库-客户端软件安装配置过程
  14. extjs6 清除grid中combo列的值
  15. safari浏览网页打开速度很慢如何解决
  16. R语言基于ARCH模型股价波动率建模
  17. 【课程】07 河口水循环
  18. AWS 中文入门开发教学 35- MySQL@RDS - 建立MySQL数据库服务
  19. 腾讯云数据库联手宇信科技发布联合方案,全面助力金融科技安全可控
  20. 在美国读书的体会 [转]

热门文章

  1. Spring Cloud【Finchley】-15 查看Zuul的路由端点和过滤器
  2. Oracle查询优化-04插入、更新与删除数据
  3. 小班计算机游戏教案,幼儿园小班游戏教案
  4. Java实现List中某个对象属性中的字符串参数首字母进行排序
  5. @Transactional事务的使用和注意事项及其属性
  6. python mql4_可以转发文章不?老外用随机森林预测外汇分钟涨跌准确率高达85%。求高手用python重写。...
  7. java 判断int是几位_快速判断一个int值是几位数
  8. php intl make 错误,无法在Debian上为php安装’intl’扩展名
  9. mybatis学习6复杂查询之一对多的处理
  10. 【ros】4.rosbag的相关用法