IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 游戏开发 -> 【Android】共享元素 share elements TextView颜色大小动画过度 -> 正文阅读

[游戏开发]【Android】共享元素 share elements TextView颜色大小动画过度

谷歌官方文档 给了一个 通过共享元素启动Activity的Demo
Demo很流畅,图片过渡很自然,但是由于两个页面的TextView大小不同(颜色不同会更加突兀),在动画开始和结束的时候TextView变化很突兀。
这篇博客在共享元素的基础上进一步自定义TextView的动画,使之过度更加自然

谷歌Demo效果展示
在这里插入图片描述
改进后效果展示
在这里插入图片描述

官方调用

这里不分析源码是怎么实现的,因为我还没彻底搞懂……
所以只简单贴一下调用方法
从ActivityA启动ActivityB时设置共享元素imageview_item和textview_name
ActivityA.java

Intent intent = new Intent(MainActivity.this, DetailActivity.class);
            intent.putExtra(DetailActivity.EXTRA_PARAM_ID, item.getId());
            ActivityOptionsCompat activityOptions = ActivityOptionsCompat.makeSceneTransitionAnimation(
                    MainActivity.this,
					new Pair<>(view.findViewById(R.id.imageview_item),
                            DetailActivity.VIEW_NAME_HEADER_IMAGE),
                    new Pair<>(view.findViewById(R.id.textview_name),
                            DetailActivity.VIEW_NAME_HEADER_TITLE)
            );
            ActivityCompat.startActivity(MainActivity.this, intent, activityOptions.toBundle());

同样在ActivityB中也设置这两个共享元素

    private ImageView mHeaderImageView;
    private TextView mHeaderTitle;
    @Override
    protected void onCreated(Bundle saveInstanceState){
    	...
		HeaderImageView = findViewById(R.id.imageview_header);
        mHeaderTitle = findViewById(R.id.textview_title);	
        ViewCompat.setTransitionName(mHeaderImageView, VIEW_NAME_HEADER_IMAGE);
        ViewCompat.setTransitionName(mHeaderTitle, VIEW_NAME_HEADER_TITLE);
        ...
    }

就这么简单。具体代码去看谷歌Demo

但是因为Demo中的textview这个共享元素在两个页面的字体不一样,所以过度很突兀

页面跳转共享元素动画实际上是先加载好ActivityB的textview,然后开始动画,所以看到在进入动画的时候,textview的字体样式突然变成了ActivityB的样式

自定义Transition

ActivityA的代码不变
ActivityB的代码略作修改

private ImageView mHeaderImageView;
private TextView mHeaderTitle;

@Override
protected void onCreate(Bundle savedInstanceState) {
	...
	mHeaderImageView = findViewById(R.id.imageview_header);
	mHeaderTitle = findViewById(R.id.textview_title);
	
	ViewCompat.setTransitionName(mHeaderImageView, VIEW_NAME_HEADER_IMAGE);
	ViewCompat.setTransitionName(mHeaderTitle, VIEW_NAME_HEADER_TITLE);
	// 配置启动动画的属性
	configEnterExitAnimation(true);
	// 推迟动画启动
	postponeEnterTransition();
	... // 这里加载所需的数据
	// 数据加载好后启动动画
	startPostponedEnterTransition();
}

配置enter和exit的动画属性

private void configEnterExitAnimation(boolean isEnter) {
	// 文字大小和颜色动画
	TextviewTransition textviewTransition = new TextviewTransition(isEnter);
	textviewTransition.addTarget(R.id.textview_title);
	// 文字位置动画
	ChangeBounds textviewChangeBounds = new ChangeBounds();
	textviewChangeBounds.addTarget(R.id.textview_title);
	// ImageView位置动画
	ChangeBounds imageChangeBounds = new ChangeBounds();
	imageChangeBounds.addTarget(VIEW_NAME_HEADER_IMAGE);
	
	TransitionSet set = new TransitionSet()
	   .addTransition(textviewTransition)
	   .addTransition(textviewChangeBounds)
	   .addTransition(imageChangeBounds)
	   .setDuration(1500); // 这里把动画时长调成1.5s,过度效果更明显
	
	this.getWindow().setSharedElementEnterTransition(set);
}

