Joy Rex
Joy Rex

Reputation: 618

Animation performance slow in Android

Is there any difference in adding single image 10 times and 10 different images(same dimens,same resolution,same file size) one time for animation.?

Because I added 1 image 10 times and provided multiple animation while swiping it was smooth throughout my interaction. but while adding different images (same dimens,same resolution,same file size) for my process, there is severe lag in animating. Some steps i tried to improve performance

1.Adding Layer type and setting null while animation ended (This improves for one time animating, when the animation is continuous, this is not helping)

2.Tried Setting hardwareaccelerated attribute in Manifest

3.Tried setting large heap attribute in manifest

4.Added animation cache for items.

5.Tried running with high RAM devices.

Do we have any options to improve animation performance.?

EDITED:

FrameLayout frame = new FrameLayout(this);
        frame.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 700));
        ArrayList<Integer> arrayList = new ArrayList<Integer>();
        arrayList.add(R.drawable.image1);
        arrayList.add(R.drawable.image2);
        arrayList.add(R.drawable.image3);
        arrayList.add(R.drawable.image4);
        arrayList.add(R.drawable.image5);
        arrayList.add(R.drawable.image6);
        arrayList.add(R.drawable.image7);
        arrayList.add(R.drawable.image8);
        arrayList.add(R.drawable.image9);
        arrayList.add(R.drawable.image10);
        arrayList.add(R.drawable.image11);
        for(int i=0;i<11;i++){
            ImageView imgvw = new ImageView(this);
            imgvw.setImageResource(arrayList.get(i));
            imgvw.setLayoutParams(new ActionBar.LayoutParams(250, 400));
            imgvw.setScaleType(ImageView.ScaleType.FIT_XY);
            imgvw.setX(this.getResources().getDisplayMetrics().widthPixels / 2);
            imgvw.setRotationY(-45);
            imgvw.setScaleY(0.7f);
            frame.addView(imgvw);
              }
              setContentView(frame);

public boolean onTouchEvent(MotionEvent event) {

        switch (event.getActionMasked()){
            case MotionEvent.ACTION_DOWN:{
                final AnimatorSet animationSet = new AnimatorSet();
                for(int i=0;i<frame.getChildCount();i++){
                    final ImageView vw = (ImageView) frame.getChildAt(i);
//                    vw.setLayerType(View.LAYER_TYPE_HARDWARE, null);

                    animationSet.playTogether(
                            ObjectAnimator.ofFloat(vw, "rotationY", 45),
                            ObjectAnimator.ofFloat(vw, "scaleY", 0.8f),
                            ObjectAnimator.ofFloat(vw, "x", 0)
                    );
                    animationSet.setDuration(600);
                    animationSet.setInterpolator(new DecelerateInterpolator(1.5f));
                    animationSet.start();

                                    animationSet.addListener(new Animator.AnimatorListener() {
                        @Override
                        public void onAnimationStart(Animator animation) {

                        }

                        @Override
                        public void onAnimationEnd(Animator animation) {
//                            vw.setLayerType(View.LAYER_TYPE_NONE,null);
                            animationSet.start();
                        }

                        @Override
                        public void onAnimationCancel(Animator animation) {

                        }

                        @Override
                        public void onAnimationRepeat(Animator animation) {
                            vw.setX(getResources().getDisplayMetrics().widthPixels / 2);
                            vw.setRotationY(-45);
                            vw.setScaleY(0.7f);
                        }
                    });

                             }
              }
}

Upvotes: 2

Views: 1900

Answers (3)

Dinash
Dinash

Reputation: 3047

By understanding your code in question, I have made some slight alternation such that the reverse animation happens and sequence happens correctly. Hope this helps!!!...

Code inside oncreate method

 frame = new FrameLayout(this);
    frame.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 700));
    ArrayList<Integer> arrayList = new ArrayList<Integer>();
    arrayList.add(R.drawable.image1);
    arrayList.add(R.drawable.image2);
    arrayList.add(R.drawable.image3);
    arrayList.add(R.drawable.image4);
    arrayList.add(R.drawable.image5);
    arrayList.add(R.drawable.image6);
    arrayList.add(R.drawable.image7);
    arrayList.add(R.drawable.image8);
    arrayList.add(R.drawable.image9);
    arrayList.add(R.drawable.image10);
    //arrayList.add(R.drawable.image11);
    for(int i=0;i<arrayList.size();i++){
        ImageView imgvw = new ImageView(this);
        imgvw.setImageResource(arrayList.get(i));
        imgvw.setLayoutParams(new ActionBar.LayoutParams(250, 400));
        imgvw.setScaleType(ImageView.ScaleType.FIT_XY);
        imgvw.setX(this.getResources().getDisplayMetrics().widthPixels / 2);
        imgvw.setRotationY(-45);
        imgvw.setScaleY(0.7f);
        frame.addView(imgvw);
    }
    setContentView(frame);

Code for animations:

private int count=0;
private int repeatMode=2;
private int repeatCount=1;
private int duration=300;

private void doAnimation(final FrameLayout frame){

    if (count>=frame.getChildCount()){
        count=0;
        return;
    }

    ImageView targetView = (ImageView) frame.getChildAt(count++);//frame.getChildCount()-1-count++);

        ObjectAnimator animator1 = ObjectAnimator.ofFloat(targetView, "rotationY", 45);
        animator1.setRepeatCount(repeatCount);
        animator1.setRepeatMode(repeatMode);
        animator1.setDuration(duration);

        ObjectAnimator animator2 = ObjectAnimator.ofFloat(targetView, "scaleY", 0.8f);
        animator2.setRepeatCount(repeatCount);
        animator2.setRepeatMode(repeatMode);
        animator2.setDuration(duration);

        ObjectAnimator animator3 = ObjectAnimator.ofFloat(targetView, "x", 0f);
        animator3.setRepeatCount(repeatCount);
        animator3.setRepeatMode(repeatMode);
        animator3.setDuration(duration);

//sequencial animation AnimatorSet set = new AnimatorSet(); set.playTogether(animator1, animator2, animator3); set.start(); set.addListener(new Animator.AnimatorListener() { @Override public void onAnimationStart(Animator animation) {

        }

        @Override
        public void onAnimationEnd(Animator animation) {
            doAnimation(frame);
        }

        @Override
        public void onAnimationCancel(Animator animation) {

        }

        @Override
        public void onAnimationRepeat(Animator animation) {

        }
    });

}

@Override
public boolean onTouch(View v, MotionEvent event) {

    return onTouchEvent(event);
}

public boolean onTouchEvent(MotionEvent event) {

    switch (event.getActionMasked()) {
        case MotionEvent.ACTION_DOWN: {
            doAnimation(frame);
            return true;
        }
    }
    return false;
}

Upvotes: 0

Sreehari
Sreehari

Reputation: 5655

Hope you would have added corresponding specific resolution images for different device resolutions.

If using same image in different screen resolutions, those devices with smaller resolutions these kind of lagging may happen.

To generate these images, you should start with your raw resource in vector format and generate the images for each density using the following size scale:

  • xhdpi: 2.0
  • hdpi: 1.5
  • mdpi: 1.0 (baseline)
  • ldpi: 0.75


More over go through the below suggestions from developer.android wrt screen density

  • ldpi Resources for low-density (ldpi) screens (~120dpi).
  • mdpi Resources for medium-density (mdpi) screens (~160dpi). (This is the baseline density.)
  • hdpi Resources for high-density (hdpi) screens (~240dpi).
  • xhdpi Resources for extra-high-density (xhdpi) screens (~320dpi).
  • xxhdpi Resources for extra-extra-high-density (xxhdpi) screens (~480dpi).
  • xxxhdpi Resources for extra-extra-extra-high-density (xxxhdpi) uses (~640dpi). Use this for the launcher icon only, see note above.
  • nodpi Resources for all densities. These are density-independent resources. The system does not scale resources tagged with this qualifier, regardless of the current screen's density.
  • tvdpi Resources for screens somewhere between mdpi and hdpi; approximately 213dpi. This is not considered a "primary" density group. It is mostly intended for televisions and most apps shouldn't need it—providing mdpi and hdpi resources is sufficient for most apps and the system will scale them as appropriate.

Upvotes: 1

Ragesh Ramesh
Ragesh Ramesh

Reputation: 3520

If you are adding 10 different images, try using animation list with seperate attributes for each image animation.

Upvotes: 0

Related Questions