android共享元素动画
In this tutorial we’ll implement a different kind of animation transition namely Shared Element Transition between activities.
在本教程中,我们将实现另一种动画过渡,即活动之间的共享元素过渡 。
Android共享元素过渡动画 ()
Android Shared Element Transition determines how shared element views are animated from one Activity/Fragment to another during a scene transition.
Android共享元素过渡确定在场景过渡期间如何将共享元素视图从一个活动/片段动画化为另一个活动/片段。
In pre-Lollipop devices Android used to support transitions between activities and fragments that involved transitions of the entire view hierarchies. However there are many cases when a view (let’s say ListView) consists of different row items. More often than not, clicking any row would show details of that respective row in the next screen. So to emphasise continuity between the two activities, we’ll show a circular reveal animation. This improves the user experience by drawing their focus towards the relationship between the new screen and the previous screen. A Shared Element Transition like this is more commonly seen in music playlist apps.
在Lollipop之前的设备中,Android用于支持活动和涉及整个视图层次结构过渡的片段之间的过渡。 但是,在许多情况下,视图(例如ListView)由不同的行项目组成。 通常,单击任何行都会在下一个屏幕中显示相应行的详细信息。 因此,为了强调两个活动之间的连续性,我们将展示一个圆形的揭示动画。 通过将注意力集中在新屏幕和先前屏幕之间的关系上,可以改善用户体验。 这样的共享元素转换在音乐播放列表应用中更为常见。
Note: This type of transition works only for android SDK>21.
注意:这种类型的转换仅适用于android SDK> 21。
Let’s begin the implementation of the app. In this tutorial we’ll implement custom ListView rows and show the desired transition for each of them.
让我们开始执行该应用程序。 在本教程中,我们将实现自定义ListView行,并为每个行显示所需的过渡。
Android共享元素过渡动画项目结构 ()
This project consists of 2 activities and a CustomAdapter for the ListView.
该项目包括2个活动和一个ListView的CustomAdapter。
Android过渡动画–共享元素过渡代码 ()
To enable this transitions add the following snippet inside the AppTheme tag in styles.xml
.
要启用此转换,请在styles.xml
的AppTheme标记内添加以下代码段。
<item name="android:windowContentTransitions">true</item>
For both the layouts with this transition we need to assign a android:transitionName
attribute.
对于这两个具有此过渡的布局,我们需要分配android:transitionName
属性。
The activity_main.xml
populates a ListView and the details_activity.xml
is for the the details screen. Both are shown below.
activity_main.xml
填充一个ListView,而details_activity.xml
用于详细信息屏幕。 两者都显示如下。
<LinearLayout xmlns:android="https://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:transitionName="@string/transition"
android:orientation="vertical">
<ListView
android:layout_width="wrap_content"
android:id="@+id/list_view"
android:layout_height="wrap_content"/>
</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="https://schemas.android.com/apk/res/android"
xmlns:tools="https://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="@dimen/activity_horizontal_margin"
android:id="@+id/layout"
android:transitionName="@string/transition"
tools:context="com.journaldev.sharedelementtransition.MainActivity">
<TextView
android:gravity="center"
android:textColor="@android:color/white"
android:id="@+id/heading"
android:layout_width="match_parent"
android:textAppearance="?android:attr/textAppearanceLarge"
android:layout_height="wrap_content" />
<TextView
android:gravity="center"
android:id="@+id/language"
android:textColor="@android:color/white"
android:layout_width="match_parent"
android:textAppearance="?android:attr/textAppearanceMedium"
android:layout_height="wrap_content"
android:layout_below="@+id/heading"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
<TextView
android:gravity="center"
android:id="@+id/desc"
android:textColor="@android:color/white"
android:layout_width="match_parent"
android:textAppearance="?android:attr/textAppearanceMedium"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
/>
</RelativeLayout>
As you can see a android:transitionName
attribute is declared as a string in the root view of both the layouts.
如您所见,在两个布局的根视图中android:transitionName
属性都声明为字符串。
We’ve created a custom ListView which populates its layout from a ArrayList of String arrays. The layout and adapter of the ListView are given below.
我们创建了一个自定义ListView,它从String数组的ArrayList填充其布局。 ListView的布局和适配器如下。
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="https://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:padding="@dimen/activity_horizontal_margin"
android:background="@color/md_black_1000"
android:layout_margin="5dp"
android:id="@+id/rl"
android:layout_height="wrap_content">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:id="@+id/primary_textview"
android:gravity="center"
android:textColor="@android:color/white"
/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:id="@+id/textView"
android:layout_below="@+id/primary_textview"
android:textColor="@android:color/white"
android:gravity="center"
/>
</RelativeLayout>
public class CustomAdapter extends BaseAdapter {
ArrayList<String[]> arrayList;
Context c;
public CustomAdapter(Context c, ArrayList<String[]> list) {
arrayList = list;
this.c = c;
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return arrayList.size();
}
@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return arrayList.get(position);
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
View row = null;
LayoutInflater inflater = (LayoutInflater) c
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (convertView == null) {
row = inflater.inflate(R.layout.row_layout, parent,
false);
} else {
row = convertView;
}
String[] detail = arrayList.get(position);
RelativeLayout rl= (RelativeLayout)row.findViewById(R.id.rl);
rl.setBackgroundColor(Color.parseColor(detail[3]));
TextView name = (TextView) row.findViewById(R.id.primary_textview);
name.setText(detail[0]);
TextView email = (TextView) row.findViewById(R.id.textView);
email.setText(detail[1]);
return row;
}
}
The MainActivity.java
and DetailsActivity.java
are given below.
MainActivity.java
和DetailsActivity.java
如下所示。
package com.journaldev.sharedelementtransition;
import android.content.Intent;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.ActivityOptionsCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final ArrayList<String[]> values = new ArrayList<String[]>();
values.add(new String[]{"Android", "Java", getString(R.string.android),'#' + Integer.toHexString(getResources().getColor(R.color.md_light_green_900))});
values.add(new String[]{"iOS", "Swift", getString(R.string.ios),'#' + Integer.toHexString(getResources().getColor(R.color.md_amber_A700))});
values.add(new String[]{"Xamarin", "C#",getString(R.string.xamarin),'#' + Integer.toHexString(getResources().getColor(R.color.md_pink_A700))});
values.add(new String[]{"PhoneGap", "HTML CSS and JScript",getString(R.string.phonegap),'#' + Integer.toHexString(getResources().getColor(R.color.md_brown_800))});
ListView listView = (ListView) findViewById(R.id.list_view);
CustomAdapter adapter = new CustomAdapter(this, values);
listView.setAdapter(adapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Intent intent = new Intent(MainActivity.this, DetailsActivity.class);
intent.putExtra("array",values.get(position));
// Get the transition name from the string
String transitionName = getString(R.string.transition);
ActivityOptionsCompat options =
ActivityOptionsCompat.makeSceneTransitionAnimation(MainActivity.this,
view, // Starting view
transitionName // The String
);
ActivityCompat.startActivity(MainActivity.this, intent, options.toBundle());
}
});
}
}
When an activity is finished, instead of finish() we invoke ActivityCompat.finishAfterTransition(this);
as shown in the code below.
活动结束后,我们将调用ActivityCompat.finishAfterTransition(this);
而不是finish( ActivityCompat.finishAfterTransition(this);
如下面的代码所示。
public class DetailsActivity extends AppCompatActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.details_activity);
String[] array= getIntent().getStringArrayExtra("array");
RelativeLayout rl= (RelativeLayout)findViewById(R.id.layout);
rl.setBackgroundColor(Color.parseColor(array[3]));
TextView textView= (TextView)findViewById(R.id.heading);
textView.setText(array[0]);
TextView type= (TextView)findViewById(R.id.language);
type.setText(array[1]);
TextView desc=(TextView)findViewById(R.id.desc);
desc.setText(array[2]);
}
@Override
public void onBackPressed() {
ActivityCompat.finishAfterTransition(this);
}
}
The output of the application in action is given below.
![android transition animation, shared element transition android](https://cdn.journaldev.com/wp-content/uploads/2016/04/android-shared-element-transition-output.gif)
实际应用程序的输出如下。
This brings an end to this tutorial. You can download the final Android Transition Animation – Shared Element Transition Project from the link below.
本教程到此结束。 您可以从下面的链接下载最终的Android Transition Animation –共享元素过渡项目 。
翻译自: https://www.journaldev.com/10473/android-shared-element-transition-animation
android共享元素动画