滚动后 ListView 崩溃
ListView crashes after scrolling
我实现了一个无限滚动的 ListView,它工作得很好,但是在滚动 "couple" 之后,比方说 10,应用程序崩溃并出现此错误
java.lang.OutOfMemoryError
at java.util.ArrayList.addAll(ArrayList.java:194)
at android.widget.ArrayAdapter.addAll(ArrayAdapter.java:195)
at com.bellantoni.chetta.lieme.ProfileFragment.onScroll(ProfileFragment.java:300)
at android.widget.AbsListView.invokeOnItemScrollListener(AbsListView.java:1755)
at android.widget.AbsListView.trackMotionScroll(AbsListView.java:6554)
at android.widget.AbsListView.scrollIfNeeded(AbsListView.java:3664)
at android.widget.AbsListView.onTouchEvent(AbsListView.java:4492)
at android.view.View.dispatchTouchEvent(View.java:7690)
这是应用程序崩溃的代码部分
public void onScroll(AbsListView view,
int firstVisible, int visibleCount, int totalCount) {
boolean loadMore =
firstVisible + visibleCount >= totalCount;
if(loadMore) {
this.adapter.setCount(this.adapter.getCount()+8);
//NEXT LINE CRASHES
this.adapter.addAll(this.rows);
adapter.notifyDataSetChanged();
}
}
onScroll 方法在创建和填充列表的片段中实现。变量 rows
是我要放入的 List<>
。我的适配器是这样的
public class CustomListAdapter extends ArrayAdapter<RowItemProfile> {
private final Activity context;
private List<RowItemProfile> rows;
private int count = 8;
public CustomListAdapter(Activity context, List<RowItemProfile> rows ) {
super(context, R.layout.mylist, rows);
this.context = context;
this.rows = rows;
}
public View getView(int position, View view, ViewGroup parent) {
LayoutInflater inflater = context.getLayoutInflater();
View rowView = inflater.inflate(R.layout.mylist, null, true);
rowView.setPadding(0,10,0,10);
TextView txtTitle = (TextView) rowView.findViewById(R.id.nameList);
txtTitle.setTextColor(Color.BLACK);
ImageView imageView = (ImageView) rowView.findViewById(R.id.imgList);
TextView extratxt = (TextView) rowView.findViewById(R.id.question);
TextView idfacebook = (TextView) rowView.findViewById(R.id.facebookId);
txtTitle.setText(this.rows.get(position).getNameSurname());
imageView.setImageResource(this.rows.get(position).getIdImg());
extratxt.setText(this.rows.get(position).getQuestion());
idfacebook.setText(this.rows.get(position).getId());
return rowView;
}
@Override
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
}
我不明白为什么!
正在为每个项目在 getview 中创建对象,这可能会导致异常。为了 100% 高效的滚动和对象创建,请将您的 getview 方法替换为以下代码。
首先在 CustomListAdapter
的构造函数中初始化 LayoutInflater
对象
并在 CustomListAdapter
中创建一个新的内部 class ViewHolder
ViewHolder
class ViewHolder {
TextView txtTitle,idfacebook,extratxt ;
ImageView imageView ;
}
将您的 getview() 方法替换为
public View getView(int position, View convertView, ViewGroup parent) {
// Avoid unneccessary calls to findViewById() on each row, which is expensive!
ViewHolder holder;
/*
* If convertView is not null, we can reuse it directly, no inflation required!
* We only inflate a new View when the convertView is null.
*/
if (convertView == null) {
convertView = inflater.inflate(R.layout.list_item_pocket, null);
// Create a ViewHolder and store references to the two children views
holder = new ViewHolder();
holder.txtTitle = (TextView) convertView.findViewById(R.id.nameList);
holder.extratxt = (TextView) convertView.findViewById(R.id.question);
holder.idfacebook = (TextView) convertView.findViewById(R.id.facebookId);
holder. imageView = (ImageView) convertView.findViewById(R.id.imgList);
// The tag can be any Object, this just happens to be the ViewHolder
convertView.setTag(holder);
} else {
// Get the ViewHolder back to get fast access to the TextView
// and the ImageView.
holder = (ViewHolder) convertView.getTag();
}
// Bind that data efficiently!
holder.txtTitle.setTextColor(Color.BLACK);
holder.txtTitle.setText(this.rows.get(position).getNameSurname());
holder.imageView.setImageResource(this.rows.get(position).getIdImg());
holder.extratxt.setText(this.rows.get(position).getQuestion());
holder.idfacebook.setText(this.rows.get(position).getId());
return convertView;
}
如果它不能解决您的问题,那么您正在使用大尺寸的列表视图中的图像,那么您需要调整图像大小。希望对你有帮助。
尝试在getView()
方法之前添加这些方法
public int getCount() {
// return the length or size of your List rows
}
public Object getItem(int position) {
return null;
}
public long getItemId(int position) {
return 0;
}
我找到了解决方案,我 post 在这里,也许它对其他人有用。
我不知道为什么,但是这两件事的结合解决了我的问题:
- 使用 Picasso 库下载图片
- 一次只添加一个元素,而不是同时添加 8 个元素的列表(我认为最重要的一个)。
我实现了一个无限滚动的 ListView,它工作得很好,但是在滚动 "couple" 之后,比方说 10,应用程序崩溃并出现此错误
java.lang.OutOfMemoryError
at java.util.ArrayList.addAll(ArrayList.java:194)
at android.widget.ArrayAdapter.addAll(ArrayAdapter.java:195)
at com.bellantoni.chetta.lieme.ProfileFragment.onScroll(ProfileFragment.java:300)
at android.widget.AbsListView.invokeOnItemScrollListener(AbsListView.java:1755)
at android.widget.AbsListView.trackMotionScroll(AbsListView.java:6554)
at android.widget.AbsListView.scrollIfNeeded(AbsListView.java:3664)
at android.widget.AbsListView.onTouchEvent(AbsListView.java:4492)
at android.view.View.dispatchTouchEvent(View.java:7690)
这是应用程序崩溃的代码部分
public void onScroll(AbsListView view,
int firstVisible, int visibleCount, int totalCount) {
boolean loadMore =
firstVisible + visibleCount >= totalCount;
if(loadMore) {
this.adapter.setCount(this.adapter.getCount()+8);
//NEXT LINE CRASHES
this.adapter.addAll(this.rows);
adapter.notifyDataSetChanged();
}
}
onScroll 方法在创建和填充列表的片段中实现。变量 rows
是我要放入的 List<>
。我的适配器是这样的
public class CustomListAdapter extends ArrayAdapter<RowItemProfile> {
private final Activity context;
private List<RowItemProfile> rows;
private int count = 8;
public CustomListAdapter(Activity context, List<RowItemProfile> rows ) {
super(context, R.layout.mylist, rows);
this.context = context;
this.rows = rows;
}
public View getView(int position, View view, ViewGroup parent) {
LayoutInflater inflater = context.getLayoutInflater();
View rowView = inflater.inflate(R.layout.mylist, null, true);
rowView.setPadding(0,10,0,10);
TextView txtTitle = (TextView) rowView.findViewById(R.id.nameList);
txtTitle.setTextColor(Color.BLACK);
ImageView imageView = (ImageView) rowView.findViewById(R.id.imgList);
TextView extratxt = (TextView) rowView.findViewById(R.id.question);
TextView idfacebook = (TextView) rowView.findViewById(R.id.facebookId);
txtTitle.setText(this.rows.get(position).getNameSurname());
imageView.setImageResource(this.rows.get(position).getIdImg());
extratxt.setText(this.rows.get(position).getQuestion());
idfacebook.setText(this.rows.get(position).getId());
return rowView;
}
@Override
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
}
我不明白为什么!
正在为每个项目在 getview 中创建对象,这可能会导致异常。为了 100% 高效的滚动和对象创建,请将您的 getview 方法替换为以下代码。
首先在 CustomListAdapter
的构造函数中初始化 LayoutInflater
对象
并在 CustomListAdapter
ViewHolder
ViewHolder
class ViewHolder {
TextView txtTitle,idfacebook,extratxt ;
ImageView imageView ;
}
将您的 getview() 方法替换为
public View getView(int position, View convertView, ViewGroup parent) {
// Avoid unneccessary calls to findViewById() on each row, which is expensive!
ViewHolder holder;
/*
* If convertView is not null, we can reuse it directly, no inflation required!
* We only inflate a new View when the convertView is null.
*/
if (convertView == null) {
convertView = inflater.inflate(R.layout.list_item_pocket, null);
// Create a ViewHolder and store references to the two children views
holder = new ViewHolder();
holder.txtTitle = (TextView) convertView.findViewById(R.id.nameList);
holder.extratxt = (TextView) convertView.findViewById(R.id.question);
holder.idfacebook = (TextView) convertView.findViewById(R.id.facebookId);
holder. imageView = (ImageView) convertView.findViewById(R.id.imgList);
// The tag can be any Object, this just happens to be the ViewHolder
convertView.setTag(holder);
} else {
// Get the ViewHolder back to get fast access to the TextView
// and the ImageView.
holder = (ViewHolder) convertView.getTag();
}
// Bind that data efficiently!
holder.txtTitle.setTextColor(Color.BLACK);
holder.txtTitle.setText(this.rows.get(position).getNameSurname());
holder.imageView.setImageResource(this.rows.get(position).getIdImg());
holder.extratxt.setText(this.rows.get(position).getQuestion());
holder.idfacebook.setText(this.rows.get(position).getId());
return convertView;
}
如果它不能解决您的问题,那么您正在使用大尺寸的列表视图中的图像,那么您需要调整图像大小。希望对你有帮助。
尝试在getView()
方法之前添加这些方法
public int getCount() {
// return the length or size of your List rows
}
public Object getItem(int position) {
return null;
}
public long getItemId(int position) {
return 0;
}
我找到了解决方案,我 post 在这里,也许它对其他人有用。 我不知道为什么,但是这两件事的结合解决了我的问题:
- 使用 Picasso 库下载图片
- 一次只添加一个元素,而不是同时添加 8 个元素的列表(我认为最重要的一个)。