我花了大约3个小时跟踪以下问题:
我有一个带有用户定义项的ListView,其中包含图像和标签。图像在一个单独的线程中加载,完成后会向UI线程发送通知,因此可以更新ImageView。
以下是我认为相关的代码段:
public final class IconListAdapter extends BaseAdapter
{
...
public static final class Item
{
final StandardIcon standardIcon;
Bitmap albumIcon;
final String label;
ImageView albumIconObserver;
...
public Item(final File iconFile)
{
if (iconFile != null)
{
new Thread()
{
public void run()
{
synchronized (IconListAdapter.class)
{
albumIcon = BitmapFactory.decodeFile(iconFile.getPath());
if (handler != null && albumIconObserver != null && albumIcon != null)
{
handler.sendMessage(new MessageData(Item.this, albumIconObserver));
}
}
}
}.start();
}
...
}
}
public IconListAdapter(Activity context, Vector<Item> itemList)
{
...
handler = new Handler()
{
public void handleMessage(Message message)
{
MessageData messageData = (MessageData)message.obj;
messageData.imageView.setImageBitmap(messageData.item.albumIcon);
}
};
}
public View getView(int position, View convertView, ViewGroup parent)
{
...
synchronized (IconListAdapter.class)
{
if (item.albumIcon != null)
{
icon.setImageBitmap(item.albumIcon);
}
else
{
icon.setImageResource(item.standardIcon.resourceId);
item.setAlbumIconObserver(icon);
}
}
...
}
}
只要我遵循ListView的XML布局,这段代码就完美了:
<ListView
android:id="@+id/fileListView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="100" />
在某些时候 - 我学到了更多关于布局权重的东西,并希望使其更加健壮 - 我将其改为此(它对分配给ListView的布局大小完全没有影响,它仍然从下面拉伸标题标签到底部):
<ListView
android:id="@+id/fileListView"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="100" />
从那时起它就不再起作用了。只加载了第一个图标(有时甚至没有图标),只有当我滚动列表时它们才会更新,因此再次调用项目上的getView()方法,意味着加载了图像文件。
(不幸的是,在我注意到新问题之前,我对代码进行了很多其他更改,需要花费很多精力来跟踪它。)
现在我的问题:为什么布局设置中的这个小改变到底有这么意外和可怕的副作用?这是一个已知的错误,还是有一些我还不了解的东西?
反复碰撞墙头
有关我的环境的信息:Eclipse 3.7.1,Android API 7,Samsung Galaxy,固件版本为2.2