Android ListView 适配器加载错误
Posted
技术标签:
【中文标题】Android ListView 适配器加载错误【英文标题】:Android ListView adapter loads wrong 【发布时间】:2014-04-18 11:24:04 【问题描述】:由于某种原因,当我使用此代码时,它无法正常工作。它不是将每个十字路口放在它的位置上,而是将最后一个放在第一个十字路口,其余的都是空的。
package com.Itay.lightalaram.lightalarm;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.List;
public class Cros-s-roadsActivity extends Activity
private List<Cros-s-road> cros-s-roads;
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.cros-s-roads);
cros-s-roads = new ArrayList<Cros-s-road>();
populateListView();
private void populateListView()
ListView list = (ListView) findViewById(R.id.cros-s-roadsListView);
cros-s-roads.add(new Cros-s-road("Oranim", 50, 30));
cros-s-roads.add(new Cros-s-road("Evelina", 40, 85));
cros-s-roads.add(new Cros-s-road("Sacker", 43, 22));
cros-s-roads.add(new Cros-s-road("bagger", 43, 22));
ArrayAdapter<Cros-s-road> adapter = new Cros-s-roadAdapter();
list.setAdapter(adapter);
private class Cros-s-roadAdapter extends ArrayAdapter<Cros-s-road>
public Cros-s-roadAdapter()
super(Cros-s-roadsActivity.this, R.layout.item_cros-s-road, cros-s-roads);
@Override
public View getView(int position, View convertView, ViewGroup parent)
View itemView = convertView;
if(null == itemView)
itemView = getLayoutInflater().inflate(R.layout.item_cros-s-road, parent, false);
Cros-s-road currentCros-s-road = cros-s-roads.get(position);
TextView name = (TextView) findViewById(R.id.item_cros-s-roadName);
TextView redLight = (TextView) findViewById(R.id.item_redLightDuration);
TextView greenLight = (TextView) findViewById(R.id.item_greenLightDuration);
try
name.setText(currentCros-s-road.getName());
redLight.setText("" + currentCros-s-road.getRedLight());
greenLight.setText("" + currentCros-s-road.getGreenLight());
catch (Exception e)
return itemView;
return null;
输出:
【问题讨论】:
从您的Adapter
中删除 return null;
我用ViewHolder
模式更新了我的答案。你应该看看。编码愉快。
【参考方案1】:
说明
出现此问题的原因是您只设置了一次膨胀布局,此时 convertView
的条件为 null
。但是,在第一次itemView
之后,就不是null
。除了第一个之外,您的项目没有更新。此外,您需要返回列表项的所有视图 (itemView)。
解决方案
在您的适配器中,getView
方法需要扩展一个布局(once)并返回此布局:
// inflate the layout to the row (items)
View itemView = convertView;
if(null == itemView)
itemView = getLayoutInflater().inflate(R.layout.item_cros-s-road, parent, false);
// Then return the inflated view and all its stuff
return itemView;
此外,您需要将所有项目的视图附加到布局,如下所示:
// itemView.findViewById(...) to retrieve the id which is on the inflated layout
TextView name = (TextView) itemView.findViewById(R.id.item_cros-s-roadName);
最后,为了提高Adapter
的性能,您应该使用ViewHolder
。这将避免您永远调用所有 findViewById
方法。这是great tutorial 和a simple example。那么,你的方法可能是:
// Init your variables
public ViewHolder
TextView name, redLight, greenLight
@Override
public View getView(int position, View convertView, ViewGroup parent)
View itemView = convertView;
// create the ViewHolder variable
ViewHolderItem viewHolder;
if(itemView == null)
itemView = getLayoutInflater().inflate(R.layout.item_cros-s-road, parent, false);
// create a new ViewHolder
viewHolder = new ViewHolderItem();
// get your views with the ViewHolder and attached to the inflated layout
viewHolder.name = (TextView) itemView.findViewById(R.id.item_cros-s-roadName);
viewHolder.redLight = (TextView) itemView.findViewById(R.id.item_redLightDuration);
viewHolder.greenLight = (TextView) itemView.findViewById(R.id.item_greenLightDuration);
// store the ViewHolder
itemView.setTag(viewHolder);
else
// this is not the first, reuse the stored ViewHolder
viewHolder = (ViewHolderItem) convertView.getTag();
// do your stuff...
Cros-s-road currentCros-s-road = cros-s-roads.get(position);
try
viewHolder.name.setText(currentCros-s-road.getName());
viewHolder.redLight.setText("" + currentCros-s-road.getRedLight());
viewHolder.greenLight.setText("" + currentCros-s-road.getGreenLight());
catch (Exception e)
// return the layout inflated
return itemView;
【讨论】:
【参考方案2】: private class Cros-s-roadAdapter extends ArrayAdapter<Cros-s-road>
public Cros-s-roadAdapter()
super(MainActivity.this, R.layout.item_cros-s-road, cros-s-roads);
TextView name, redLight, greenLight;
@Override
public View getView(int position, View convertView, ViewGroup parent)
View itemView = convertView;
Cros-s-road currentCros-s-road = cros-s-roads.get(position);
if (null == itemView)
itemView = getLayoutInflater().inflate(R.layout.item_cros-s-road,
parent, false);
name = (TextView) itemView
.findViewById(R.id.item_cros-s-roadName);
redLight = (TextView) itemView
.findViewById(R.id.item_redLightDuration);
greenLight = (TextView) itemView
.findViewById(R.id.item_greenLightDuration);
try
name.setText(currentCros-s-road.getName());
redLight.setText("" + currentCros-s-road.getRedLight());
greenLight.setText("" + currentCros-s-road.getGreenLight());
catch (Exception e)
return itemView;
【讨论】:
我不认为这是一个正确的答案:第一个文本视图没有附加到膨胀的布局上。第二个更多的内容和解释将非常感激。谢谢。【参考方案3】:将getview方法改为
public View getView(int position, View convertView, ViewGroup parent)
View itemView = convertView;
if(null == itemView)
itemView = getLayoutInflater().inflate(R.layout.item_cros-s-road, parent, false);
Cros-s-road currentCros-s-road = cros-s-roads.get(position);
TextView name = (TextView) itemView.findViewById(R.id.item_cros-s-roadName);
TextView redLight = (TextView) itemView.findViewById(R.id.item_redLightDuration);
TextView greenLight = (TextView) itemView.findViewById(R.id.item_greenLightDuration);
name.setText(currentCros-s-road.getName());
redLight.setText("" + currentCros-s-road.getRedLight());
greenLight.setText("" + currentCros-s-road.getGreenLight());
return itemView;
评论我的结果
【讨论】:
以上是关于Android ListView 适配器加载错误的主要内容,如果未能解决你的问题,请参考以下文章
android listview 适配器 asynctask 图像加载
android从listview中删除任何项目删除最后一个元素
在android(初级)的Listview上延迟加载图像? [复制]