Activity runs slow with a couple of ImageView-s

10,029

Solution 1

Problem is resolution of the image, if you can reduce resolution of the image then work fine, here is some example for reducing image resolution and size.

If you pass bitmap width and height then use below function.

    public Bitmap getResizedBitmap(Bitmap image, int bitmapWidth,
            int bitmapHeight) {
        return Bitmap.createScaledBitmap(image, bitmapWidth, bitmapHeight,
                true);
    } 

if you want bitmap ratio same and reduce bitmap size. then pass your maximum size bitmap. you can use this function

public Bitmap getResizedBitmap(Bitmap image, int maxSize) {
    int width = image.getWidth();
    int height = image.getHeight();

    float bitmapRatio = (float)width / (float) height;
    if (bitmapRatio > 0) {
        width = maxSize;
        height = (int) (width / bitmapRatio);
    } else {
        height = maxSize;
        width = (int) (height * bitmapRatio);
    }
    return Bitmap.createScaledBitmap(image, width, height, true);
}

or if you are using drawable resources then use this method

public Drawable resizeImage(int imageResource) {// R.drawable.large_image
    // Get device dimensions
    Display display = getWindowManager().getDefaultDisplay();
    double deviceWidth = display.getWidth();

    BitmapDrawable bd = (BitmapDrawable) this.getResources().getDrawable(
            imageResource);
    double imageHeight = bd.getBitmap().getHeight();
    double imageWidth = bd.getBitmap().getWidth();

    double ratio = deviceWidth / imageWidth;
    int newImageHeight = (int) (imageHeight * ratio);

    Bitmap bMap = BitmapFactory.decodeResource(getResources(), imageResource);
    Drawable drawable = new BitmapDrawable(this.getResources(),
            getResizedBitmap(bMap, newImageHeight, (int) deviceWidth));

    return drawable;
}

/************************ Resize Bitmap *********************************/
public Bitmap getResizedBitmap(Bitmap bm, int newHeight, int newWidth) {

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

    float scaleWidth = ((float) newWidth) / width;
    float scaleHeight = ((float) newHeight) / height;

    // create a matrix for the manipulation
    Matrix matrix = new Matrix();

    // resize the bit map
    matrix.postScale(scaleWidth, scaleHeight);

    // recreate the new Bitmap
    Bitmap resizedBitmap = Bitmap.createBitmap(bm, 0, 0, width, height,
            matrix, false);

    return resizedBitmap;
}

Solution 2

Actually this should not be an issue and these images are not so big to make you phone laggy. Take a look on other stuff you have in the application, it is possible there is some heavy operations (like DB writing/readin, API requests) right in UI thread.

If there is no such operations and you see such problems with the perfomance, try to set these images via some libraries, like Picasso.

Gradle dependency:

compile 'com.squareup.picasso:picasso:2.4.0'

And code will look like this:

Picasso.with(this).load(R.drawable.my_image).into(toolbar);

Share:
10,029
BabbevDan
Author by

BabbevDan

CS and ₿itcoin

Updated on July 30, 2022

Comments

  • BabbevDan
    BabbevDan almost 2 years

    I have an activity containing 4 images in total. They are all matching the resolution of a 1080x1920 device. When I run the activity with those images, which are loaded directly in my activity via the XML, it runs tremendously slow in my Genymotion emulator and lags on a real Android device.

    Here is the setup:

    <android.support.design.widget.AppBarLayout
    ...>
    <android.support.design.widget.CollapsingToolbarLayout
    ...>
    <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="200dp"
                android:orientation="vertical"
                app:layout_collapseMode="parallax">
    
                <ImageView
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:id="@+id/imageView"
                    android:src="@drawable/shot_header"
                    android:scaleType="centerCrop" />
    
     </LinearLayout>
     <android.support.v7.widget.Toolbar
                .../>
     </android.support.design.widget.CollapsingToolbarLayout>
     </android.support.design.widget.AppBarLayout>
    

    The first image is in a CollapsingToolbarlayout. The resolution of the image is 1080x649 PNG.

    The content_activity:
    This image fills the parent width.It's resolution is 1080x772 PNG.

     <ImageView
        android:layout_width="match_parent"
        android:layout_height="250dp"
        android:id="@+id/main_image"
        android:layout_below="@+id/shot_error_field"
        android:src="@drawable/forehand_midpng"
        android:adjustViewBounds="true"
        android:scaleType="centerCrop"
        android:layout_marginTop="15dp"/>
    

    The other 2 images are in a LinearLayout, their resolution is 500x399

    <LinearLayout
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/main_image">
    
        <ImageView
            android:layout_width="150dp"
            android:layout_height="150dp"
            android:id="@+id/imageView3"
            android:src="@drawable/forehand_mid_wrong"
            android:layout_weight="1"/>
    
        <View
            android:layout_width="0dp"
            android:layout_height="1dp"
            android:layout_weight="1" >
        </View>
    
        <ImageView
            android:layout_width="150dp"
            android:layout_height="150dp"
            android:id="@+id/imageView4"
            android:src="@drawable/forehand_mid_wrong"
            android:layout_weight="1"/>
    </LinearLayout>
    

    To summarize, I have an activity with 4 ImageViews, populated with properly sized images, which should no problem for a modern Android device. The problem is that this activity is running extremely slow and lagging due to a high memory consumption.

    Am I doing something wrong? How can I further optimize those images?

    I looked into other threads- out of memory issue but none seems to propose a solution to such a problem.

  • BabbevDan
    BabbevDan over 8 years
    The size of my images is low. The largest is 351 KB
  • Amit Vaghela
    Amit Vaghela over 8 years
    that is reason. it should be evenless than that for smooth working
  • BabbevDan
    BabbevDan over 8 years
    Excellent! The resizeImage() method worked perefctly
  • Big_Chair
    Big_Chair about 5 years
    Damn, thank you so much for that resizeImage() function man! Got my activity with a huge background running super smooth now.