将视图缩放到父布局大小

Scale view to parent layout size

我正在尝试使用对象动画器将视图缩放到布局大小。视图是 LinearLayout。视图会拉伸,但不会拉伸到两个方向(即 X 和 Y)的屏幕尺寸。

这是代码。

我感觉要么是这个问题:

  1. 计算必须完成多少缩放的公式。

    zoomTillX = screen_width/zoomView_width;
    zoomTillY = screen_height/zoomView_height;
    
  2. 或者以错误的方式完成的动画 属性 代码。

请告诉我如何实现放大。

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);

            }
        });

    }
}

这是最终的样子。

这可以通过 ValueAnimator 来完成。

将此布局作为 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>

并且在 activity 的 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();
    });


这将是结果:


转换 API

我们自己实现了这个动画。但为什么我们不让系统负责构建所有这些动画师呢?

有一个 Transitions API,它将为我们承担繁重的工作。我们所要做的就是要求框架检测布局变化,创建适当的动画师和 运行 动画。

因此,上面的所有代码都可以更改为以下代码,这将导致完全相同的输出:



    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();
    });