Android - 片断过渡
什么是过渡?
Lollipop 中的 Activity 和 Fragment 过渡建立在 Android 中一个相对较新的功能(称为过渡)之上。 在 KitKat 中引入的转换框架提供了一个方便的 API,用于在应用程序的不同 UI 状态之间进行动画处理。 该框架围绕两个关键概念构建:场景和过渡。 场景定义了应用程序 UI 的给定状态,而过渡定义了两个场景之间的动画变化。
当场景发生变化时,过渡有两个主要职责 −
- 捕捉开始和结束场景中每个视图的状态。
- 根据差异创建动画器,将视图从一个场景动画化到另一个场景。
示例
本示例将向您解释如何使用片段过渡创建自定义动画。 因此,让我们按照以下步骤类似于我们在创建 Hello World 示例时所遵循的步骤 −
| 步骤 | 描述 |
|---|---|
| 1 | 您将使用 Android Studio 创建一个 Android 应用程序,并将其命名为 fragmentcustomanimations,位于包 com.example.fragmentcustomanimations 下,Activity 为空白。 |
| 2 | 修改 activity_main.xml,在res/layout/activity_main.xml中添加一个 Text 文本视图 |
| 3 | 在目录 res/layout 下创建一个名为 fragment_stack.xml.xml 的布局来定义您的片段标签和按钮标签 |
| 4 | 创建一个文件夹,放在 res/ 并命名为 animation 并添加 fragment_slide_right_enter.xml, fragment_slide_left_exit.xml,fragment_slide_right_exit.xml 和 fragment_slide_left_enter.xml |
| 5 | 在 MainActivity.java 中,需要添加 fragment stack、fragment manager、onCreateView() |
| 6 | 运行应用程序以启动 Android 模拟器并验证应用程序中所做更改的结果。 |
以下将是 res.layout/activity_main.xml 它包含 TextView 的内容
<?xml version="1.0" encoding="utf-8"?> <TextView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/text" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center_vertical|center_horizontal" android:text="@string/hello_world" android:textAppearance="?android:attr/textAppearanceMedium" />
以下是 res/animation/fragment_stack.xml 文件的内容。 它包含框架布局和按钮
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<fragment
android:id="@+id/fragment1"
android:name="com.pavan.listfragmentdemo.MyListFragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
以下是 res/animation/fragment_slide_left_enter.xml 文件的内容。它包含 set 方法和 objectAnimator
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<objectAnimator
android:interpolator="@android:interpolator/decelerate_quint"
android:valueFrom="100dp" android:valueTo="0dp"
android:valueType="floatType"
android:propertyName="translationX"
android:duration="@android:integer/config_mediumAnimTime" />
<objectAnimator
android:interpolator="@android:interpolator/decelerate_quint"
android:valueFrom="0.0" android:valueTo="1.0"
android:valueType="floatType"
android:propertyName="alpha"
android:duration="@android:integer/config_mediumAnimTime" />
</set>
以下是 res/animation/fragment_slide_left_exit.xml 文件的内容。它包含 set 和 objectAnimator 标签。
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<objectAnimator
android:interpolator="@android:interpolator/decelerate_quint"
android:valueFrom="0dp" android:valueTo="-100dp"
android:valueType="floatType"
android:propertyName="translationX"
android:duration="@android:integer/config_mediumAnimTime" />
<objectAnimator
android:interpolator="@android:interpolator/decelerate_quint"
android:valueFrom="1.0" android:valueTo="0.0"
android:valueType="floatType"
android:propertyName="alpha"
android:duration="@android:integer/config_mediumAnimTime" />
</set>
以下代码是 res/animation/fragment_slide_right_enter.xmlfile.it 的内容。它包含 set 和 objectAnimator 标签
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<objectAnimator
android:interpolator="@android:interpolator/decelerate_quint"
android:valueFrom="-100dp" android:valueTo="0dp"
android:valueType="floatType"
android:propertyName="translationX"
android:duration="@android:integer/config_mediumAnimTime" />
<objectAnimator
android:interpolator="@android:interpolator/decelerate_quint"
android:valueFrom="0.0" android:valueTo="1.0"
android:valueType="floatType"
android:propertyName="alpha"
android:duration="@android:integer/config_mediumAnimTime" />
</set>
以下代码是 res/animation/fragment_slide_right_exit.xml 文件的内容,它包含 set 和 objectAnimator 标签
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<objectAnimator
android:interpolator="@android:interpolator/decelerate_quint"
android:valueFrom="0dp" android:valueTo="100dp"
android:valueType="floatType"
android:propertyName="translationX"
android:duration="@android:integer/config_mediumAnimTime" />
<objectAnimator
android:interpolator="@android:interpolator/decelerate_quint"
android:valueFrom="1.0" android:valueTo="0.0"
android:valueType="floatType"
android:propertyName="alpha"
android:duration="@android:integer/config_mediumAnimTime" />
</set>
以下代码将是 src/main/java/MainActivity.java 文件的内容。 它包含按钮侦听器、堆栈片段和 onCreateView
package com.example.fragmentcustomanimations;
import android.app.Activity;
import android.app.Fragment;
import android.app.FragmentTransaction;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
/**
* Demonstrates the use of custom animations in a FragmentTransaction when
* pushing and popping a stack.
*/
public class FragmentCustomAnimations extends Activity {
int mStackLevel = 1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.fragment_stack);
// Watch for button clicks.
Button button = (Button)findViewById(R.id.new_fragment);
button.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
addFragmentToStack();
}
});
if (savedInstanceState == null) {
// Do first time initialization -- add initial fragment.
Fragment newFragment = CountingFragment.newInstance(mStackLevel);
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.add(R.id.simple_fragment, newFragment).commit();
}
else
{
mStackLevel = savedInstanceState.getInt("level");
}
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt("level", mStackLevel);
}
void addFragmentToStack() {
mStackLevel++;
// Instantiate a new fragment.
Fragment newFragment = CountingFragment.newInstance(mStackLevel);
// Add the fragment to the activity, pushing this transaction
// on to the back stack.
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.setCustomAnimations(R.animator.fragment_slide_left_enter,
R.animator.fragment_slide_left_exit,
R.animator.fragment_slide_right_enter,
R.animator.fragment_slide_right_exit);
ft.replace(R.id.simple_fragment, newFragment);
ft.addToBackStack(null);
ft.commit();
}
public static class CountingFragment extends Fragment {
int mNum;
/**
* Create a new instance of CountingFragment, providing "num"
* as an argument.
*/
static CountingFragment newInstance(int num) {
CountingFragment f = new CountingFragment();
// Supply num input as an argument.
Bundle args = new Bundle();
args.putInt("num", num);
f.setArguments(args);
return f;
}
/**
* When creating, retrieve this instance's number from its arguments.
*/
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mNum = getArguments() != null ? getArguments().getInt("num") : 1;
}
/**
* The Fragment's UI is just a simple text view showing its
* instance number.
*/
@Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container,Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.hello_world, container, false);
View tv = v.findViewById(R.id.text);
((TextView)tv).setText("Fragment #" + mNum);
tv.setBackgroundDrawable(getResources().
getDrawable(android.R.drawable.gallery_thumb));
return v;
}
}
}
以下将是 AndroidManifest.xml 的内容
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.fragmentcustomanimations"
android:versionCode="1"
android:versionName="1.0" >
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="com.example.fragmentcustomanimations.MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
运行应用程序
让我们尝试运行我们刚刚创建的 Fragment Transitions 应用程序。假设您在进行环境设置时已经创建了 AVD。 要从 Android Studio 运行应用程序,请打开项目的活动文件之一,然后单击工具栏中的 Run
图标。Android 会在您的 AVD 上安装应用程序并启动它,如果您的设置和应用程序一切正常,它将显示以下 Emulator 窗口:
如果单击新片段,它将第一个片段更改为第二个片段,如下所示