自定义的TextView的Transition类,用来管理文字颜色和大小的动画过度

class TextviewTransition extends Transition {

	private boolean mIsEnter = true;	

    public TextviewTransition(boolean isEnter) {
        mIsEnter = isEnter;
    }

    @Override
    public void captureStartValues(TransitionValues transitionValues) {
    }

    @Override
    public void captureEndValues(TransitionValues transitionValues) {
    }

    @Override
    public Animator createAnimator(ViewGroup sceneRoot, TransitionValues startValues, TransitionValues endValues) {
        if (startValues == null || endValues == null) {
            return null;
        }
        return createEnterAnimator(startValues, endValues);
    }

    private Animator createEnterAnimator(TransitionValues startValues, TransitionValues endValues) {
    	// 文字大小过度动画
        ObjectAnimator textSizeAnimator = ObjectAnimator.ofFloat((TextView) startValues.view,
                new Property<TextView, Float>(Float.class, "textSize") {
                    @Override
                    public void set(TextView object, Float value) {
                        object.setTextSize(TypedValue.COMPLEX_UNIT_PX, value);
                    }

                    @Override
                    public Float get(TextView object) {
                        return object.getTextSize();
                    }
                },
                mIsEnter ? getResources().getDimensionPixelOffset(R.dimen.text_size_start) :
                        getResources().getDimensionPixelOffset(R.dimen.text_size_end),
                mIsEnter ? getResources().getDimensionPixelOffset(R.dimen.text_size_end) :
                        getResources().getDimensionPixelOffset(R.dimen.text_size_start)

        );
		// 文字颜色过度动画
        ObjectAnimator textColorAnimator = ObjectAnimator.ofArgb((TextView) startValues.view,
                new Property<TextView, Integer>(Integer.class, "textColor") {
                    @Override
                    public void set(TextView object, Integer value) {
                        object.setTextColor(value);
                    }

                    @Override
                    public Integer get(TextView object) {
                        return object.getCurrentTextColor();
                    }
                },
                mIsEnter ? getResources().getColor(R.color.start_color, null) :
                        getResources().getColor(R.color.end_color, null),
                mIsEnter ? getResources().getColor(R.color.end_color, null) :
                        getResources().getColor(R.color.start_color, null)
        );

        AnimatorSet animatorSet = new AnimatorSet();
        animatorSet.playTogether(textSizeAnimator, textColorAnimator);
        return animatorSet;
    }
}

简单分析下就是TextviewTransition类中包含了两个动画,一个是TextView的大小,另一个是TextView的颜色
然后整体的页面过度动画TransitionSet又包含三个:TextView大小颜色动画(TextviewTransition)、TextView大小和位置动画ImageView大小和位置动画。这样就能在谷歌Demo的基础上让文字过度更加自然。(这里没有处理字重过度的问题 ,感兴趣可以去拓展)

ChangeBounds: View的大小与位置动画
ChangeTransform: View的缩放与旋转动画
ChangeClipBounds: View的裁剪区域(View.getClipBounds())动画
ChangeScroll: 处理View的scrollX与scrollY属性
ChangeImageTransform: 处理ImageView的ScaleType属性
参考简书

效果不是很完美(包括字重过度、动画启动结束时TextView内容换行问题),但已经实现了TextView大小和动画的过度。

项目代码已传GitHub

  游戏开发 最新文章
6、英飞凌-AURIX-TC3XX: PWM实验之使用 GT
泛型自动装箱
CubeMax添加Rtthread操作系统 组件STM32F10
python多线程编程:如何优雅地关闭线程
数据类型隐式转换导致的阻塞
WebAPi实现多文件上传,并附带参数
from origin ‘null‘ has been blocked by
UE4 蓝图调用C++函数(附带项目工程)
Unity学习笔记(一)结构体的简单理解与应用
【Memory As a Programming Concept in C a
上一篇文章      下一篇文章      查看所有文章
加:2022-03-11 22:32:23  更:2022-03-11 22:32:33 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/27 14:47:24-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码