2016-03-03 3 views
1

Я начал работать с анимацией на Android и хочу сделать это правильно. Так, в принципе, я хочу, чтобы осуществить что-то вроде этого: enter image description hereПроблема с производительностью AnimationSet

Мой код, чтобы сделать это:

frg_wave.xml

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" 
     xmlns:tools="http://schemas.android.com/tools" 
     android:id="@+id/content" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent"> 

<View 
    android:id="@+id/wave_view1" 
    android:layout_width="35dp" 
    android:layout_height="35dp" 
    android:background="@drawable/wave_circle" 
    android:layout_gravity="center" 

    tools:alpha="0.2" 
    /> 

<View 
    android:id="@+id/wave_view2" 
    android:layout_width="35dp" 
    android:layout_height="35dp" 
    android:background="@drawable/wave_circle" 
    android:layout_gravity="center" 
    /> 

<View 
    android:id="@+id/wave_view3" 
    android:layout_width="35dp" 
    android:layout_height="35dp" 
    android:background="@drawable/wave_circle" 
    android:layout_gravity="center" 
    /> 

<View 
    android:id="@+id/wave_view4" 
    android:layout_width="35dp" 
    android:layout_height="35dp" 
    android:layout_gravity="center" 
    android:background="@drawable/wave_circle" 
    /> 

<View 
    android:id="@+id/wave_view5" 
    android:layout_width="35dp" 
    android:layout_height="35dp" 
    android:layout_gravity="center" 
    android:background="@drawable/wave_circle" 
    /> 

и фрагмент У меня есть

private View mWave1; 
private View mWave2; 
private View mWave3; 
private View mWave4; 
private View mWave5; 

private AnimatorSet setAnimation; 



PropertyValuesHolder pvhX = PropertyValuesHolder.ofFloat(View.SCALE_X, 10F); 
PropertyValuesHolder pvhY = PropertyValuesHolder.ofFloat(View.SCALE_Y, 10F); 
PropertyValuesHolder alpha = PropertyValuesHolder.ofFloat(View.ALPHA, 1F, 0.05F); 

@Nullable 
@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
    View view = inflater.inflate(R.layout.frg_wave, container, false); 
    mWave1 = view.findViewById(R.id.wave_view1); 
    mWave2 = view.findViewById(R.id.wave_view2); 
    mWave3 = view.findViewById(R.id.wave_view3); 
    mWave4 = view.findViewById(R.id.wave_view4); 
    mWave5 = view.findViewById(R.id.wave_view5); 
    setupAnimatorSet(); 
    return view; 
} 

@Override 
public void onViewCreated(View view, Bundle savedInstanceState) { 
    super.onViewCreated(view, savedInstanceState); 
    setAnimation.start(); 
} 

private void setupAnimatorSet(){ 
    setAnimation = new AnimatorSet(); 

    setAnimation.play(waveAnimation(mWave1)); 

    setAnimation.play(waveAnimation(mWave2)).after(1000L); 

    setAnimation.play(waveAnimation(mWave3)).after(2000L); 

    setAnimation.play(waveAnimation(mWave4)).after(3000L); 

    setAnimation.play(waveAnimation(mWave5)).after(4000L); 

} 



private ObjectAnimator waveAnimation(View view){ 
    ObjectAnimator scaleAnimation = 
      ObjectAnimator.ofPropertyValuesHolder(view, pvhX, pvhY, alpha); 
    scaleAnimation.setRepeatCount(ValueAnimator.INFINITE); 
    scaleAnimation.setDuration(5000L); 
    return scaleAnimation; 
} 

и wave_circle.xml является

<shape xmlns:android="http://schemas.android.com/apk/res/android" 
android:shape="oval"> 

<solid android:color="@color/colorAccent"/> 

Это, кажется, работает нормально, но я включаю рендеринг GPU и увидеть, что у меня не очень хорошая реализация. Я очень близок к ограничению, и если я добавлю другую анимацию (например, поворот представления), я буду превышать 16 мс. enter image description here

Кто-нибудь знает, что я делаю неправильно? P.S Я также пытался сделать с android:hardwareAccelerated="true", и мне это не очень помогло.

ответ

2

Анимация с несколькими масштабами обременяет RenderAnimator, поэтому вы испытываете падение FPS. Вы также потеряете некоторые fps для свойств разрешения ObjectAnimator, вместо этого вы можете попытаться использовать ViewPropertyAnimator.

Вы можете улучшить это, анимировав ImageViewMatrix, у него есть setScale(xScale, yScale). Что означает, что вы должны использовать некоторые ValueAnimator только анимировать масштабные коэффициенты, применять Matrixscale factors и установить его в ваш ImageView с:

Matrix matrix = new Matrix(); 
matrix.setScale(scale, scale, mPivotX, mPivotY); 
mTargetScalingView.setImageMatrix(matrix); 

Но лучшее исполнение вы добьетесь, если вы рисуете круги на Canvas , что относительно легко сделать, а затем только оживить радиус окружностей, которые будут имитировать масштабирование, которое вы пытаетесь достичь. Я предполагаю, что вы хотите добиться анимации, которая имеет приложение tinder, которое в основном увеличивает радиус круга и уменьшает альфу сплошного цвета и порождает новый круг до половины времени, необходимого для достижения полной прозрачности цвета (да , это именно то, что я вижу). Canvas анимации великолепны, если вы хотите достичь 60 кадров в секунду.

Будьте осторожны, вы не выполняете никаких тяжелых итераций/операций здесь, иначе вы не получите 60 кадров в секунду.

Это приведет к тому, что иерархия представлений будет иметь только один вид, а не количество волн, которые вы пытаетесь оживить, что является еще одной победой!

Смежные вопросы