我在Eclipse中收到以下警告:
"Unconditional layout inflation from view adapter: Should use View Holder pattern (use recycled view passed into this method as the second parameter) for smoother scrolling"
我使用的代码是:
class myadapter extends ArrayAdapter<String>
{
Context context;
int[] images;
String[] mytitle;
String[] mydescp;
myadapter(Context c, String[] tittle, int[] imgs, String[] desc)
{
super(c, R.layout.single_row, R.id.listView1, tittle);
this.context=c;
this.images=imgs;
this.mytitle= tittle;
this.mydescp=desc;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
LayoutInflater inflator = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View row = inflator.inflate(R.layout.single_row, parent, false);
ImageView myImage = (ImageView) row.findViewById(R.id.imageView1);
TextView myText = (TextView) row.findViewById(R.id.textView1);
TextView mydesc = (TextView) row.findViewById(R.id.textView2);
myImage.setImageResource(images[position]);
myText.setText(mytitle[position]);
mydesc.setText(mydescp[position]);
return row;
}
}
我在行中收到警告:查看row = inflator.inflate(R.layout.single_row,parent,false);
它导致我的Android应用程序强制关闭......我现在能做什么? 任何建议???
答案 0 :(得分:2)
您需要回收您的视图。系统关心的android只是可见的项目。因此,您必须回收未关注的行项目以重新用于新项目。 或者想象一下所涉及的缓存量。
@Override
public View getView(int position, View row, ViewGroup parent) {
// TODO Auto-generated method stub
if(row==null){
LayoutInflater inflator = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
row = inflator.inflate(R.layout.single_row, parent, false);
}
ImageView myImage = (ImageView) row.findViewById(R.id.imageView1);
TextView myText = (TextView) row.findViewById(R.id.textView1);
TextView mydesc = (TextView) row.findViewById(R.id.textView2);
myImage.setImageResource(images[position]);
myText.setText(mytitle[position]);
mydesc.setText(mydescp[position]);
return row;
}
答案 1 :(得分:1)
你应该重复使用视图而不是一次又一次地膨胀。这降低了性能。
从您的代码中
View row = inflator.inflate(R.layout.single_row, parent, false);
每次滚动时都会膨胀。要最大化性能,请使用
//re-use
if (row == null)
{
inflate code here
}
else
{
you already have a view `row`, just use it.
}
您可以看到row
第一次为空&amp;它会在视图row
中充气并存储它。但是,从下一次开始,它不会一次又一次地膨胀,而是使用View row
。 (重复利用)
“来自视图适配器的无条件布局膨胀:应使用View Holder模式(使用传递给此方法的循环视图作为第二个参数)以实现更流畅的滚动”
这不是错误,只是要求您使用ViewHolder
模式的警告。让我解释一下为什么它很重要。
没有ViewHolder
模式:
第一次加载时,convertView为null。我们必须通过findViewById()
来扩充我们的列表项布局并找到TextView。
第二次加载时,convertView不为null,好!我们不必再次膨胀它。但我们会再次使用findViewById()
。
以下次加载时,convertView绝对不是null。但findViewById()
经常被调用,它会起作用,但它会降低性能,特别是如果你的ListView中有很多项目和视图。
使用ViewHolder
设计模式:
第一次加载时,convertView为null。我们必须扩充列表项布局,实例化ViewHolder,通过findViewById()
找到TextView并将其分配给ViewHolder,并将ViewHolder设置为convertView的标记。
第二次加载时,convertView不为null,好!我们不必再次膨胀它。这是最好的事情,我们不必调用findViewById()
,因为我们现在可以通过ViewHolder访问TextView。
以下时间加载,convertView绝对不是null。 findViewById()
永远不会再被调用,这使得我们顺利地滚动ListView。
为什么要使用?
在滚动ListView期间,您的代码可能会经常调用findViewById()
,这会降低性能。即使适配器返回一个膨胀的视图以进行回收,您仍然需要查找元素并更新它们。围绕重复使用findViewById()
的方法是使用view holder
设计模式。
那么,ViewHolder
是什么?
ViewHolder
对象将每个组件视图存储在Layout的标记字段中,因此您可以立即访问它们,而无需重复查找它们。首先,您需要创建一个类来保存您的确切视图集。
如何使用?
创建一个单独的类ViewHolder&amp;声明你使用的是EditText,TextView等..
static class ViewHolder {
TextView text;
TextView timestamp;
ImageView icon;
ProgressBar progress;
int position;
}
然后填充ViewHolder并将其存储在布局中。
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) { // if convertView is null
convertView = mInflater.inflate(R.layout.mylayout,
parent, false);
holder = new ViewHolder();
// initialize views
convertView.setTag(holder); // set tag on view
} else {
holder = (ViewHolder) convertView.getTag();
// if not null get tag
// no need to initialize
}
//update views here
return convertView;
}
来源:
答案 2 :(得分:0)
您必须使用此代码
View row = convertView;
在这一行之前,
View row = inflator.inflate(R.layout.single_row, parent, false);
希望它有效..
答案 3 :(得分:0)
Hi Vinesh Senthilvel, 别担心 使用下面的代码,它将明确地解决您的问题,
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
LayoutInflater inflator = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View row = inflator.inflate(R.layout.single_row, null, false);
ImageView myImage = (ImageView) row.findViewById(R.id.imageView1);
TextView myText = (TextView) row.findViewById(R.id.textView1);
TextView mydesc = (TextView) row.findViewById(R.id.textView2);
myImage.setImageResource(images[position]);
myText.setText(mytitle[position]);
mydesc.setText(mydescp[position]);
return row;
}
如果问题仍然存在,那么发布logcat异常堆栈跟踪,我会帮助你
答案 4 :(得分:0)
还有另一种方法,您只需import android.view.LayoutInflater;
并获取父(ViewGroup)的上下文 - parent.getContext()
,它将起作用
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
View v = LayoutInflater.from(parent.getContext()).inflate(
R.layout.single_row, parent, false);