【问题标题】:Transition from Button to EditText从 Button 到 EditText 的转换
【发布时间】:2018-03-18 21:56:35
【问题描述】:

我想在我的 android 中有一个 transition viewsButton 和另一个是 EditText,过渡必须像这个动画

我是这样尝试的

布局xml是

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="app.itc.org.todo.MainActivity">

    <LinearLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:weightSum="2">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"
            android:orientation="vertical"
            android:background="@android:color/white"
            android:gravity="center_horizontal|center_vertical">

            <TextView
                android:id="@+id/title_tv"
                android:text="@string/to_do"
                android:textSize="22sp"
                android:textStyle="bold"
                android:textColor="@android:color/black"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:padding="10dp"/>

            <TextView
                android:id="@+id/date_tv"
                android:textSize="16sp"
                android:textColor="@android:color/darker_gray"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content" />


        </LinearLayout>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"
            android:background="@color/colorGray"
            android:gravity="center_horizontal|center_vertical"
            android:orientation="vertical">

            <TextView
                android:text="@string/what_do_you_want_to_do_today"
                android:textSize="16sp"
                android:textColor="@android:color/darker_gray"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:padding="10dp"/>

            <TextView
                android:text="@string/start_adding_items_to_your_to_do_list"
                android:textSize="16sp"
                android:textColor="@android:color/darker_gray"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"/>


        </LinearLayout>

    </LinearLayout>

    <FrameLayout
        android:id="@+id/transitions_container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:visibility="visible">

        <Button
            android:id="@+id/add_btn"
            android:layout_width="200dp"
            android:layout_height="60dp"
            android:text="@string/add_item"
            android:textSize="18sp"
            android:paddingLeft="20dp"
            android:textColor="@android:color/white"
            android:drawableLeft="@drawable/ic_add_24dp"
            android:background="@drawable/rounded_black_bg"
            android:layout_gravity="center"/>

        <EditText
            android:id="@+id/item_input_et"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:visibility="gone"
            android:minHeight="50dp"
            android:layout_marginLeft="@dimen/margin_30dp"
            android:layout_marginRight="@dimen/margin_30dp"
            android:paddingLeft="@dimen/dimen_20dp"
            android:paddingRight="@dimen/dimen_50dp"
            android:textColor="@android:color/black"
            android:inputType="text"
            android:background="@drawable/rounded_edit_text"
            android:layout_gravity="center"/>


    </FrameLayout>

</RelativeLayout>

预览是

Java代码是

public class MainActivity extends AppCompatActivity {

    private EditText mItemInputEditText;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        TextView dateTextView = (TextView) findViewById(R.id.date_tv);

        mItemInputEditText = (EditText) findViewById(R.id.item_input_et);
        final Button addButton = (Button) findViewById(R.id.add_btn);

        final ViewGroup transitionsContainer = (ViewGroup) findViewById(R.id.transitions_container);

        mItemInputEditText.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {



                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                    TransitionSet set = new TransitionSet()
                            .addTransition(new Fade())
                            .setInterpolator(new FastOutLinearInInterpolator());

                    TransitionManager.beginDelayedTransition(transitionsContainer, set);
                }

                addButton.setVisibility(View.VISIBLE);
                mItemInputEditText.setVisibility(View.GONE);
            }
        });

        addButton.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                    TransitionSet set = new TransitionSet()
                            .addTransition(new Fade())
                            .setInterpolator(new FastOutLinearInInterpolator());

                    TransitionManager.beginDelayedTransition(transitionsContainer, set);
                }

                addButton.setVisibility(View.GONE);
                mItemInputEditText.setVisibility(View.VISIBLE);
            }

        });

        SimpleDateFormat dt = new SimpleDateFormat("EEE d MMM yyyy");
        dateTextView.setText(dt.format(new Date()));

    }
}

但是使用这段代码,结果转换是

正如您所看到的,与预期的相比,这有点奇怪,任何人都可以建议我进行一些更改以获得所需的过渡。

【问题讨论】:

  • 你想要的过渡不是淡入淡出过渡。它是ChangeBounds。 developer.android.com/reference/android/transition/… 并使用单独的场景以获得更好的过渡。
  • 请举个例子...
  • 如果您不想使用单独的场景。我建议你创建一个自定义动画师。几天前,我还尝试将浮动操作按钮转换为 CardView。过渡并没有按预期进行。所以我为我的目的创建了一个动画师。
  • @ArshadAli,你能在 github 上发布一个具有这种行为的简单项目吗?

标签: java android animation android-animation android-transitions


【解决方案1】:

