ArrayAdapter 中的错误 - 布局充气器抛出错误
Error in ArrayAdapter - layout inflator thows error
我在 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;
}
}
我在行中收到警告:View row = inflator.inflate(R.layout.single_row, parent, false);
它会导致我的 android 应用程序强制关闭...我现在该怎么办?
有什么建议吗???
您必须使用此代码
View row = convertView;
在这一行之前,
View row = inflator.inflate(R.layout.single_row, parent, false);
希望它有用..
嗨 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;
}
如果问题仍然存在,那么 post logcat 异常堆栈跟踪,我会帮助你
您需要回收 views.What android 因为系统只关心 visible.So 您必须回收未聚焦的行项目重新用于新项目。
或者想象一下所涉及的缓存量。
@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;
}
还有另一种方法,您只需要 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);
您应该重新使用视图而不是一次又一次地膨胀。这会降低性能。
根据您的代码,
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
将为 null & 它会膨胀并将其存储在视图 row
中。但是,从下一次开始,它不会一次又一次地膨胀,而是使用视图 row
。 (重复使用)
"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"
这不是错误,它只是要求您使用 ViewHolder
模式的警告。让我来解释一下为什么它很重要。
没有 ViewHolder
模式:
第一次加载时,convertView为null。我们必须扩充我们的列表项布局并通过 findViewById()
.
找到 TextView
第二次加载,convertView不为null,good!我们不必再次给它充气。但我们将再次使用 findViewById()
。
以后加载的时候,convertView肯定不为null。但是 findViewById()
会不断被调用,它会起作用,但是会降低性能,尤其是当您的 ListView 中有很多项目和视图时。
使用 ViewHolder
设计模式:
第一次加载时,convertView为null。我们必须膨胀我们的列表项布局,实例化 ViewHolder,通过 findViewById()
找到 TextView 并将其分配给 ViewHolder,并将 ViewHolder 设置为 convertView 的标签。
第二次加载,convertView不为null,good!我们不必再次给它充气。这是一件好事,我们不必调用 findViewById()
,因为我们现在可以通过其 ViewHolder 访问 TextView。
下次加载时,convertView肯定不为null。 findViewById()
再也不会被调用,这使得我们的 ListView 滚动流畅。
为什么要用?
您的代码可能会在 ListView 滚动期间频繁调用 findViewById()
,这会降低性能。即使当 Adapter returns 一个用于回收的膨胀视图时,您仍然需要查找元素并更新它们。避免重复使用 findViewById()
的一种方法是使用 view holder
设计模式。
那么,什么是ViewHolder
?
一个 ViewHolder
对象将每个组件视图存储在 Layout 的标记字段中,因此您可以立即访问它们而无需重复查找它们。首先,您需要创建一个 class 来保存您的确切视图集。
如何使用?
创建一个单独的 class 作为 ViewHolder 并声明您使用的内容,如 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;
}
来源:
我在 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;
}
}
我在行中收到警告:View row = inflator.inflate(R.layout.single_row, parent, false);
它会导致我的 android 应用程序强制关闭...我现在该怎么办? 有什么建议吗???
您必须使用此代码
View row = convertView;
在这一行之前,
View row = inflator.inflate(R.layout.single_row, parent, false);
希望它有用..
嗨 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;
}
如果问题仍然存在,那么 post logcat 异常堆栈跟踪,我会帮助你
您需要回收 views.What android 因为系统只关心 visible.So 您必须回收未聚焦的行项目重新用于新项目。 或者想象一下所涉及的缓存量。
@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;
}
还有另一种方法,您只需要 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);
您应该重新使用视图而不是一次又一次地膨胀。这会降低性能。
根据您的代码,
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
将为 null & 它会膨胀并将其存储在视图 row
中。但是,从下一次开始,它不会一次又一次地膨胀,而是使用视图 row
。 (重复使用)
"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"
这不是错误,它只是要求您使用 ViewHolder
模式的警告。让我来解释一下为什么它很重要。
没有 ViewHolder
模式:
第一次加载时,convertView为null。我们必须扩充我们的列表项布局并通过
findViewById()
. 找到 TextView
第二次加载,convertView不为null,good!我们不必再次给它充气。但我们将再次使用
findViewById()
。以后加载的时候,convertView肯定不为null。但是
findViewById()
会不断被调用,它会起作用,但是会降低性能,尤其是当您的 ListView 中有很多项目和视图时。
使用 ViewHolder
设计模式:
第一次加载时,convertView为null。我们必须膨胀我们的列表项布局,实例化 ViewHolder,通过
findViewById()
找到 TextView 并将其分配给 ViewHolder,并将 ViewHolder 设置为 convertView 的标签。第二次加载,convertView不为null,good!我们不必再次给它充气。这是一件好事,我们不必调用
findViewById()
,因为我们现在可以通过其 ViewHolder 访问 TextView。下次加载时,convertView肯定不为null。
findViewById()
再也不会被调用,这使得我们的 ListView 滚动流畅。
为什么要用?
您的代码可能会在 ListView 滚动期间频繁调用 findViewById()
,这会降低性能。即使当 Adapter returns 一个用于回收的膨胀视图时,您仍然需要查找元素并更新它们。避免重复使用 findViewById()
的一种方法是使用 view holder
设计模式。
那么,什么是ViewHolder
?
一个 ViewHolder
对象将每个组件视图存储在 Layout 的标记字段中,因此您可以立即访问它们而无需重复查找它们。首先,您需要创建一个 class 来保存您的确切视图集。
如何使用?
创建一个单独的 class 作为 ViewHolder 并声明您使用的内容,如 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; }
来源: