从按钮过渡到 EditText
Transition from Button to EditText
我想在我的 android 中有一个 transition
views
视图是 Button
另一个是 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()));
}
}
但是使用此代码生成的转换是
如您所见,这与预期相比有点奇怪,任何人都可以建议我进行一些更改以获得所需的转换。
首先,更改布局 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()));
}
}
Transitions API固然是好东西,但它不能为你解决所有问题。你还没有指示过渡框架如何执行该动画,它怎么会理解你要执行的最终动画是什么?
我不确定仅使用过渡可以实现此动画 API。相反,您可以坚持使用标准动画 APIs,例如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();
}
editTextWidth
和 buttonWidth
是视图的初始大小:
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。
您可以为此使用 FABReveal Layout。从中获取参考并将相对布局更改为按钮。并按要求修改。
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>
我想在我的 android 中有一个 transition
views
视图是 Button
另一个是 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()));
}
}
但是使用此代码生成的转换是
如您所见,这与预期相比有点奇怪,任何人都可以建议我进行一些更改以获得所需的转换。
首先,更改布局 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()));
}
}
Transitions API固然是好东西,但它不能为你解决所有问题。你还没有指示过渡框架如何执行该动画,它怎么会理解你要执行的最终动画是什么?
我不确定仅使用过渡可以实现此动画 API。相反,您可以坚持使用标准动画 APIs,例如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();
}
editTextWidth
和 buttonWidth
是视图的初始大小:
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。
您可以为此使用 FABReveal Layout。从中获取参考并将相对布局更改为按钮。并按要求修改。
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>