listview调用getview为什么会执行三次??
@OverrideprotectedvoidonCreate(BundlesavedInstanceState){//TODOAuto-generatedmethodst...
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.homepage_list);
ListView listView = (ListView) findViewById(R.id.tab_homepage_list);
ArrayList<MicroBlogHP> listBlog = new ArrayList<MicroBlogHP>();
for (int i = 0; i < 50; i++) {
MicroBlogHP blog = new MicroBlogHP();
blog.setContent("content" + i);
blog.setUserName("name" + i);
listBlog.add(blog);
}
System.out.println("listBog size is " + listBlog.size());
MyAdapter adapter = new MyAdapter(Test3.this, listBlog);
listView.setAdapter(adapter);
}
private class MyAdapter extends BaseAdapter {
private ArrayList<MicroBlogHP> mData;
private LayoutInflater inflater;
private Context context;
public MyAdapter(Context context, ArrayList<MicroBlogHP> list) {
this.mData = list;
this.context = context;
// inflater = (LayoutInflater)
// getSystemService(Context.LAYOUT_INFLATER_SERVICE);
inflater = LayoutInflater.from(context);
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return mData.size();
}
@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return mData.get(position);
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
System.out.println("position-->" + position + ",convertView===>"
+ convertView);
String content = mData.get(position).getContent();
String name = mData.get(position).getUserName();
ViewHolder holder = null;
if (convertView == null) {
convertView = inflater.inflate(R.layout.homepage_item, null);
holder = new ViewHolder();
holder.tvContent = (TextView) convertView
.findViewById(R.id.hp_microBlogContent);
holder.tvName = (TextView) convertView
.findViewById(R.id.hp_username);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.tvContent.setText(content);
holder.tvName.setText(name);
return convertView;
}
}
private static class ViewHolder {
private TextView tvContent, tvName;
} 展开
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.homepage_list);
ListView listView = (ListView) findViewById(R.id.tab_homepage_list);
ArrayList<MicroBlogHP> listBlog = new ArrayList<MicroBlogHP>();
for (int i = 0; i < 50; i++) {
MicroBlogHP blog = new MicroBlogHP();
blog.setContent("content" + i);
blog.setUserName("name" + i);
listBlog.add(blog);
}
System.out.println("listBog size is " + listBlog.size());
MyAdapter adapter = new MyAdapter(Test3.this, listBlog);
listView.setAdapter(adapter);
}
private class MyAdapter extends BaseAdapter {
private ArrayList<MicroBlogHP> mData;
private LayoutInflater inflater;
private Context context;
public MyAdapter(Context context, ArrayList<MicroBlogHP> list) {
this.mData = list;
this.context = context;
// inflater = (LayoutInflater)
// getSystemService(Context.LAYOUT_INFLATER_SERVICE);
inflater = LayoutInflater.from(context);
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return mData.size();
}
@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return mData.get(position);
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
System.out.println("position-->" + position + ",convertView===>"
+ convertView);
String content = mData.get(position).getContent();
String name = mData.get(position).getUserName();
ViewHolder holder = null;
if (convertView == null) {
convertView = inflater.inflate(R.layout.homepage_item, null);
holder = new ViewHolder();
holder.tvContent = (TextView) convertView
.findViewById(R.id.hp_microBlogContent);
holder.tvName = (TextView) convertView
.findViewById(R.id.hp_username);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.tvContent.setText(content);
holder.tvName.setText(name);
return convertView;
}
}
private static class ViewHolder {
private TextView tvContent, tvName;
} 展开
2个回答
2018-08-02 · 做真实的自己 用良心做教育
千锋教育
千锋教育专注HTML5大前端、JavaEE、Python、人工智能、UI&UE、云计算、全栈软件测试、大数据、物联网+嵌入式、Unity游戏开发、网络安全、互联网营销、Go语言等培训教育。
向TA提问
关注
展开全部
今天在做一个功能:在初始化ListView时,把第一行背景置为黄色,同时保存第一行对象,用于在点击其他行时将该行重新置为白色。
if(position==0){
convertView.setBackgroundColor(Color.YELLOW);
lastconvertView=convertView;
}
结果运行时发现第一行的颜色一直会是黄色而无法改变。调试了之后发现getView中 if(position==0) 居然会多次进入,最终导致的结果便是我最后一次取得的lastconvertView并非listview上面的第一行。网上查了之后发现原因是因为未固定listview的高度导致的,但是root cause却找不到说明。于是去翻阅了源码+大量调试,大概推算出了原因,在此记录。
首先是说明下ListView的显示机制,listview的机制是这样子的:
假如你有1000条数据,但是屏幕只能显示10条,那么当你第一次加载显示的时候,会先创建10个View,1-10,当你拖动Listview,使1隐藏而11显示的时候,系统会自动把填充1的View传递过来,注意看代码Adapter的getView方法
@Override
public View getView(final int position, View convertView, ViewGroup parent)
这里的converView就是1的view,一般的做法会把这个view拿来复用,作为11的view。
当我们固定listview的高度时(fill_parent或直接固定高度),那么listview很容易就能计算出容器内可以显示多少行。但如果我们使用了“wrap_content”,只有在屏幕内控件完全加载后才知道到底能显示多少行数据时,ListView自身便会做一些尝试性计算。在源码中可以发现一些叫做onMeasure的方法,目测是做此用处(源码略显复杂,没读透)。
当listview计算出屏幕一共需要多少行后,如果listview自身高度不变,那么它的容纳的行数就不会变,使用getChildCount()可以得到它的最大行数。
再回到原来的问题,为什么最后一次取得的结果不是listview的第一行呢? 将listview设置为“wrap_content”后用下面的测试代码,看下输出。
//获取当前listview的个数 相等输出个数和站点名 不相等输出个数和"无"
if(listView.getChildCount() == position)
{
//child个数 当前position位置 +站名
Log.i("", listView.getChildCount()+" "+position+" "+coordInfo.stationname);
}
else {
//child个数 当前position位置+无
Log.i("", listView.getChildCount()+" "+position+" "+"无");
}
if(position==0){
convertView.setBackgroundColor(Color.YELLOW);
lastconvertView=convertView;
}
结果运行时发现第一行的颜色一直会是黄色而无法改变。调试了之后发现getView中 if(position==0) 居然会多次进入,最终导致的结果便是我最后一次取得的lastconvertView并非listview上面的第一行。网上查了之后发现原因是因为未固定listview的高度导致的,但是root cause却找不到说明。于是去翻阅了源码+大量调试,大概推算出了原因,在此记录。
首先是说明下ListView的显示机制,listview的机制是这样子的:
假如你有1000条数据,但是屏幕只能显示10条,那么当你第一次加载显示的时候,会先创建10个View,1-10,当你拖动Listview,使1隐藏而11显示的时候,系统会自动把填充1的View传递过来,注意看代码Adapter的getView方法
@Override
public View getView(final int position, View convertView, ViewGroup parent)
这里的converView就是1的view,一般的做法会把这个view拿来复用,作为11的view。
当我们固定listview的高度时(fill_parent或直接固定高度),那么listview很容易就能计算出容器内可以显示多少行。但如果我们使用了“wrap_content”,只有在屏幕内控件完全加载后才知道到底能显示多少行数据时,ListView自身便会做一些尝试性计算。在源码中可以发现一些叫做onMeasure的方法,目测是做此用处(源码略显复杂,没读透)。
当listview计算出屏幕一共需要多少行后,如果listview自身高度不变,那么它的容纳的行数就不会变,使用getChildCount()可以得到它的最大行数。
再回到原来的问题,为什么最后一次取得的结果不是listview的第一行呢? 将listview设置为“wrap_content”后用下面的测试代码,看下输出。
//获取当前listview的个数 相等输出个数和站点名 不相等输出个数和"无"
if(listView.getChildCount() == position)
{
//child个数 当前position位置 +站名
Log.i("", listView.getChildCount()+" "+position+" "+coordInfo.stationname);
}
else {
//child个数 当前position位置+无
Log.i("", listView.getChildCount()+" "+position+" "+"无");
}
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询