Rathiga Jesika
Rathiga Jesika

Reputation: 357

adding images in ListView shows out of memory

I'm creating the listView that contains image and text but unfortunately it will work for adding three images more than that it shows out of memory.I saw many questions like the same.but still i dint get any clear idea how to call the Bitmap functions within my code.

My code is here, help me to complete this task.

public class MainActivity extends AppCompatActivity {

String[] titles;
ListView list1;

int [] img = {R.drawable.meal11,R.drawable.meal12,R.drawable.mrngs1,R.drawable.mrngs2,R.drawable.lunch1,R.drawable.lunch2};
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    list1 = (ListView) findViewById(R.id.list);
    titles = new String[]{"BANANA & BERRY SMOOTHIE","COTTAGE CHEESE, AVOCADO & TOMATO TOAST","FRITTATA CAKES","CHOC PROTEIN BALLS","CHICKEN & SUNDRIED TOMATO SALAD","TUNA WRAP"};

    myAdapter adapter = new myAdapter(getApplicationContext(),titles,img);

    list1.setAdapter(adapter);




}

class myAdapter extends ArrayAdapter<String> {
    Context context;
    int[] imgs;
    String[] titles;
    myAdapter(Context context,String[] titles,int imgs[]) {
        super(context,R.layout.list_item,R.id.text,titles);
        this.context= context;
        this.imgs = imgs;
        this.titles = titles;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        View row = inflater.inflate(R.layout.list_item,parent,false);

        ImageView myImage = (ImageView) row.findViewById(R.id.image);

        TextView myText = (TextView) row.findViewById(R.id.texttitle);

        myImage.setImageResource(imgs[position]);

        myText.setText(titles[position]);

        return row;
    }
}}

xml code for mainActiviy.xml:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.sa.addimagelistview.MainActivity"
android:padding="0dp">

<ListView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/list">

</ListView>

xml code for list_item.xml:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal">
<LinearLayout
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:layout_weight="0.2">

    <ImageView
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:id="@+id/image"
        android:src="@drawable/meal11"/>
</LinearLayout>
<LinearLayout
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:layout_weight="0.8">


    <TextView
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:id="@+id/texttitle"
        android:textSize="20sp"
        android:text="@string/app_name"/>

</LinearLayout>
</LinearLayout>

Upvotes: 0

Views: 726

Answers (6)

Siddhesh Dighe
Siddhesh Dighe

Reputation: 2954

The issue here is that, images you are trying to add in your listview are large and after a certain time they exceed the default memory provided by android.
To over come this you have to scale the images down to the size you actually want them in

You can use Piccaso which does the scaling work on its own if you use fit()

All you have to do is this.

add the Picasso dependency in your gradle compile 'com.squareup.picasso:picasso:2.5.2' and then try this

Picasso
  .with(context)
  .load(your_image)
  .fit()
  // call .centerInside() or .centerCrop() to avoid a stretched image
  .into(your_imageview);

Upvotes: 2

WinHtaikAung
WinHtaikAung

Reputation: 414

Here is my modification on your adapter please try this one hope it would help :D

class myAdapter extends ArrayAdapter<String> {
    Context context;
    int[] imgs;
    String[] titles;
    myAdapter(Context context,String[] titles,int imgs[]) {
        super(context,R.layout.list_item,R.id.text,titles);
        this.context= context;
        this.imgs = imgs;
        this.titles = titles;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder holder;
        if(convertView!=null){
            holder=(ViewHolder) convertView.getTag();
        }else{
            LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

            convertView = inflater.inflate(R.layout.list_item,parent,false);

            holder = new ViewHolder(convertView);

            convertView.setTag(holder);
        }


        holder.myImage = (ImageView) convertView.findViewById(R.id.image);

        holder.myText = (TextView) convertView.findViewById(R.id.texttitle);

        myImage.setImageResource(imgs[position]);

        myText.setText(titles[position]);

        return convertView;
    }

    // somewhere else in your class definition
    static class ViewHolder {
        ImageView myImage;
        TextView myText;    
    }
}

Here is Reference for ViewHolder

Upvotes: 1

alzamon
alzamon

Reputation: 11

I had the same problem. It worked for me if I just opened the image in Gimp, scaled it down and exported it with loss of quality so that it took up less space.

Should be some better solution though since the image I had was only a couple of megabytes in the first place.

Upvotes: 0

Kush
Kush

Reputation: 1092

put in Mainfest--->

<application
        android:largeHeap="true"
    >
.....
   </application>

may it will help

Upvotes: 1

Kishan S. Rakholiya
Kishan S. Rakholiya

Reputation: 389

Don't use setImageResource() directly but, use libraries like Glide and Picasso which loads image very smoothly and do image caching to load it fast.

Glide Compile Line - compile 'com.github.bumptech.glide:glide:3.7.0'

Picasso Compile Line - compile 'com.squareup.picasso:picasso:2.5.2'

Glide Example:

Glide.with(context).load(imgs[position]).into(myImage);

Picasso Exaple:

Picasso.with(context).load(imgs[position]).into(myImage);

If you don't want to use libraries try this official Android Link.

Upvotes: 1

Saurabh Vardani
Saurabh Vardani

Reputation: 1861

You can do this with the help of picasso...

  Picasso.with(context)
                    .load(imgs[position])//load images into imageview
                    .placeholder(R.drawable.image_file)//default image
                    .into(myImage);

Upvotes: 1

Related Questions