Scale view to parent layout size
Asked Answered
S

1

7

I am trying to scale a view to layout size by using object animator. The view is a LinearLayout. The view does stretch, but not till the screen size in both the directions (i.e X and Y).

Here is the code.

I feel that either the problem is with this:

  1. The formula to calculate how much zoom must be done.

    zoomTillX = screen_width/zoomView_width;
    zoomTillY = screen_height/zoomView_height;
    
  2. Or with the Animation property code that is done in a wrong way.

Please let me know how can I achieve a zoom in.

public class MainActivity extends AppCompatActivity {

    TextView tv;
    double screen_height;
    LinearLayout zoomView;
    double screen_width;
    double zoomTillX;
    double zoomTillY;
    double zoomView_width;
    double zoomView_height;



    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);


        tv = (TextView) findViewById(R.id.tv);
        zoomView = (LinearLayout) findViewById(R.id.zoomView);
        DisplayMetrics dm = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(dm);
        screen_height = (double)dm.heightPixels;
        screen_width = (double)dm.widthPixels;
        zoomView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                zoomView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
                zoomView_width = (double)zoomView.getMeasuredWidth();
                zoomView_height =  (double)zoomView.getMeasuredHeight();


            }
        });
        zoomView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {


            final  Handler handler =  new Handler(Looper.getMainLooper());

                handler.postDelayed(new Runnable() {
                    @Override
                    public void run() {

                        if(zoomView_width > 0 && zoomView_height > 0)
                        {
                            zoomTillX = screen_width/zoomView_width;
                            zoomTillY = screen_height/zoomView_height;

                            Log.d("VIEW GET X IS ",String.valueOf(zoomView.getX()));
                            Log.d("VIEW GET Y IS ",String.valueOf(zoomView.getY()));

                            ObjectAnimator scaleDownX = ObjectAnimator.ofFloat(zoomView, "scaleX", (float)(zoomTillX));
                            ObjectAnimator scaleDownY = ObjectAnimator.ofFloat(zoomView, "scaleY",(float)(zoomTillY));

                            List<Animator> oaList = new ArrayList<Animator>();
                            oaList.add(scaleDownX);
                            oaList.add(scaleDownY);

                            AnimatorSet ani = new AnimatorSet();
                            ani.playTogether(oaList);
                            ani.setDuration(500);
                           ani.start();

                        }else{

                            handler.postDelayed(this,300);
                        }

                    }
                },500);

            }
        });

    }
}

This is how it looks finally.

enter image description here

Skein answered 29/5, 2017 at 6:0 Comment(3)
Can you post the layout before, so that we can see what happens after animation? Also, why exactly do you want to achieve that using scaling?Breakneck
@Breakneck The requirement is simple, the blue color thing(LinearLayout) is present in the upper left corner as a small 170dp by 170dp in height and width..When the layout is clicked the layout will start zooming in i.e scaling in X and Y direction, the scaling should happen till the screen size, but presently the layout is being scaled till as shown in the above image. I would like the layout to be scaled till the screen dimensions, then the blue color thing would cover the entire screen.. Got it ?Skein
@Breakneck If that can be achieved by any other property than scale animation please do let me know ?Skein
B
7

That can be done via ValueAnimator.

Having this layout as the content of activity:

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

  <View
      android:id="@+id/view"
      android:layout_width="170dp"
      android:layout_height="170dp"
      android:background="#3143ff"/>

</FrameLayout>

And in activity's onCreate():



    final View view = findViewById(R.id.view);
    final View contentView = findViewById(R.id.content_frame);

    contentView.setOnClickListener(v -> {

      final int screenWidth = contentView.getWidth();
      final int screenHeight = contentView.getHeight();

      ValueAnimator widthAnimator = ValueAnimator.ofInt(view.getWidth(), screenWidth);
      ValueAnimator heightAnimator = ValueAnimator.ofInt(view.getHeight(), screenHeight);

      widthAnimator.setDuration(1500);
      heightAnimator.setDuration(1500);

      widthAnimator.addUpdateListener(animation -> {
        view.getLayoutParams().width = (int) animation.getAnimatedValue();
        view.requestLayout();
      });

      heightAnimator.addUpdateListener(animation -> {
        view.getLayoutParams().height = (int) animation.getAnimatedValue();
        view.requestLayout();
      });

      widthAnimator.start();
      heightAnimator.start();
    });


This will be the result:

enter image description here


Transitions API

We've implemented this animation ourselves. But why won't we let the system take care of building all this animators?

There's a Transitions API, which will take the heavy lifting for us. All we have to do, is to ask the framework to detect layout changes, create appropriate animators and run the animations.

So, all the code above can be changed to following, which will result in exactly same output:



    contentView.setOnClickListener(v -> {
      final int screenWidth = contentView.getWidth();
      final int screenHeight = contentView.getHeight();

      // Uncomment this, if you want Transitions API to run default animation
      // TransitionManager.beginDelayedTransition(contentView);

      Transition autoTransition = new AutoTransition();
      autoTransition.setDuration(1500);

      // With this overload you can control actual transition animation
      TransitionManager.beginDelayedTransition(contentView, autoTransition);
      // After `beginDelayedTransition()` function perform changes to the layout
      // Transitions framework will detect those changes and perform appropriate animations
      view.getLayoutParams().width = screenWidth;
      view.getLayoutParams().height = screenHeight;
      view.requestLayout();
      view.invalidate();
    });


Breakneck answered 31/5, 2017 at 13:52 Comment(2)
I will award you my bounty as soon I am able to.Skein
@Breakneck +1..Nice explanation.!Gabriello

© 2022 - 2024 — McMap. All rights reserved.