Анимация между действиями и общими видами: glitchy/hack на концах анимации?
Итак, проблема, с которой я сталкиваюсь, заключается в том, что анимация, которую я делаю между двумя действиями и двумя разделяемыми представлениями, выглядит не очень хорошо.
Проблема заключается в том, что ее "glitchy", переходя из Activity2 обратно в Activity1, TextViews, являющийся общим типом миганий в конце анимации, показывает "больший текст" из Activity2 на долю секунды, поэтому он "мигает".
Действие 1 (RecyclerView с тремя элементами):
![enter image description here]()
Действие 2 (Подробности):
![enter image description here]()
Я снимал экран, делая анимацию. Когда вы возвращаетесь из Activity2 в Activit2, вы можете видеть, что текст близок в самом конце. Это видео (36MB, извините за размер) показывает это:
https://drive.google.com/file/d/0B3wIZ9CS9Kj_a0MyVFlzX1YtY0E/view?usp=sharing
Вопрос в том, что я делаю неправильно? Почему это так моргает? Я вижу видео на других анимах, и они все супер гладкие и приятные.
Я тестировал разные типы переходов (changeBounds, explode и т.д. и т.д.), но всегда происходит что-то странное. Любые советы, идеи были бы очень благодарны =)
МОЙ КОД
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);
}
}
И макеты, сначала my_text_view, которые находятся в списке 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>
И action_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>
И переход xml (в/res/переход):
<?xml version="1.0" encoding="utf-8"?>
<transitionSet xmlns:android="http://schemas.android.com/apk/res/android">
<changeBounds/>
<explode />
</transitionSet>
и 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>
Ответы
Ответ 1
Проблема заключается в том, что вы пытаетесь оживить размер TextView
как общий элемент, используя переход ChangeBounds
. Это не будет работать из-за того, как работает ChangeBounds
. Переход ChangeBounds
анализирует границы компоновки представления в начале и конце перехода и оживляет между ними. ChangeBounds
работает для произвольных просмотров, поэтому он не будет вызывать setTextSize()
на вашем TextView
во время перехода для вас... это то, что вам нужно будет сделать самостоятельно, используя настраиваемый переход, если вы хотите увидеть TextView
размер плавно увеличивается/уменьшается во время анимации. Существует некоторая информация о том, как это сделать в fooobar.com/info/277855/....