Search code examples
androidandroid-layoutimageviewcropimage-resizing

Android Studio: Load ImageView after layout change to proper layout


I have an Activity that will scroll through a list of pictures, showing either a fullscreen picture (by default, when entering the activity) or the picture with some details below it. I do that by changing the visibility of the FrameLayout containing the details.

When the picture is in fullscreen, I want to see all of it, so I load it with Glide as such; when I want to see the details, I load it with centerCrop(). The problem is that when I want to reload the picture (from fullscreen mode to details mode), the imageView keeps the old layout, and uses centerCrop() on that (since the example is a screenshot from the same device, it does nothing).

If I just scroll to the next picture and back while in details mode, it works as intended. I tried some of the stuff from other posts (AsyncTast, invalidate, requestLayout), but none seem to work.

On swiping upwards from the fullscreen mode:

what I get: What I want:

The layout of the activity:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    <!-- irrelevant stuff -->
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <FrameLayout
        android:id="@+id/frameLayoutZoomImage"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_weight="2">

        <com.example.gallery_app.customViews.ZoomImageView
            android:id="@+id/fullscreen_ImageView"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_gravity="center" />

        <!-- a layout on top of the ImageView that contains some hidden buttons-->
    </FrameLayout>

    <FrameLayout
        android:id="@+id/detail_split_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_weight="3">

        <include
            layout="@layout/activity_image_detail"
            android:layout_height="match_parent"
            android:layout_width="match_parent" />
    </FrameLayout>
</LinearLayout>

Solution

  • Figured it out (kind of), so I thought I'd write it for anyone in the same situation. Since what you need is for the activity to recalculate the layouts and then run the code related to loading in the picture, it works if you use a handler, like so:

    import android.os.Bundle
    class FullscreenImageActivity : AppCompatActivity(), MyFlingListener{
      private val handler = Handler()
      private val loadSplitScreenPictureRunnable = Runnable {
        //code that loads the inageView
      }
    
      private fun loadSplitScreenPicture(){
        handler.post(loadSplitScreenPictureRunnable)
        //there is no need to use postDelayed
      }
    }
    

    The obvious disadvantage with this method is that there is a visible split second before the handler executes the Runnable, especially if the picture is not already cached. If anyone finds a better method, please let me know.