Shimmer Effect not working on Height wrap_content

2.9k views Asked by At

I'm trying to implement the shimmer effect with the Height of wrap_content but the images are not loading, I know why it is not loading the images because the imageView has wrap_content and the shimmer also has wrap_content but I want the Height Should be wrap_content and not fixed.

After implementing a fixed height of eg 200dp in shimmer it works but after that images are not loading

I want to make it like Pinterest where the height is adjusted according to the image

XML Files

post_item_container_search.xml

<com.google.android.material.imageview.ShapeableImageView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/imagePostSearch"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginStart="6dp"
    android:layout_marginTop="11dp"
    android:layout_marginEnd="6dp"
    android:contentDescription="@string/todo"
    app:shapeAppearanceOverlay="@style/RoundedCorner" />

post_item_containe_shimmer.xml

<com.google.android.material.imageview.ShapeableImageView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/imageShimmer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="11dp"
android:layout_marginTop="11dp"
android:background="#E7E7E7"
android:contentDescription="@string/todo"
app:shapeAppearanceOverlay="@style/RoundedCorner" />

this how it looks like after adding minHeight to both or in actual imageView

this how it looks like after adding minHeight to both or in actual imageView

4

There are 4 answers

4
Darkman On BEST ANSWER

After implementing a fixed height of eg 200dp in shimmer it works but after that images are not loading

In that case, you should probably set an absolute width/height for the ImageView first. Later, you can set it back to WARP_CONTENT if you really need to. But first you'll need an estimated/absolute width/height for the view.

int height = bitmap.getHeight();
int width = bitmap.getWidth();

ShapeableImageView siv = findViewById(R.id.imagePostSearch);
ViewGroup.LayoutParams params = siv.getLayoutParams();
params.height = height;
params.width = width;

//To set it back to warp content or match parent:
params.height = ViewGroup.LayoutParams.WRAP_CONTENT;
params.width = ViewGroup.LayoutParams.MATCH_PARENT;
0
Dheeraj Gupta On

By default, the wrapcontent doesn't have any size so it is 0dp you need to define 50dp or something for the height of shimmer then only you can see the shimmering.

Can refer this blog or try to use this

post_item_container_search.xml

 <com.google.android.material.imageview.ShapeableImageView
 xmlns:android="http://schemas.android.com/apk/res/android"
         android:id="@+id/imagePostSearch"
         android:layout_width="200dp"
         android:layout_height="200dp"
         android:scaleType="fitCenter"
         android:layout_marginStart="6dp"
         android:layout_marginTop="11dp"
         android:layout_marginEnd="6dp"
         android:contentDescription="@string/todo"
         app:shapeAppearanceOverlay="@style/RoundedCorner" />
8
Mohit Ajwani On

Please keep android:minHeight for the ImageView as it will give you a minimum height and also android:height can be wrap_content so it grows if the image is larger than minHeight.

For example,

<com.google.android.material.imageview.ShapeableImageView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/imageShimmer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="100dp"
android:layout_marginStart="11dp"
android:layout_marginTop="11dp"
android:background="#E7E7E7"
android:contentDescription="@string/todo"
app:shapeAppearanceOverlay="@style/RoundedCorner" />

2
sandeep dhami On

You can create a dummy view for shimmer with fixed height, make its visibility to visible and show it until the image loads, and once the image is loaded make the dummy view visibility gone.

//XML

<RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <shimmerView //You can use your own
            android:id="@+id/dummyShimmerView"
            android:layout_width="100dp"
            android:layout_height="100dp"/>

        <ImageView
            android:id="@+id/postImageView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:visibility="gone"/>

    </RelativeLayout>

//dummyShimmerView visibility is visible byDefault
Glide.with(context)
            .load(url)
            .listener(object : RequestListener<Drawable> {
                override fun onLoadFailed(e: GlideException?, model: Any?, target: Target<Drawable>?, isFirstResource: Boolean): Boolean {
                    //TODO: something on exception
                }
                override fun onResourceReady(resource: Drawable?, model: Any?, target: Target<Drawable>?, dataSource: DataSource?, isFirstResource: Boolean): Boolean {
                    Log.d(TAG, "OnResourceReady")
                    dummyShimmerView.visibility = View.GONE
                    postImageView.visibility = View.VISIBLE
                    return false
                }
            })
            .into(imgView)