So, the problem I am facing is that the animation I do between two Activities and two shared views is not looking great.
The problem is that its "glitchy", when going from Activity2 back to Activity1, the TextViews being shared sort of blinks at the end of the animation, revealing the "bigger text" from Activity2 for a fraction of a second, so it "blinks".
Activity 1 (RecyclerView with three items):
Activity 2 (Details):
I filmed the screen, while doing the animation. When going back from Activity2 to Activit2, you can see the text blink at the very end. This video (36MB, sorry for size) shows it:
https://drive.google.com/file/d/0B3wIZ9CS9Kj_a0MyVFlzX1YtY0E/view?usp=sharing
The question is: what I am doing wrong? Why is it blinking like that? I see videos on other anims, and they are all super smooth and nice.
I have tested different type of transitions (changeBounds, explode, etc etc), but there is always something weird going on. Any tips, ideas would be greatly appreciated =)
MY CODE
MainActivity (Activity1):
package se.snapcode.lollipoptest;
import android.app.Activity;
import android.app.ActivityOptions;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.view.GestureDetectorCompat;
import android.support.v7.widget.DefaultItemAnimator;
import android.support.v7.widget.LinearLayoutManager;
import android.util.Pair;
import android.view.GestureDetector;
import android.view.Menu;
import android.view.MenuItem;
import android.support.v7.widget.RecyclerView;
import android.view.MotionEvent;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends Activity {
private RecyclerView mRecyclerView;
private MyAdapter mAdapter;
private RecyclerView.LayoutManager mLayoutManager;
GestureDetectorCompat gestureDetector;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mRecyclerView = (RecyclerView) findViewById(R.id.my_recycler_view);
// use this setting to improve performance if you know that changes
// in content do not change the layout size of the RecyclerView
mRecyclerView.setHasFixedSize(true);
// use a linear layout manager
mLayoutManager = new LinearLayoutManager(this);
mRecyclerView.setLayoutManager(mLayoutManager);
// specify an adapter (see also next example)
String[] strings = new String[3];
strings[0] = "A1";
strings[1] = "A2";
strings[2] = "A3";
mAdapter = new MyAdapter(strings);
mRecyclerView.setAdapter(mAdapter);
mAdapter.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(View view, int position) {
final TextView headerView = (TextView)view.findViewById(R.id.textView1);
final TextView textView = (TextView)view.findViewById(R.id.textView2);
Intent intent = new Intent(MainActivity.this, DetailsActivity.class);
intent.putExtra("header", headerView.getText().toString());
intent.putExtra("text", textView.getText().toString());
ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(MainActivity.this, Pair.create((View)headerView, "header"),
Pair.create((View)textView, "text"));
startActivity(intent, options.toBundle());
}
});
RecyclerView.ItemDecoration itemDecoration =
new DividerItemDecoration(this, DividerItemDecoration.VERTICAL_LIST);
mRecyclerView.addItemDecoration(itemDecoration);
// this is the default; this call is actually only necessary with custom ItemAnimators
mRecyclerView.setItemAnimator(new DefaultItemAnimator());
}
}
DetailsActivity (Activity2):
package se.snapcode.lollipoptest;
import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.TextView;
public class DetailsActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_details);
String header = getIntent().getStringExtra("header");
String text = getIntent().getStringExtra("text");
TextView tv1 = (TextView)findViewById(R.id.tv_details_header);
tv1.setText(header);
TextView tv2 = (TextView)findViewById(R.id.tv_details_text);
tv2.setText(text);
}
}
And the layouts, first my_text_view that is in the list of the RecyclerView:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent"
android:clickable="true"
android:focusable="true"
android:background="?android:attr/selectableItemBackground"
android:colorControlHighlight="@android:color/holo_blue_light"
android:padding="10dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="MY HEADER IS HERE"
android:transitionName="header"
android:id="@+id/textView1" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceSmall"
android:text="This is some text that is of relevance"
android:transitionName="text"
android:id="@+id/textView2" />
</LinearLayout>
And the activity_details.xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
android:orientation="vertical"
tools:context="se.snapcode.lollipoptest.DetailsActivity">
<TextView android:id="@+id/tv_details_header" android:text="A1" android:layout_width="wrap_content"
android:transitionName="header"
android:textSize="48dp"
android:layout_height="wrap_content" />
<TextView android:id="@+id/tv_details_text" android:text="Some text of lesser importance" android:layout_width="wrap_content"
android:textSize="24dp"
android:transitionName="text"
android:layout_height="wrap_content" />
</LinearLayout>
And the transition xml (in /res/transition):
<?xml version="1.0" encoding="utf-8"?>
<transitionSet xmlns:android="http://schemas.android.com/apk/res/android">
<changeBounds/>
<explode />
</transitionSet>
and the styles.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="AppTheme" parent="android:Theme.Material.Light">
<!-- enable window content transitions -->
<item name="android:windowContentTransitions">true</item>
<!-- specify enter and exit transitions -->
<item name="android:windowEnterTransition">@android:transition/slide_left</item>
<item name="android:windowExitTransition">@android:transition/slide_right</item>
<!-- specify shared element transitions -->
<item name="android:windowSharedElementEnterTransition">
@transition/change_image_transform</item>
<item name="android:windowSharedElementExitTransition">
@transition/change_image_transform</item>
</style>
</resources>
The problem is that you are trying to animate a TextView
's size as a shared element using a ChangeBounds
transition. This will not work because of the way ChangeBounds
works. The ChangeBounds
transition analyzes the layout bounds of a view at the start and end of the transition and animates between the two. ChangeBounds
works for arbitrary views, so it will not call setTextSize()
on your TextView
during the transition for you... this is something you would need to do yourself using a custom transition if you wanted to see the TextView
's size seamlessly increase/decrease during the animation. There is some information on how to do this in this StackOverflow answer.
来源:https://stackoverflow.com/questions/27123561/animation-between-activities-and-shared-views-glitchy-hack-at-the-ends-of-anima