我为listview创建了customadapter。当我慢慢滚动时工作正常但是,我正在滚动快速应用程序崩溃。我看了一些关于这个的解决方案,但我不明白。我想我需要添加getViewTypeCount和getItemViewType,但我无法正确添加这些。
此处所有代码; 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
抱歉,我在pastebin中提供代码,因为它太长了,我在Customadapter中尝试了这段代码,但它没有用
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;
}
答案 0 :(得分:1)
使用
public View getView(int position, View convertView, ViewGroup parent)
利用convertView
来节省内存使用量。
这是一篇很好的文章performance-tips-for-androids-listview。
答案 1 :(得分:1)
您需要创建ViewHolder
来快速滚动列表。这只是该持有人需要看起来如何的暗示:
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;
}
}
答案 2 :(得分:0)
您在适配器中加载的图像位图很可能很大,因此内存不足。
imageView.setImageResource(imageId[position]);
您也不会缓存任何内容。您基本上为列表视图中的每个项目分配一个新的位图(图像),因此会快速耗尽内存。
使用Picasso或Glide有效处理图片加载。另外你应该考虑调整原始图像的尺寸(质量较差,图像尺寸较小等),以免在OutOfMemoryExceptions中运行得太快......
答案 3 :(得分:0)
尝试查看RecyclerView,它会强制执行Holder模式,并且您不太可能遇到内存问题。同样如Sockeqwe所建议的那样,你应该尝试使用Picasso来制作你的图像。
http://developer.android.com/training/material/lists-cards.html(recyclerview) http://square.github.io/picasso/