doe
doe

Reputation: 981

How to get the Actual height and width in pixels after perform scaling on a View

I have a seekbar and an ImageView. On movement of seekbar Im scaling the Imageview accordingly. Below is my whole code

XML

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical"
tools:context="com.app.pdf.pdfmetadata.Main2Activity">

<FrameLayout
    android:background="#20000000"
    android:layout_width="match_parent"
    android:layout_height="300dp">

    <ImageView
        android:id="@+id/imageView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:src="@android:drawable/ic_dialog_info"/> 
</FrameLayout>

<SeekBar
    android:id="@+id/seekbar"
    android:min="1"
    android:max="5"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"/>

Java code

public class MainActivity extends AppCompatActivity {
private static final String TAG = "Main2Activity";
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    final View imageView = findViewById(R.id.imageView);
    SeekBar seekBar = findViewById(R.id.seekbar);
    seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
        @Override
        public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
            imageView.animate().scaleX(progress).scaleY(progress).setDuration(0).start();
            int height = imageView.getHeight();
            Log.d(TAG, "onProgressChanged: "+height);
        }

        @Override
        public void onStartTrackingTouch(SeekBar seekBar) {

        }

        @Override
        public void onStopTrackingTouch(SeekBar seekBar) {

        }
    });
}

}

As you can see , Im just scaling the Imageview and printing its height.

Question

Here height always I'm getting a constant value 96. Is it possible to get the actual height in pixels after scaling? What I need is the actual height occupied relative to the Image views parent. In my example, its a FrameLayout of 300dp height. Out of that, how much my ImageView occupies after scaling how can I get?

Upvotes: 4

Views: 1735

Answers (1)

lelloman
lelloman

Reputation: 14183

The problem is that when you animate a View with scaleX and scaleY, you're not changing the Views dimensions in the hierarchy, but only the dimension of the rendering on the screen. View.getWidth() and View.getHeight() return the size of the View as it's been laid out within the parent View while scaleX and scaleY only affect the rendering.

In order to get the "actual" rendered size, you need to multiply the View's width and height by the progress

float renderedWidth = view.getWidth() * progress;
float renderedHeight = view.getHeight() * progress;

Also, what's the point of calling animate() with 0 duration? You can use View.setScaleX(float) and View.setScaleY(float) directly.

If you want to understand better what's the difference between the layout and the rendered size/coordinates, I suggest you to run this layout:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <View
        android:id="@+id/redSquare"
        android:layout_width="48dp"
        android:layout_height="48dp"
        android:layout_centerHorizontal="true"
        android:background="#ffff0000" />


    <View
        android:id="@+id/blackSquare"
        android:layout_width="48dp"
        android:layout_height="48dp"
        android:layout_below="@+id/redSquare"
        android:layout_centerHorizontal="true"
        android:background="#ff000000" />

    <View
        android:id="@+id/blueSquare"
        android:layout_width="48dp"
        android:layout_height="48dp"
        android:layout_below="@+id/redSquare"
        android:layout_centerHorizontal="true"
        android:scaleX="2"
        android:scaleY="2"
        android:background="#550000ff" />

</RelativeLayout>

As you can see, the black square is positioned just below the red one. The blue square on the other hand, is overlapping the red one, even if it has the same attribute android:layout_below="@+id/redSquare". This is happening because scaleX and scaleY are not changing the position of the blue square, so the blue square is below the red square in the layout, but when redendered its size is scaled by a factor of 2 and therefore overlaps the red square

Upvotes: 5

Related Questions