Transitions API 确实是个好东西,但它不能为您解决所有问题。你还没有向过渡框架指示如何执行该动画,它怎么会理解你要执行的最终动画是什么?

我不确定仅使用 Transitions API 是否可以实现此动画。相反,您可以坚持使用标准动画 API,例如ValueAnimator.

动画由几个阶段组成。当一个按钮被点击时,你希望它变得稍微宽一些,同时也失去它的透明度。完成此操作后,您希望 EditText 进入场景并从按钮所在的宽度开始动画到其最终值。

所以,内部按钮点击监听器:

@Override public void onClick(View v) { final int from = addButton.getWidth(); final int to = (int) (from * 1.2f); // increase by 20% final LinearInterpolator interpolator = new LinearInterpolator(); ValueAnimator firstAnimator = ValueAnimator.ofInt(from, to); firstAnimator.setTarget(addButton); firstAnimator.setInterpolator(interpolator); firstAnimator.setDuration(DURATION); final ViewGroup.LayoutParams params = addButton.getLayoutParams(); firstAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { params.width = (Integer) animation.getAnimatedValue(); addButton.setAlpha(1 - animation.getAnimatedFraction()); addButton.requestLayout(); } }); firstAnimator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { // reset alpha channel addButton.setAlpha(1.0f); addButton.setVisibility(View.GONE); mItemInputEditText.setVisibility(View.VISIBLE); ValueAnimator secondAnimator = ValueAnimator.ofInt(to, editTextWidth); secondAnimator.setTarget(mItemInputEditText); secondAnimator.setInterpolator(interpolator); secondAnimator.setDuration(DURATION); final ViewGroup.LayoutParams params = mItemInputEditText.getLayoutParams(); secondAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { params.width = (Integer) animation.getAnimatedValue(); mItemInputEditText.requestLayout(); } }); secondAnimator.start(); } }); firstAnimator.start(); }

EditText 回到按钮时执行类似的操作:

@Override public void onClick(View view) { final int from = mItemInputEditText.getWidth(); final int to = (int) (from * 0.8f); final LinearInterpolator interpolator = new LinearInterpolator(); ValueAnimator firstAnimator = ValueAnimator.ofInt(from, to); firstAnimator.setTarget(mItemInputEditText); firstAnimator.setInterpolator(interpolator); firstAnimator.setDuration(DURATION); final ViewGroup.LayoutParams params = mItemInputEditText.getLayoutParams(); firstAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { params.width = (Integer) animation.getAnimatedValue(); mItemInputEditText.requestLayout(); } }); firstAnimator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { mItemInputEditText.setVisibility(View.GONE); addButton.setVisibility(View.VISIBLE); ValueAnimator secondAnimator = ValueAnimator.ofInt(to, buttonWidth); secondAnimator.setTarget(addButton); secondAnimator.setInterpolator(interpolator); secondAnimator.setDuration(DURATION); final ViewGroup.LayoutParams params = addButton.getLayoutParams(); secondAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { params.width = (Integer) animation.getAnimatedValue(); addButton.setAlpha(animation.getAnimatedFraction()); addButton.requestLayout(); } }); secondAnimator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationStart(Animator animation) { addButton.setAlpha(0.0f); } }); secondAnimator.start(); } }); firstAnimator.start(); }

editTextWidthbuttonWidth 是视图的初始大小:

private int editTextWidth, buttonWidth; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ... // `transitions_container` is the parent of both `EditText` and `Button` // Thus, posting on it ensures that both of those views are laid out when this runnable is executed findViewById(R.id.transitions_container).post(new Runnable() { @Override public void run() { editTextWidth = mItemInputEditText.getWidth(); // `mItemInputEditText` should be left visible from XML in order to get measured // setting to GONE after we have got actual width mItemInputEditText.setVisibility(View.GONE); buttonWidth = addButton.getWidth(); } }); }

这是输出:

您可以拥有带有更改的补丁文件here

【讨论】:

  • 看起来很完美。
  • 我会在我这边测试并奖励你
  • 天哪!奖励有限制,取消后我会奖励..
  • 我想问的最后一件事是how can I get add icon animated as in first gif image?
  • @ArshadAli,看起来像Animated Vector Drawable。看看ShapeShifter
【解决方案2】:

