Search code examples
androidandroid-imageviewandroid-scrollview

How to get ImageView full width when inside a HorizontalScrollView



I'm placing a very wide image inside a HorizontalScrollView.
The ImageView/ScrollView height is dynamic as I've set the height to 0dp and added constraints.
Since the ImageView's scale type is fitStart and adjustViewBounds is true - the image's width is being resized.

XML:

     <HorizontalScrollView
        android:id="@+id/mapScrollView"
        android:layout_width="wrap_content"
        android:layout_height="0dp"
        android:layout_marginBottom="10dp"
        app:layout_constraintBottom_toTopOf="@id/playButton"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <android.support.constraint.ConstraintLayout
            android:id="@+id/mapLayout"
            android:layout_width="wrap_content"
            android:layout_height="match_parent">

            <ImageView
                android:id="@+id/mapImage"
                android:layout_width="wrap_content"
                android:layout_height="0dp"
                android:adjustViewBounds="true"
                android:scaleType="fitStart"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toTopOf="parent" />

            <com.gigi.testmap.activities.quest.QuestMapPathView
                android:id="@+id/mapLinesView"
                android:layout_width="0dp"
                android:layout_height="0dp"
                app:layout_constraintBottom_toBottomOf="@id/mapImage"
                app:layout_constraintEnd_toEndOf="@id/mapImage"
                app:layout_constraintStart_toStartOf="@id/mapImage"
                app:layout_constraintTop_toTopOf="@id/mapImage" />

        </android.support.constraint.ConstraintLayout>

    </HorizontalScrollView>


I'm trying to get the ImageView width (total width, visible & invisible part). Getting the ScrollView total width will also help.
My goal is to place buttons on top of the map in positions calculated according to width & height of the rendered ImageView.

I'm loading the image using Glide:

final ImageView mapImage = mActivity.findViewById(R.id.mapImage);
Glide.with(mActivity).load(R.drawable.fullmap).into(mapImage);

mapImage.getViewTreeObserver().addOnGlobalLayoutListener(new 
ViewTreeObserver.OnGlobalLayoutListener() {
    @Override
    public void onGlobalLayout() {
        mapImage.getWidth(); // --> returns 0    
        mapImage.getViewTreeObserver()
             .removeOnGlobalLayoutListener(this);
    }
 });

I've tried getting the width using tree view observer's global layout listener but all I got is 0. The height is returned correctly though.

Any help will be much appreciated, Thank you very much.


Solution

  • It seems that the image is not fully rendered once the tree view global layout listener is first called (I guess it's because the image width is pretty big) - What I did was to have a check for the image width and only if greater than 0, remove the listener and continue with my code.

    final ImageView mapImage = mActivity.findViewById(R.id.mapImage);
            Glide.with(mActivity).load(R.drawable.fullmap).into(mapImage);
            mapImage.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
                @Override
                public void onGlobalLayout() {
                    if (mapImage.getWidth() > 0) {
                        mapImage.getViewTreeObserver().removeOnGlobalLayoutListener(this);
                        //continue width related code here
                    }
                }
            });
    

    Maybe not the prefect solution and there is a small delay until the image shows up - but it is ok for my use case.