简体   繁体   中英

ListView crashes while fast scrolling

i created customadapter for listview.Its working fine when im slowly scrolling but, i while im scrolling fast app is crashes. I looked some solutions about this but i dont get it. I think i need to add getViewTypeCount and getItemViewType but i couldnt add these ones properly.

All codes here; http://pastebin.com/BZB9G9p7

CustomAdapter.java

package com.example.mete.cocuksarkilari;

import android.app.Activity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;

public class CustomAdapter extends ArrayAdapter<String>{

private final int VIEW_TYPE_STRING = 0;
private final int VIEW_TYPE_IMAGE = 1;
private final Activity context;
private final String[] names;
private final Integer[] imageId;

public CustomAdapter(Activity context, String[] names, Integer[] imageId) {
    super(context, R.layout.custom_row,names);
    this.context = context;
    this.names = names;
    this.imageId = imageId;

}

@Override
public int getViewTypeCount() {
    return 2;
}

@Override
public int getItemViewType(int position) {
    return (position == 0) ? VIEW_TYPE_STRING :VIEW_TYPE_IMAGE;
}

@Override
public View getView(int position, View view, ViewGroup parent) {
    LayoutInflater inflater = context.getLayoutInflater();
    View rowView= inflater.inflate(R.layout.custom_row, null, true);
    TextView txtTitle = (TextView) rowView.findViewById(R.id.textView);

    ImageView imageView = (ImageView) rowView.findViewById(R.id.imageView);
    txtTitle.setText(names[position]);

   try{
       imageView.setImageResource(imageId[position]);
   }catch (Exception e){

   }

    return rowView;
 }
}

LOG

02-01 17:22:51.001  14221-14221/com.example.mete.cocuksarkilari E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.example.mete.cocuksarkilari, PID: 14221
java.lang.OutOfMemoryError: Failed to allocate a 8087052 byte allocation with 2036816 free bytes and 1989KB until OOM
        at dalvik.system.VMRuntime.newNonMovableArray(Native Method)
        at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method)
        at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:609)
        at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:444)
        at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:988)
        at android.content.res.Resources.loadDrawableForCookie(Resources.java:2474)
        at android.content.res.Resources.loadDrawable(Resources.java:2381)
        at android.content.res.Resources.getDrawable(Resources.java:787)
        at android.content.Context.getDrawable(Context.java:403)
        at android.support.v4.content.ContextCompatApi21.getDrawable(ContextCompatApi21.java:26)
        at android.support.v4.content.ContextCompat.getDrawable(ContextCompat.java:321)
        at android.support.v7.widget.TintManager.getDrawable(TintManager.java:175)
        at android.support.v7.widget.TintManager.getDrawable(TintManager.java:168)
        at android.support.v7.widget.AppCompatImageHelper.setImageResource(AppCompatImageHelper.java:51)
        at android.support.v7.widget.AppCompatImageView.setImageResource(AppCompatImageView.java:72)
        at com.example.mete.cocuksarkilari.CustomAdapter.getView(CustomAdapter.java:47)
        at android.widget.AbsListView.obtainView(AbsListView.java:2347)
        at android.widget.ListView.makeAndAddView(ListView.java:1864)
        at android.widget.ListView.fillDown(ListView.java:698)
        at android.widget.ListView.fillGap(ListView.java:662)
        at android.widget.AbsListView.trackMotionScroll(AbsListView.java:4991)
        at android.widget.AbsListView.scrollIfNeeded(AbsListView.java:3418)
        at android.widget.AbsListView.onTouchMove(AbsListView.java:3801)
        at android.widget.AbsListView.onTouchEvent(AbsListView.java:3632)
        at android.view.View.dispatchTouchEvent(View.java:8471)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2399)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2092)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2405)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2106)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2405)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2106)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2405)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2106)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2405)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2106)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2405)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2106)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2405)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2106)
        at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:2369)
        at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1719)
        at android.app.Activity.dispatchTouchEvent(Activity.java:2742)
        at android.support.v7.view.WindowCallbackWrapper.dispatchTouchEvent(WindowCallbackWrapper.java:60)
        at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:2330)
        at android.view.View.dispatchPointerEvent(View.java:8666)
        at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:4123)
        at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:3989)
        at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3544)
        at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3597)
        at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3563)
        at     android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:3680)
        at android.view.ViewRootImpl$InputSta

Sorry i give codes in pastebin because its too long and I try this code in Customadapter but it didnt work

private final int VIEW_TYPE_STRING = 0;
private final int VIEW_TYPE_IMAGE = 1;


@Override
public int getViewTypeCount() {
    return 2;
}

@Override
public int getItemViewType(int position) {
    return (position == 0) ? VIEW_TYPE_STRING :VIEW_TYPE_IMAGE;
}

Use

public View getView(int position, View convertView, ViewGroup parent)

And utilize the convertView to conserve your memory usage.

Here's a good article performance-tips-for-androids-listview .

You need to create ViewHolder for scrolling fast your list. This is just a hint how that holder needs to look like:

public CustomAdapter(Activity context, String[] names, Integer[] imageId) {
    super(context, R.layout.custom_row,names);
    this.context = context;
    this.names = names;
    this.imageId = imageId;

}

static class MyViewHolder{
    TextView txtTitle;

MyViewHolder(View v){
            txtTitle = (TextView) v.findViewById(R.id.YourTextView);        

        }
    }

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

        View row=convertView;
        MyViewHolder holder=null;
        if(row==null){      
        LayoutInflater inf=(LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        row=inf.inflate(R.layout.your_row, parent, false);
        holder=new MyViewHolder(row);
        row.setTag(holder);

        }else{
            holder=(MyViewHolder) row.getTag();
        }           
        holder.txtTitle.setText(names[position]);
        return row;
    }   
}   

Most likely the image bitmap you are loading in your adapter is to big and therefore you run out of memory.

imageView.setImageResource(imageId[position]);

You also don't cache anything. You basically allocate a new bitmap (image) for each item in your listview and therefore run out of memory quickly.

Use Picasso or Glide to handle image loading efficiently. Also you should think about resizing the original image (less quality, less image size etc.) to not run too fast into OutOfMemoryExceptions ...

Try to look at RecyclerView, it enforces the Holder pattern and you are less likely to get memory issues. Also as suggested by Sockeqwe, you should try using Picasso for your images.

http://developer.android.com/training/material/lists-cards.html (recyclerview) http://square.github.io/picasso/

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM