19

Problem, który napotykam, polega na tym, że animacja, którą wykonuję między dwoma działaniami i dwoma wspólnymi widokami, nie wygląda świetnie.Animacja między działaniami i wspólnymi widokami: glitchy/hack na końcu animacji?

Problem polega na tym, że jego "glitchy", gdy przechodzimy z Activity2 z powrotem do Activity1, to widok TextViews jest dzielony w rodzaju migania na końcu animacji, odsłaniając "większy tekst" z Activity2 na ułamek sekundy, więc "miga".

aktywny 1 (RecyclerView z trzech pozycjach):

enter image description here

Activity 2 (szczegóły):

enter image description here

I nakręcony ekran, podczas gdy robi animację. Wracając z Activity2 do Activit2, możesz zobaczyć tekst migający na samym końcu. Ten film (36MB, przepraszam za rozmiarze) pokazuje go:

https://drive.google.com/file/d/0B3wIZ9CS9Kj_a0MyVFlzX1YtY0E/view?usp=sharing

Pytanie brzmi: co robię źle? Dlaczego tak mrugało? Widzę filmy na innych animach i wszystkie są super gładkie i ładne.

Testowałem różne rodzaje przejść (changeBounds, explode, etcetera itp.), Ale zawsze dzieje się coś dziwnego. Wszelkie wskazówki, pomysły będą bardzo mile widziane =)

mój kod

główną działalność (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); 
    } 
} 

A układy, najpierw my_text_view, który znajduje się na liście 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> 

A 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> 

I xml przejście (w/RES/przejściowy)

<?xml version="1.0" encoding="utf-8"?> 
<transitionSet xmlns:android="http://schemas.android.com/apk/res/android"> 
    <changeBounds/> 
    <explode /> 
</transitionSet> 

i 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> 
+0

Myślę, że ta odpowiedź może pomóc: http://stackoverflow.com/a/26813670/758458 – howettl

+0

Dzięki za dane wejściowe. Zatem definiowanie animacji/przejść w XML jak w moim przypadku nie działa i nie jest dobre? Czy sądzisz, że jest to oficjalna postawa Google'a? – Ted

+0

Udostępnione przejścia między obiektami okazały się nieco bardziej kłopotliwe, niż się spodziewałem. Mam nadzieję, że Google ulepszy dokumentację, ponieważ jej brakuje. – howettl

Odpowiedz

10

Problem polega na tym, że próbujesz animować rozmiar TextView jako element współdzielony przy użyciuPrzejście. To nie zadziała z powodu działania ChangeBounds. Przejście ChangeBounds analizuje granice układu widoku na początku i końcu przejścia i animuje między nimi. ChangeBounds działa dla dowolnych widoków, więc nie będzie wywoływać setTextSize() na twoim TextView podczas przejścia dla ciebie ... to jest coś, co musisz zrobić sam, używając niestandardowego przejścia, jeśli chcesz, aby rozmiar TextView płynnie zwiększał/zmniejszał podczas animacji. Jest kilka informacji, jak to zrobić w this StackOverflow answer.

+1

Tak więc odpowiedź została powiązana z powyższymi szczegółami implementującymi klasę przejściową. Nie mogę zobaczyć, jak Google pomyśli, że ktoś wpadnie na pomysł napisania takiej klasy. Jestem doświadczonym programistą i nie miałbym pojęcia, jak napisać tę klasę. Wydaje się bardzo nieporęczny i niechlujny. – Ted

+0

Ale. zasadniczo, skopiuję tę klasę Transition, a następnie dodaję ją w XML, w ten sposób? Ted

+0

Po prostu próbowałem właśnie tego, dodałem klasę java, zmieniłem xml przejścia jak wyżej (z poprawną nazwą pakietu), ale wtedy animacja nie istnieje, tylko skok od jednej czynności do następnej, ten sam "błąd" z tekstem ... – Ted

Powiązane problemy