android - 如何使用共享元素转换来缩放 TextView ?

标签 android android-5.0-lollipop shared-element-transition activity-transition

我能够使用 ActivityOptions.makeSceneTransitionAnimation 让 TextViews 在两个 Activity 之间完美转换。但是,我想让文本在转换时按比例放大。我可以看到 material design example放大联系人卡片转换中的文本“Alphonso Engelking”。

我尝试在目标 TextView 上设置缩放属性并使用 changeTransform 共享元素转换,但它没有缩放,并且文本最终在转换时被截断。

如何使用共享元素转换来缩放 TextView?

最佳答案

编辑:

正如 Kiryl Tkach 在下面的评论中指出的那样,this Google I/O talk 中描述了一个更好的解决方案。 .


您可以创建一个自定义过渡,以动画化 TextView 的文本大小,如下所示:

public class TextSizeTransition extends Transition {
    private static final String PROPNAME_TEXT_SIZE = "alexjlockwood:transition:textsize";
    private static final String[] TRANSITION_PROPERTIES = { PROPNAME_TEXT_SIZE };

    private static final Property<TextView, Float> TEXT_SIZE_PROPERTY =
            new Property<TextView, Float>(Float.class, "textSize") {
                @Override
                public Float get(TextView textView) {
                    return textView.getTextSize();
                }

                @Override
                public void set(TextView textView, Float textSizePixels) {
                    textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSizePixels);
                }
            };

    public TextSizeTransition() {
    }

    public TextSizeTransition(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    public String[] getTransitionProperties() {
        return TRANSITION_PROPERTIES;
    }

    @Override
    public void captureStartValues(TransitionValues transitionValues) {
        captureValues(transitionValues);
    }

    @Override
    public void captureEndValues(TransitionValues transitionValues) {
        captureValues(transitionValues);
    }

    private void captureValues(TransitionValues transitionValues) {
        if (transitionValues.view instanceof TextView) {
            TextView textView = (TextView) transitionValues.view;
            transitionValues.values.put(PROPNAME_TEXT_SIZE, textView.getTextSize());
        }
    }

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

        Float startSize = (Float) startValues.values.get(PROPNAME_TEXT_SIZE);
        Float endSize = (Float) endValues.values.get(PROPNAME_TEXT_SIZE);
        if (startSize == null || endSize == null || 
            startSize.floatValue() == endSize.floatValue()) {
            return null;
        }

        TextView view = (TextView) endValues.view;
        view.setTextSize(TypedValue.COMPLEX_UNIT_PX, startSize);
        return ObjectAnimator.ofFloat(view, TEXT_SIZE_PROPERTY, startSize, endSize);
    }
}

由于更改 TextView 的文本大小会导致其布局范围在动画过程中发生变化,因此要使过渡正常工作将比简单地抛出 ChangeBounds 过渡到相同的 TransitionSet。您需要做的是在 SharedElementCallback 中手动测量/布局 View 的最终状态。

我在 GitHub 上发布了一个示例项目这说明了这个概念(请注意,该项目定义了两种 Gradle 产品风格......一种使用 Activity Transitions,另一种使用 Fragment Transitions)。

关于android - 如何使用共享元素转换来缩放 TextView ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26599824/

相关文章:

java - Android Lollipop 设计问题

Nexus 5 (Lollipop) 上的 Android 媒体录制失败

java - ViewPager 中的 fragment 和新 fragment 之间的共享元素转换

android - onPostExecute 不会被调用

android - 检查查看器以在 Android Lollipop 中打开文件

android - 是否有用于 Fragment 转换的 "setSharedElementsUseOverlay()"方法?

android - 配置更改后共享元素返回/重新进入转换中断

android - 重叠阴影效果保留在 Navigation Drawer 的 NavigationView 上

android - 尝试从 URI 启动时出现 "Exported activity does not require permission"

android - app 和 uri 的内部存储