首先,更改您的布局 XML

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="app.itc.org.todo.MainActivity">

    <LinearLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:weightSum="2">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"
            android:orientation="vertical"
            android:background="@android:color/white"
            android:gravity="center_horizontal|center_vertical">

            <TextView
                android:id="@+id/title_tv"
                android:text="@string/to_do"
                android:textSize="22sp"
                android:textStyle="bold"
                android:textColor="@android:color/black"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:padding="10dp"/>

            <TextView
                android:id="@+id/date_tv"
                android:textSize="16sp"
                android:textColor="@android:color/darker_gray"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content" />


        </LinearLayout>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"
            android:background="@color/colorGray"
            android:gravity="center_horizontal|center_vertical"
            android:orientation="vertical">

            <TextView
                android:text="@string/what_do_you_want_to_do_today"
                android:textSize="16sp"
                android:textColor="@android:color/darker_gray"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:padding="10dp"/>

            <TextView
                android:text="@string/start_adding_items_to_your_to_do_list"
                android:textSize="16sp"
                android:textColor="@android:color/darker_gray"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"/>


        </LinearLayout>

    </LinearLayout>

    <FrameLayout
        android:id="@+id/transitions_container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:visibility="visible">
        <include layout="@layout/a_scene" />
    </FrameLayout>

</RelativeLayout>

然后为按钮创建您的第一个场景。 第一个场景的布局定义如下:

res/layout/a_scene.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/scene_container"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
    <Button
            android:id="@+id/add_btn"
            android:layout_width="200dp"
            android:layout_height="60dp"
            android:text="@string/add_item"
            android:textSize="18sp"
            android:paddingLeft="20dp"
            android:textColor="@android:color/white"
            android:drawableLeft="@drawable/ic_add_24dp"
            android:background="@drawable/rounded_black_bg"
            android:layout_gravity="center"/>
</RelativeLayout>

第二个场景的布局包含editText(ID相同),定义如下:

res/layout/another_scene.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/scene_container"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >
        <EditText
                android:id="@+id/add_btn"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:visibility="gone"
                android:minHeight="50dp"
                android:layout_marginLeft="@dimen/margin_30dp"
                android:layout_marginRight="@dimen/margin_30dp"
                android:paddingLeft="@dimen/dimen_20dp"
                android:paddingRight="@dimen/dimen_50dp"
                android:textColor="@android:color/black"
                android:inputType="text"
                android:background="@drawable/rounded_edit_text"
                android:layout_gravity="center"/>
    </RelativeLayout>

Java 代码:

public class MainActivity extends AppCompatActivity {

    private EditText mItemInputEditText;
    private Scene mAScene;
    private Scene mAnotherScene;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        TextView dateTextView = (TextView) findViewById(R.id.date_tv);

        mItemInputEditText = (EditText) findViewById(R.id.item_input_et);
        final Button addButton = (Button) findViewById(R.id.add_btn);

        final ViewGroup transitionsContainer = (ViewGroup) findViewById(R.id.transitions_container);

        // Create the scenes
        mAScene = Scene.getSceneForLayout(mSceneRoot, R.layout.a_scene, this);
        mAnotherScene = Scene.getSceneForLayout(mSceneRoot, R.layout.another_scene, this);

        mItemInputEditText.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {



                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                    Transition transition = new ChangeBounds();

                    TransitionManager.go(mAScene, transition);
                }

                addButton.setVisibility(View.VISIBLE);
                mItemInputEditText.setVisibility(View.GONE);
            }
        });

        addButton.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                    Transition transition = new ChangeBounds();

                    TransitionManager.go(mAnotherScenetransition);
                }

                addButton.setVisibility(View.GONE);
                mItemInputEditText.setVisibility(View.VISIBLE);
            }

        });

        SimpleDateFormat dt = new SimpleDateFormat("EEE d MMM yyyy");
        dateTextView.setText(dt.format(new Date()));

    }
}

【讨论】:

  • 然后使用 valueanimator 为这个动画创建自己的动画师
【解决方案3】:

您可以为此使用 FABReveal 布局。从中获取参考并将相对布局更改为按钮。并根据需要进行修改。

XML

<com.truizlop.fabreveallayout.FABRevealLayout
    android:id="@+id/fab_reveal_layout"
    android:layout_width="match_parent"
    android:layout_height="@dimen/fab_reveal_height"
    >

    <android.support.design.widget.FloatingActionButton
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:backgroundTint="@color/some_color"
        android:src="@drawable/some_drawable"
        />

    <RelativeLayout
        android:id="@+id/main_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        ...
    </RelativeLayout>

    <RelativeLayout
        android:id="@+id/secondary_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        ...
    </RelativeLayout>

</com.truizlop.fabreveallayout.FABRevealLayout>

https://github.com/truizlop/FABRevealLayout

https://github.com/saulmm/Curved-Fab-Reveal-Example

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-02-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-30
    相关资源
    最近更新 更多